美文网首页
activity的使用总结

activity的使用总结

作者: 名字_都被占了 | 来源:发表于2018-05-07 21:38 被阅读0次
activity的生命周期图如下:

activity的使用总结
从整个生命周期来说,onCreate和onDestroy是配对的,分别标识着Activity的创建和销毁,从Activity是否可见来说,onStart和onStop是配对的,从Activity是否在前台来说,onResume和onPause是配对的。
小提示:(1)onStart和onStop是从Activity是否可见这个角度来回调,而onResume和onPause是从Activity是否位于前台这个角度来回调的。onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。(2)旧Activity先onPause,然后新Activity再启动。

--------------------------------------------------------

android在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。(另外View也有onSaveInstanceState和onRestoreInstanceState这两个方法,能够恢复自身所设置好的要恢复的数据),示例代码如下:
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainactivity);
        if(savedInstanceState!=null){
            Log.d("MainActivity", "onCreate:"+savedInstanceState.getString("zhi"));
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("zhi","我是销毁后保存的数据");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("MainActivity", "onRestoreInstanceState:"+savedInstanceState.getString("zhi"));
    }
 /*   旋转屏幕后输出如下结果:
    05-07 20:49:55.955 30487-30487/com.wenxi.biandianzhan D/MainActivity: onCreate:我是销毁后保存的数据
    05-07 20:49:55.965 30487-30487/com.wenxi.biandianzhan D/MainActivity: onRestoreInstanceState:我是销毁后保存的数据*/
}
防止因为屏幕旋转而使activity重新创建,给activity配置了android:configChanges="orientation|screenSize"
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainactivity);
        if(savedInstanceState!=null){
            Log.d("MainActivity", "onCreate:"+savedInstanceState.getString("zhi"));
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("zhi","我是销毁后保存的数据");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("MainActivity", "onRestoreInstanceState:"+savedInstanceState.getString("zhi"));
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d("MainActivity", "屏幕设置改变了");
    }
    /*旋转屏幕后输出如下结果:(activity没有重新创建,因为在AndroidManifest.xml文件中配置了给activity配置了android:configChanges="orientation|screenSize")
    05-07 21:22:54.375 9924-9924/com.wenxi.biandianzhan D/MainActivity: 屏幕设置改变了*/
}

--------------------------------------------------------

activity的启动模式
(1)standard 标准模式(activity默认的启动模式)
(2)singleTop 栈顶复用模式(在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被调用,但是如果新Activity的实例已存在但不是位于栈顶,那么新Activity仍然会重新创建)
(3)singleTask 栈内复用模式(在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统会回调其onNewIntent)
(4)singleInstance 单例模式(是一种加强版的singleTask模式,具有此模式的Activity只能单独的位于一个任务栈中)
任务栈的概念:activity有个属性是TaskAffinity,中文意思是任务相关性,这个参数表示了一个activity所需要的任务栈的名字,默认情况下,所有activity所需的任务栈的名字为应用的包名,任务栈分为前台任务栈和后台任务栈,后台任务栈中的activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
通过设置intent的标志位来为activity指定启动模式,这种方式的优先级要高于在AndroidManifest.xml文件设置的启动模式
小提示,通过在terminal中输入如下命令查看栈内具体信息

adb shell dumpsys activity com.wenxi.biandianzhan -top 获取当前界面的UI信息,在这里com.wenxi.biandianzhan是applicationId
adb shell dumpsys activity com.wenxi.biandianzhan -top | findstr ACTIVITY 获取栈内activity的详细情况
更多命令在网址https://testerhome.com/topics/1462

--------------------------------------------------------

IntentFilter的匹配规则
为了匹配过滤列表,需要同时匹配过滤列表中的action,category,data信息(注意action,category可以是多个,只要匹配action,category中的一个即可),否则匹配失败。另外一点,一个activity可以有多个intent-filter,一个intent只要能匹配任何一组intent-filter即可成功启动对应的activity。

注意点如下:
1:action区分大小写,大小写不同,那么所对应的action就不同。
2:category必须得有android:name="android.intent.category.DEFAULT",不然该activity不支持隐式启动。
3:data的URI可以不指定值,它是有默认值的,默认值为content和file,也就是说,虽然没有指定URI,但是intent中的URI部分的schema必须为content或者file才能匹配。
4:如果要为intent指定data的值,必须要调用setDataAndType方法,不能先调用setData再调用setType,因为这两个方法会清除对方的值。
5:Intent-filter的匹配规则对于service和broadcastreceiver也是同样的道理,不过系统对于service的建议是尽量使用显示调用方式来启动服务。
6:通过隐式启动activity可以会出现找不到相应activity的情况,这时候就可以通过ActivityInfo来判断是否找到了对应的activity。代码如下:

ActivityInfo activityInfo = intent.resolveActivityInfo(getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY);
if (activityInfo != null)
    startActivity(intent);

7:系统在调用startActivity或者是startActivityForResult时会默认认为intent加上了"android.intent.category.DEFAULT",也正是因为这一点,使得category必须得有android:name="android.intent.category.DEFAULT",不然该activity不支持隐式启动。

完整示例代码如下:

...
<activity android:name=".lanjiazai.SecondActivity">
            <intent-filter>
                <action android:name="android.intent.action.ANSWER"/>
                <action android:name="android.intent.action.ALL_APPS"/>
                <category android:name="android.intent.category.APP_BROWSER"/>
                <category android:name="android.intent.category.APP_EMAIL"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:mimeType="image/*"/>
                <data android:scheme="http"/>
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.FACTORY_TEST"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
</activity>
...
···
 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.ANSWER");
                intent.addCategory("android.intent.category.APP_EMAIL");
                intent.addCategory("android.intent.category.APP_BROWSER");
                intent.addCategory("android.intent.category.DEFAULT");//这句代码可写可不写,因为系统在调用startActivity时会默认为intent加上"android.intent.category.DEFAULT"
                intent.setDataAndType(Uri.parse("http://abc.txt"), "image/*");
                ActivityInfo activityInfo = intent.resolveActivityInfo(getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY);
                if (activityInfo != null)
                    startActivity(intent);
            }
        });
···

-----------------------------------------------------------------------------------

android群英传中对Activity的介绍

1:Intent Flag启动模式

Intent.FLAG_ACTIVITY_NEW_TASK
使用一个新的Task来启动一个Activity,但启动的每个Activity都将在一个新的Task中,该Flag通常使用在从Service中启动Activity的场景,由于在Service中并不存在Activity栈,所以使用该Flag来创建一个新的Activity栈,并创建新的Activity实例。
Intent.FLAG_ACTIVITY_SINGLE_TOP
使用singletop模式来启动一个Activity,与指定android:launchMode="singleTop"效果相同。
Intent.ACTIVITY_CLEAR_TOP
使用SingleTask模式来启动一个Activity,与指定android:launchMode="singleTask"效果相同。
Intent.FLAG_ACTIVITY_NO_HISTORY
使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中。

2:清空任务栈

系统同样提供了清空任务栈的方法来让我们将一个Task全部清除,通常情况下,可以在AndroidManifest文件中的<activity>标签中使用以下几种属性来清理任务栈。
  • clearTaskOnLaunch,就是在每次返回该Activity时,都将该Activity之上的所有Activity都清除。通过这个属性,可以让这个Task每次在初始化的时候,都只有这一个Activity。
  • finishOnTaskLaunch,该属性与clearTaskOnLaunch属性类似,只不过clearTaskOnLaunch作用在别人身上,而finishOnTaskLaunch作用在自己身上。通过这个属性,当离开这个Activity所处的Task,那么用户再返回时,该Activity就会被finish掉。
  • alwaysRetainTaskState,该属性给了Task一道“免死金牌”,如果将Activity的这个属性设置为True,那么该Activity所在的Task将不接受任何清理命令,一直保持当前Task状态。

相关文章

网友评论

      本文标题:activity的使用总结

      本文链接:https://www.haomeiwen.com/subject/siavrftx.html