Activity拾遗
一、Activity生命周期
正常流程生命周期
1、创建一个页面
04-26 17:28:11.851 2951-2951/com.demo.xp D/MainActivity: onCreate
04-26 17:28:12.090 2951-2951/com.demo.xp D/MainActivity: onStart
04-26 17:28:12.093 2951-2951/com.demo.xp D/MainActivity: onResume
2、启动另一个页面
04-26 17:28:18.285 2951-2951/com.demo.xp D/MainActivity: onPause
04-26 17:28:18.290 2951-2951/com.demo.xp D/Main2Activity: onCreate
04-26 17:28:18.299 2951-2951/com.demo.xp D/Main2Activity: onStart
04-26 17:28:18.300 2951-2951/com.demo.xp D/Main2Activity: onResume
04-26 17:28:19.027 2951-2951/com.demo.xp D/MainActivity: onStop
3、按下back键返回第一个界面
04-26 17:28:32.524 2951-2951/com.demo.xp D/Main2Activity: onPause
04-26 17:28:32.543 2951-2951/com.demo.xp D/MainActivity: onRestart
04-26 17:28:32.543 2951-2951/com.demo.xp D/MainActivity: onStart
04-26 17:28:32.544 2951-2951/com.demo.xp D/MainActivity: onResume
04-26 17:28:33.056 2951-2951/com.demo.xp D/Main2Activity: onStop
04-26 17:28:33.059 2951-2951/com.demo.xp D/Main2Activity: onDestroy
4、按下home键
04-26 17:33:24.801 2951-2951/com.demo.xp D/MainActivity: onPause
04-26 17:33:24.961 2951-2951/com.demo.xp D/MainActivity: onStop
异常流程生命周期
1、资源相关的系统配置发生改变导致Activity被杀死并重新创建。
2、资源内存不足导致优先级低的Activity被杀死。
二、屏幕切换时的生命周期
1、API=25,默认情况下竖屏切横屏
2、API=25,默认情况下横屏切竖屏
3、API=25,设置Activity的android:configChanges="orientation"时
4、API=25,设置Activity的android:configChanges="orientation|keyboardHidden"时,切横屏、竖屏只会执行一次生命周期。
04-26 17:57:01.519 17721-17721/com.demo.xp D/MainActivity: onPause
04-26 17:57:01.521 17721-17721/com.demo.xp D/MainActivity: onStop
04-26 17:57:01.521 17721-17721/com.demo.xp D/MainActivity: onDestroy
04-26 17:57:01.539 17721-17721/com.demo.xp D/MainActivity: onCreate
04-26 17:57:01.553 17721-17721/com.demo.xp D/MainActivity: onStart
04-26 17:57:01.556 17721-17721/com.demo.xp D/MainActivity: onResume
5、API=25,当设置android:configChanges="orientation|keyboardHidden|screenSize"切屏不会重新调用各个生命周期。
自从Android 3.2(API 13),在设置Activity的android:configChanges="orientation|keyboardHidden"后,还是一样会重新调用各个生命周期的。因为screen size也开始跟着设备的横竖切换而改变。因此,阻止程序在运行时重新加载Activity,除了设置"orientation",你还必须加上"ScreenSize"。
三、Activity启动模式
见:https://github.com/XieXiePro/LearnDemo
Android四种启动模式:
1、standard,默认为此模式
04-26 18:59:11.773 7154-7154/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 21 hasCode:44123917
04-26 18:59:11.773 7154-7154/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 18:59:14.701 7154-7154/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 21 hasCode:125095489
04-26 18:59:14.701 7154-7154/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:00:58.932 7154-7154/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 21 hasCode:212299573
04-26 19:00:58.932 7154-7154/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:01:05.019 7154-7154/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 21 hasCode:118245998
04-26 19:01:05.019 7154-7154/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
2、singleTop
04-26 19:39:33.792 31605-31605/com.demo.xp I/BaseActivity: onCreate:SingleTopActivity TaskId: 23 hasCode:56583874
04-26 19:39:33.794 31605-31605/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:39:55.269 31605-31605/com.demo.xp I/BaseActivity: onNewIntent:SingleTopActivity TaskId: 23 hasCode:56583874
04-26 19:39:55.270 31605-31605/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:39:56.133 31605-31605/com.demo.xp I/BaseActivity: onNewIntent:SingleTopActivity TaskId: 23 hasCode:56583874
04-26 19:39:56.133 31605-31605/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
3、singleInstance
04-26 19:45:51.273 5664-5664/com.demo.xp I/BaseActivity: onCreate:SingleInstanceActivity TaskId: 29 hasCode:234473767
04-26 19:45:51.274 5664-5664/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:45:55.186 5664-5664/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 28 hasCode:116954427
04-26 19:45:55.187 5664-5664/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:45:58.868 5664-5664/com.demo.xp I/BaseActivity: onNewIntent:SingleInstanceActivity TaskId: 29 hasCode:234473767
04-26 19:45:58.868 5664-5664/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:46:07.095 5664-5664/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 28 hasCode:234710287
04-26 19:46:07.097 5664-5664/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:46:12.733 5664-5664/com.demo.xp I/BaseActivity: onNewIntent:SingleInstanceActivity TaskId: 29 hasCode:234473767
04-26 19:46:12.734 5664-5664/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
4、singleTask
04-26 19:58:30.703 8423-8423/com.demo.xp I/BaseActivity: onCreate:SingleTaskActivity TaskId: 32 hasCode:74078356
04-26 19:58:30.703 8423-8423/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:58:33.920 8423-8423/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 32 hasCode:136280344
04-26 19:58:33.920 8423-8423/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:58:38.181 8423-8423/com.demo.xp I/BaseActivity: onNewIntent:SingleTaskActivity TaskId: 32 hasCode:74078356
04-26 19:58:38.181 8423-8423/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:58:41.067 8423-8423/com.demo.xp I/BaseActivity: onCreate:StandardActivity TaskId: 32 hasCode:238283109
04-26 19:58:41.067 8423-8423/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
04-26 19:58:43.832 8423-8423/com.demo.xp I/BaseActivity: onNewIntent:SingleTaskActivity TaskId: 32 hasCode:74078356
04-26 19:58:43.832 8423-8423/com.demo.xp I/BaseActivity: taskAffinity:com.demo.xp
四、安全退出所有的Activity
SingTask的应用:
可以用来退出整个应用。
将主Activity设为SingTask模式,然后在要退出的Activity中转到主Activity,然后重写主Activity的onNewIntent函数,并在函数中加上一句finish。
退出单个Activity方法:
调用finish
杀死该进程:killprocess(Process.mId)
终止正在运行的虚拟机:system.exit()
退出整个应用:
制造抛异常导致整个程序退出
将所有的activity放入到一个list中,然后在需要退出的时候,将所有的activity,finish掉
通过广播来完成退出功能
通过广播来完成退出功能,具体实现过程是这样的:在每个Activity创建时(onCreate时)给Activity注册一个广播接收器,当退出时发送该广播即可。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("finish");
registerReceiver(mFinishReceiver, filter);
……
}
private BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if("finish".equals(intent.getAction())) {
Log.e("#########", "I am " + getLocalClassName()
+ ",now finishing myself...");
finish();
}
}
};
定义一个Application类来存储Activity对象的引用
package com.demo.xp;
import android.app.Activity;
import android.app.Application;
import java.util.LinkedList;
import java.util.List;
/**
* Created by xp on 17/4/27.
*/
public class AppApplication extends Application {
private List<Activity> activityList = new LinkedList<>();
private static AppApplication instance;
// 单例模式中获取唯一的ExitApplication实例
public static AppApplication getInstance() {
if (null == instance) {
instance = new AppApplication();
}
return instance;
}
// 添加Activity到容器中
public void addActivity(Activity activity) {
activityList.add(activity);
}
// 遍历所有Activity并finish
public void exit() {
for (Activity activity : activityList) {
activity.finish();
}
System.exit(0);
}
}