Activity精选内容,看看还有没有你的盲点!
https://juejin.cn/user/4441682709326958
Activity的生命周期,正常情况和异常情况?
Activity的四种启动模式,启动页设置singleTask/singleInstance可能造成什么后果?
任务,任务栈,前台任务栈,后台任务栈,返回栈分别是什么?
startActivityForResult导致的一系列问题?
清除返回栈(Clearing the back stack)的一些概念
allowTaskReparenting的使用
Activity的隐式启动
Activity启动流程
Activity生命周期的变化对进程的优先级有什么影响?
如果App还存在缓存进程,这个时候启动App,应用Application的onCreate方法会执行吗?
一个Activity A启动另一个Activity B,为何会先走A的onPause方法,等到B执行完onResume方法后,才会走A的onStop方法呢?
为什么要这么设计Activity生命周期?
今日头条极速版-新闻界面打开的一些限制和首页
启动Activity:onCreate()->onStart()->onResume()
点击返回键:onPause()->onStop()->onDestroy()
点击Home键:onPause()->onSaveInstanceState()->onStop(),注意在API28之后onSaveInstanceState()方法的执行放在了onStop()之后。
用户再次回到原Activity:onRestart()->onStart()->onResume()
A Activity启动B Activity:A#onPause()->B#onCreate()->B#onStart()->B#onResume()->A#onStop()
stardard:默认模式,系统在启动该 Activity 的任务中创建 Activity 的新实例,并将 intent 传送给该实例。Activity 可以多次实例化,每个实例可以属于不同的任务,一个任务可以拥有多个实例。注意在该模式下配合FLAG_ACTIVITY_NEW_TASK 与 FLAG_ACTIVITY_CLEAR_TOP,单独/一起配合,都会重新创建实例。
singleTop:栈顶复用模式,如果当前任务的顶部已存在 Activity 的实例,则系统会通过调用其 onNewIntent() 方法来将 intent 转送给该实例,而不是创建 Activity 的新实例。在该模式下配合FLAG_ACTIVITY_CLEAR_TOP是用哪个,不会重新创建实例,会有类似SingleTask的效果,但是如果再加上FLAG_ACTIVITY_NEW_TASK,还是会创建新实例。
singleTask:栈内复用模式,系统会创建新任务,并实例化新任务的根 Activity。但是,如果另外的任务中已存在该 Activity 的实例,则系统会通过调用其 onNewIntent() 方法将 intent 转送到该现有实例,而不是创建新实例。Activity 一次只能有一个实例存在。该模式默认具有clearTop的效果。
singleInstance:单实例模式,与 "singleTask" 相似,唯一不同的是系统不会将任何其他 Activity 启动到包含该实例的任务中。该 Activity 始终是其任务唯一的成员;由该 Activity 启动的任何 Activity 都会在其他的任务中打开。
一般地,对于没有分屏功能以及虚拟屏的情况下,ActivityStackSupervisor与ActivityDisplay都是系统唯一;
ActivityDisplay主要有Home Stack和App Stack这两个栈;
每个ActivityStack中可以有若干个TaskRecord对象,当前只会有一个获得了焦点的ActivityStack;
每个TaskRecord包含如果若干个ActivityRecord对象;
每个ActivityRecord记录一个Activity信息。
implicitIntent.setAction("com.test.image");
implicitIntent.addCategory("android.intent.category.DEFAULT");
MainActivity.this.startActivity(implicitIntent);
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="com.test.image" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
// 看源码很重要的一个能力就是‘眼中只有你’,认不到的都忽略,看认得到的
···
// 创建主线程的Looper对象,发现和工作线程创建Looper对象调用的方法不一样,这里先记下,以后在详解。
// 主线程原来也有Looper对象啊
Looper.prepareMainLooper();
//创建ActivityThread
ActivityThread thread = new ActivityThread();
thread.attach(false);
// 如果主线程的Handler为空(可以看出,一个好的命名可读性是多么高),那就为主线程创建一个Handler。
// 然后我们还可以在主线程创建Handler,说明一个线程对应多个Handler。多读源码,很多问题都得到了解决啊。
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
// 这里抛了个异常,主线程loop异常退出。说明主线程loop不能退出,这里和前面建立Looper对象的调用方法有关
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Launcher通知AMS启动App的启动页Activity,AMS记录要启动的Activity信息,并且通知Launcher进入pause状态。
Launcher进入pause状态后,通知AMS已经paused了,可以启动App了
如果App未开启过,AMS发送创建进程请求,Zogyte进程接受AMS请求并孵化应用进程,应用进程调用ActivityThread并调用mian()方法,并且main()方法中创建ActivityThread对象,activityThread.attach()方法中进行绑定(应用进程绑定到AMS),传入applicationThread以便通讯。
AMS通知App绑定Application(bindApplication)并启动Activity,并且创建和关联Context,最后调用onCreate等方法。
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
...
//获取AMS的代理对象
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
//得到activity的service引用,即IBinder类型的AMS引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
//转换成IActivityManager对象
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
}
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
//DecoreView和WindowManager进行关联。
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
//设置DecorView可见
mDecor.setVisibility(View.VISIBLE);
}
它正在用户的互动屏幕上运行一个 Activity(其 onResume() 方法已被调用)。
它有一个BroadcastReceiver 目前正在运行(其 BroadcastReceiver.onReceive() 方法正在执行)。
它有一个Service目前正在执行其某个回调(Service.onCreate()、Service.onStart() 或 Service.onDestroy())中的代码。
它正在运行的 Activity 在屏幕上对用户可见,但不在前台(其 onPause() 方法已被调用)。举例来说,如果前台 Activity 显示为一个对话框,而这个对话框允许在其后面看到上一个 Activity,则可能会出现这种情况。
它有一个 Service 正在通过 Service.startForeground()(要求系统将该服务视为用户知晓或基本上对用户可见的服务)作为前台服务运行。
系统正在使用其托管的服务实现用户知晓的特定功能,例如动态壁纸、输入法服务等。
界面启动时候用需要设计一个方法
界面完全渲染完毕显示需要一个方法
界面被部分遮盖时/跳到其他界面/退到后台需要一个方法
界面完全退出销毁时需要一个方法
Run #4: ActivityRecord{8794744 u0 com.ss.android.article.lite/com.ss.android.article.base.feature.detail2.view.NewDetailActivity t6564}
Run #3: ActivityRecord{8be5248 u0 com.ss.android.article.lite/com.ss.android.article.base.feature.detail2.view.NewDetailActivity t6564}
Run #2: ActivityRecord{8bd6a09 u0 com.ss.android.article.lite/com.ss.android.article.base.feature.detail2.view.NewDetailActivity t6564}
Run #1: ActivityRecord{87cc383 u0 com.ss.android.article.lite/com.ss.android.article.base.feature.detail2.view.NewDetailActivity t6564}
Run #0: ActivityRecord{8bd6b44 u0 com.ss.android.article.lite/.activity.SplashActivity t6564}
baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ss.android.article.lite/.activity.SplashActivity }
baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.sina.weibo/.SplashActivit }
baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=cmccwm.mobilemusic/.ui.base.SplashActivity }
baseIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.daimajia.gold/im.juejin.android.ui.SplashActivity }
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ss.android.article.lite/.activity.SplashActivity bnds=[544,149][796,458] }
mActivityComponent=com.ss.android.article.lite/.activity.SplashActivity
mIntent=Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ss.android.article.lite/.activity.SplashActivity bnds=[544,149][796,458] }
#0 ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684} type=standard mode=fullscreen override-mode=undefined //启动模式是standard
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ss.android.article.lite/.activity.SplashActivity}
mActivityComponent=com.ss.android.article.lite/.activity.SplashActivity
Activities=[ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}]
Hist #0: ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.ss.android.article.lite/.activity.SplashActivity bnds=[544,149][796,458] }
Run #0: ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}
mResumedActivity: ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.sina.weibo/.SplashActivity}
mActivityComponent=com.sina.weibo/.SplashActivity
intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=cmccwm.mobilemusic/.ui.base.SplashActivity}
mActivityComponent=cmccwm.mobilemusic/.ui.base.SplashActivity
ResumedActivity:ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}
ResumedActivity: ActivityRecord{8e43505 u0 com.ss.android.article.lite/.activity.SplashActivity t6684}
Intent { flg=0x24008000 cmp=com.ss.android.article.news/.activity.MainActivity (has extras) }
mActivityComponent=com.ss.android.article.news/.activity.MainActivity
mIntent=Intent { flg=0x24008000 cmp=com.ss.android.article.news/.activity.MainActivity (has extras) }
#0 ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685} type=standard mode=fullscreen override-mode=undefined //standard启动模式
#0 ActivityRecord{9130583 u0 cmccwm.mobilemusic/.ui.base.MainActivity t6681} type=standard mode=fullscreen override-mode=undefined
Activities=[ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}]
Hist #0: ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}
Intent { flg=0x24008000 cmp=com.ss.android.article.news/.activity.MainActivity (has extras) }
Run #0: ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}
mResumedActivity: ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}
Activities=[ActivityRecord{9130583 u0 cmccwm.mobilemusic/.ui.base.MainActivity t6681}, ActivityRecord{9822b05 u0 cmccwm.mobilemusic/com.migu.music.ui.local.LocalSongsActivity t6681}]
Hist #0: ActivityRecord{9130583 u0 cmccwm.mobilemusic/.ui.base.MainActivity t6681}
Intent { flg=0x10000000 cmp=cmccwm.mobilemusic/.ui.base.MainActivity (has extras) }
Run #0: ActivityRecord{9130583 u0 cmccwm.mobilemusic/.ui.base.MainActivity t6681}
ResumedActivity:ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}
ResumedActivity: ActivityRecord{8fadec6 u0 com.ss.android.article.news/.activity.MainActivity t6685}