本文为Android的Activity相干常识整顿,具体参考了

《Android开发艺术摸索》第一章
《Android群英传》第八章
《第一行代码》第二章
Activity是与用户交互的第一接口。

Activity生命周期
Activity具备多种状态。其生命周期图如下:

其中,有三个稳固态,其余都是过渡态:

Resumed ,此时,Activity处于栈顶,解决用户交互。
Paused,当Activity的一部分被挡住的时候进入这个状态,不会与用户交互。
Stopped,当Activity齐全被笼罩时进入这个状态,此时Activity不可见,仅在后盾运行。

1.1 Activity经典生命周期

(以下均指MainActivity的生命周期)

Activity启动,点开一个利用展现MainActivity
onCreate()->onStart()->onResume() 达到Resumed状态,此时MainActivity被关上。

Activity暂停与复原,1:关上了一个半屏幕的dialog,2:按返回键返回MainActivity
onPause()达到Paused状态,此时dialog被关上。
onResume()达到Resumed状态,此时dialog被敞开,显示MainActivity

Activity进行与复原,1:关上另一个SecondActivity,2:按返回键返回MainActivity
onPause()->onStop()到Stopped状态,此时SecondActivity被关上。
onRestart()->onStart()->onResume()到Resumed状态,此时SecondActivity被敞开,从新回到MainActivity。

Activity销毁,在MainActivity按返回键
onPause()->onStop()->onDestory(),此时曾经销毁 MainActivity。
留神:
在onPause()中肯定要开释应用的系统资源,比方Camera,sensor,receivers!!
在onStop()中执行更大、更多CPU密集的敞开操作。比方写入信息到数据库。
当零碎长期处于onStopped状态而且此时零碎内存缓和时,零碎会回收此Activity,而此时,零碎会通过onSaveInstanceState()办法将Activity状态保留到Bundle对象中(finish()办法销毁时不会保留)。当从新创立此Activity时,保留的Bundle对象会传递到onRestoreInstanceState()与onCreate()中。
onCreate和onDestroy是配对的,别离标识着Activity的创立和销毁; onStart和onStop是配对的,标识着Activity是否可见;onResume和onPause是配对的,标识着Activity是否在前台。
假如以后Activity为MainAcitivty ,这时用户启动SecondActivity ,那么MainAcitivty 的onPause先执行,SecondActivity 的onResume后执行。Android规定,不能在onPause中做重量级操作,就是基于这里。咱们应该尽量在onStop中做操作,使得新Activity尽快显示
MainAcitivty->onPause
SecondActivity->onCreate
SecondActivity->onStart
SecondActivity->onResume
MainAcitivty->onStop

1.2 异样生命周期

以下几种状况下,Activity的生命周期会产生异样
1,资源相干的系统配置产生扭转
比方,旋转屏幕,在默认状态下,Activity就会被销毁并且从新创立。

首先,Activity就会被销毁,onPause(), onStop(),onDestory()均会被调用,同时因为Activity是在异样状态下终止的,零碎会在onStop()之前,调用onSaveInstanceState()来保留以后Activity的状态。
而后,Activity被从新创立,零碎会在onStart()之后,调用onRestoreInstanceState(),并且把之前保留的Bundle对象传递给onRestoreInstanceState()和onCreate()办法。
PS: 这两个办法都能对Bundle数据进行解决,然而个别用 onRestoreInstanceState()。因为onRestoreInstanceState()一旦被调用,其参数 Bundle savedInstanceState 肯定是有值的,咱们不用判断其是否为空。

@Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(savedInstanceState != null){ String test = savedInstanceState.getString("extre_test"); Log.d(TAG, test); } } @Override protected void onSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState);   outState.putString("extre_test", "test"); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState){ super.onRestoreInstanceState(savedInstanceState); String test = savedInstanceState.getString("extre_test"); Log.d(TAG, test); } 

执行程序:
1 onPause()
2 onSaveInstanceState(Bundle outState)
3 onStop()
4 onDestory()
5 onCreate(Bundle savedInstanceState)
6 onStart()
7 onRestoreInstanceState(Bundle savedInstanceState)

留神:零碎仅仅在Activity异样终止时才会调用onRestoreInstanceState()。

2,零碎内存不足
此时的零碎中数据的存储和复原状况和下面第一种状况统一。Activity优先级如下:

1 前台Activity
2 可见但非前台Activity
3 后盾Activity
当系统资源有余的时候,会依照这个优先级应用onSaveInstanceState()和onRestoreInstanceState()来存储和复原数据。

还有一些后盾过程不是四大组件,这样就会很容易被杀死~~ 个别是将这些后盾工作放入Service中,从而保障有肯定的优先级。

PS:阻止Activity被从新创立

应用android:configChanges="orientation|screenSize"属性。

罕用属性:

locale:设施的本地地位发生变化,个别指切换了零碎语言。
orientation:屏幕方向发生变化
screenSize:屏幕大小发生变化,当旋转屏幕的时候,屏幕尺寸会变!!!!这个比拟非凡,当minSdkVersion和targetSdkVersion均低于13时,此选项不会导致Activity重启,否则会导致Activity重启。
keyboardHidden:键盘的可拜访性发生变化,比方调出键盘。

<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="orientation|screenSize|keyboardHidden" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>  @Override public void onConfigurationChanged(Configuration newConfig){     super.onConfigurationChanged(newConfig);     ......//当系统配置发上变换时,进行的工作 }  

Android工作栈
Android的APP通常会有多个Activity,各个Activity之间通过Intent进行连贯,零碎通过栈构造来保留整个APP的Activity。零碎有两种形式管制Activity的启动模式。

AndroidMainifest的launchMode
Intent Flag(优先级更高)

2.1AndroidMainifest启动模式

在AndroidMainifest.xml文件外面的activity标签设置启动模式。

<activity android:name=".FirstActivity" android:launchMode="singleTop" android:label="This is FirstActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 

standard,规范模式,每次都会创立新的Activity笼罩在原Activity上

singleTop,栈顶复用模式,首先判断栈顶Activity是否是要启动的Activity,如果是则不创立新的Activity而间接援用这个Activity;如果不是则创立新的Activity。

singleTask,栈内复用模式,检测整个Activity栈中是否存在以后须要启动的Activity,如果存在则将该Activity置于栈顶,并销毁其上所有Activity。

singleInstance,单实例模式,创立新的工作栈,且该工作栈仅有一个Activity。

TaskAffinity
taskAffinity,工作相关性。xml中的一个属性,标识了一个Activity所须要的工作栈的名字。默认是包名。如果设置了其余的名字如com.test.task1,那启动它的时候就会新建一个名为com.test.task1的工作栈。

<activity android:name="com.test.task0.MainActivity" android:label="@string/app_name" android:launchMode="standard"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category andorid:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity andorid:name="com.test.SecondActivity" android:taskAffinity="com.test.task1" android:label="@string/app_name" android:launchMode="singleTask"/> <activity andorid:name="com.test.ThirdActivity" android:taskAffinity="com.test.task1" android:label="@string/app_name" android:launchMode="singleTask"/> 

如果从MainActivity启动SecondActivity,而后再启动ThirdActivity,那么工作栈如下:
com.test.task0 MainActivity
com.test.task1 SecondActivity ThirdActivity
若再从ThirdActivity启动MainActivity,那么工作栈如下:
com.test.task0 MainActivity
com.test.task1 SecondActivity ThirdActivity MainActivity

2.2 Intent Flag启动模式

对Intent进行设置

Intent intent = new Intent();  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

重要的Flag:

FLAG_ACTIVITY_NEW_TASK,启动的Activity在新的Task中,相当于android:launchMode="newTask"
FLAG_ACTIVITY_SINGLE_TOP,相当于android:launchMode="singleTop"
FLAG_ACTIVITY_CLEAR_TOP,相当于android:launchMode="singleTask"
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,当以此种模式启动A,A再启动B时,A会被销毁。等同于android:excludeFromeRecents="true"
3 IntentFilter的匹配规定

<activity android:name="SecondActivity"> <intent-filter> <action android:name="android.intent.action.SEND"> <category android:name="android.intent.category.DEFAULT"> <data android:mimeType="text/plain"> </intent-filter> </activity> 

调用一个Activity次要包含两种:
1,显式调用。

Intent intent = new Intent(MainActivity.this,SecondActivity.class); startActivity(intent); 

2, 隐式调用

Intent intent = new Intent(Intent.ACTION_SEND); intent.setDataAndType(Uri.parse("file://abc"), "text/plain"); startActivity(intent); 

隐式调用须要Intent可能匹配指标组件的IntentFilter中的过滤信息。
IntentFilter中的过滤信息有action, category, data。
只有一个Intent同时匹配这三个类别能力启动指标Activity。

action的匹配要求,Intent中的action存在且必须和过滤规定中的其中一个action雷同。
data的匹配要求,Intent中的data存在且必须和过滤规定中的其中一个data雷同。
category匹配要求,如果含有category,那么所有的category都必须和过滤规定中的其中一个category雷同。也就是说它的category能够没有!!!!!(起因是默认的category是android.intent.category.DEFAULT,不过得在activity标签的intent-filter中退出android.intent.category.DEFAULT这个category)
退出程序的两种办法

4.1 利用Activity的singleTask模式退出

将主Activity设置为singleTask模式

<activity      android:name=".MainActivity"      android:launchMode="singleTask"      ...  

在要退出的Activity直达到主Activity中,从而将主Activity之上的Activity都革除

Intent intent = new Intent(this, MainActivity.class); startActivity(intent); 

而后重写主Activity的onNewIntent()办法,在办法中加上finish(),从而销毁最初一个Activity。

@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); finish(); } 

4.2 利用专门的汇合类对所有的流动进行治理
创立一个ActivityCollector 类作为流动管理器。List<Activity>作为寄存流动的列表。

public class ActivityCollector { public static List<Activity> activities = new ArrayList<Activity>(); public static void addActivity(Activity activity) {     activities.add(activity); } public static void removeActivity(Activity activity) {       activities.remove(activity); } public static void finishAll() { for (Activity activity : activities) { if (!activity.isFinishing()) {               activity.finish(); } } } } 

创立一个继承自Activity的BaseActivity 。ActivityCollector里寄存的流动要随着onCreate而增加,随着onDestory而销毁。

public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("BaseActivity", getClass().getSimpleName()); ActivityCollector.addActivity(this); } @Override protected void onDestroy() { super.onDestroy(); ActivityCollector.removeActivity(this); } } 

全副的Activity都要继承自BaseActivity,此时,只有调用 ActivityCollector.finishAll();,就能够销毁所有Activity,关掉程序。
欢送各位技术大佬一起交换探讨,记得点击下上方的关注哦,这样就能够及时看到音讯啦!