Activity用法

Activity(活动)

显式启动

第一个参数是启动Activity的上下文,第二个参数是指定想要启动的活动目标,intent的意图十分明显,所以叫做显式启动。

//显式启动Activity
Intent intent=new Intent(this,TwoActivity.class);
startActivity(intent);

隐式启动

隐式启动

  1. 首先要先在AndroidManifest中为TwoActivity指定action和category;

  2. 修改点击事件,需要intent的action与category与AndroidManifest都相同时才能启动Activity;

    如果有多个Activity符合那么会弹出选择框

AndroidManifest:

其中的android.intent.category.DEFAULT是一种默认的category,在调用startActivity时会自动添加到intent中

<activity android:name=".TwoActivity">
    <intent-filter>
        <action android:name="android.intent.action.TWO" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

点击事件:

Intent intent=new Intent("android.intent.action.TWO");
startActivity(intent);

Activity可以设置多个category,需要所有的category都匹配才能启动Activity

设置Activity的Category:

<activity android:name=".TwoActivity">
    <intent-filter>
        <action android:name="android.intent.action.TWO" />
        <category android:name="ppp" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

使用addCategory添加category:

Intent intent=new Intent("android.intent.action.TWO");
intent.addCategory("ppp");
startActivity(intent);

隐式intent的更多用法

使用隐式intent可以启动其他程序中的Activity,这就可以在不同程序之间实现功能共享;

先指定intent的action是Intent.ACTION_VIEW,这是一个android内置动作,常量值为android.intent.action.VIEW.然后通过Uri.parse()方法将一个网址字符串解析成为一个Uri对象,再调用Intent的setData()方法将这个Uri对象传入进去。

系统会弹出一个列表,显示所有能够响应这个Intent的程序

启动手机自带的浏览器并进入百度:

Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);

使用intent启动其他app的Activity如下

目标Activity:

<intent-filter tools:ignore="AppLinkUrlError">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="https"/>
</intent-filter>

点击事件:

Intent intent=new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);

向下一个Activity传递数据

  1. 新建一个Intent;
  2. 使用initent.putExtra("extra_data",data)来传递数据,第一个参数是键值第二个才是要传递的值;
  3. 在接收端使用getIntent()返回得到intent;
  4. 使用intent.getStringExtra("extra_data")获得传递的数据;

发送端:

Intent intent=new Intent();
intnet.putExtra("one",1);
startActivity(intent);

接收端:

Intent intent=getIntent();
int i=intent.getIntExtra("one");

返回数据给上一个Activity

  1. 使用startActivityForResult(intent,1)启动Activty,第一个参数是intent,第二个参数是请求码;
  2. 重写请求端的onActivityResult()方法用来判断返回的数据;
  3. 接收端new一个intent使用setResult(RESULT_OK,intent),intent用于携带数据。

startActivityForResult

Intent intent = new Intent(this, UserXyActivity.class);
startActivityForResult(intent, 1);

onActivityResult()

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
	int i=data.getIntExtra("age",1);
    Toast.makeText(this, i + "", Toast.LENGTH_SHORT).show();
    
    if (resultCode == RESULT_OK) {
        ckRead.setChecked(true);
    }
}

setResult(RESULT_OK,intent)

Intent intent=new Intent();
intent.putExtra("age",1);
setResult(RESULT_OK,intent);

Activity的生命周期

alt Activity生命周期

Activity被回收之后保存数据

Activity被回收之后未保存的临时数据就会消失,所以调用onSaveInstanceState()来保存数据,再在该Activity的onCreate()中恢复数据

onSaveInstanceState()】携带一个Bundle类型的参数用于保存数据,onCreate也携带了一个Bundle参数用于恢复数据

onSaveInstanceState():

//Activity被回收时保存临时数据
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        String data="这是需要被保存的字符串类型的数据";
        int i=1234;//这是需要保存到int型数据
        outState.putString("name",data);
        outState.putInt("age",i);
    }

onCreate:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        //取出onSaveInstanceState方法中保存的临时数据
        if(savedInstanceState!=null){
            String name=savedInstanceState.getString("name");
            int age=savedInstanceState.getInt("age");
        }

Activity的启动模式

1.standard(默认启动模式)

standard模式是Activity默认的启动模式,在不进行显示指定的情况下,所有的Activity都使用standard模式启动;

在standard模式下,每启动一个新的Activity就会在返回栈中入栈,并处于栈顶,无论这个Activity是否已经在返回栈中,都会新建一个实例;

所以如果使用standard模式启动多个Activity那么要点击多次返回按钮才能完全退出。

2.singleTop

当活动的启动模式指定为singleTop时,若发现该活动处于栈顶时,

则认为可以直接使用它;

不处于栈顶时依然会创建新的实例。

android:launchMode="singleTop"

<activity 
	android:name=".FirstActivity"
    android:launchMode="singleTop">
    
    <intent-filter>
        <action android:name="android.intent.action.TWO" />
        <category android:name="ppp" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

3.singleTask

当活动的启动模式被指定为singleTask时,每次启动活动,系统就会首先在返回栈中检查是否存在该活动的实例;

若存在,则直接使用该实例,并把这个活动之前的活动全部出栈;

若不存在,则创建一个新的实例。

android:launchMode="singleTask"

4.singleInstance

如果想多个app共享一个Activity的实例,其他的三种都不行,因为每一个app都有自己独立的栈,而singleInstance有一个单独的栈来管理这个Activity

A使用singleInstance模式启动B,B再正常启动C,C返回时是返回到A;因为C与A处于同一个栈,C弹出之后,A就处于栈顶;A再返回才是到B,因为A弹出之后该Task栈就空了,于是就展示另一个Task栈的栈顶;B再退出时,这个程序才退出。

android:launchMode="singleInstance"


启动活动的最佳写法

在项目启动Activity并传递数据,接收方并不知到你启动时传递了那些类型的数据,只有问你或者查看代码,效率低;

于是将Intent添加数据的代码放入一个方法中,就能够通过方法的参数看出传递数据的类型;

actionStart()

public void actionStart(Context context,int age,String name){
    Intent intent=new Intent(context,TwoActivity.class);
    intent.putExtra("name",name);
    intent.putExtra("age",age);
    context.startActivity(intent);
}

启动

actionStart(this,age,name);
posted @ 2021-08-13 13:44  踩红帽的小姑娘  阅读(493)  评论(0)    收藏  举报