多进程导致 Application 多次执行的问题研究
来源:互联网 发布:lb极速网络 编辑:程序博客网 时间:2024/05/22 06:25
在项目中我们有时会用到多进程,需要在 AndroidManifest 里进行声明 :
<activity android:name=".RemoteActivity" android:process=":remote"/>
启动这个 Activity 后,你的应用就有了两个进程,这时就有问题了,Application 类的生命周期也调用了两次了:
07-13 10:03:40.069 22804 22804 D MyApplication: onCreate07-13 10:03:40.885 22846 22846 D MyApplication: onCreate
至于为什么 Appilication 类的生命周期为什么会被调用两次,我们需要从底层进行分析,重点是看 Appilication 实例是在什么地方创建的,创建后生命周期是如何调用的;Activity 和 Application 都是普通的类,他们是在 ActivityThread 中创建的,并且给予了它们生命周期回调;
具体 Activity 启动流程可以看 Activity的启动流程
这里分析下与 Appilication 相关的内容
AMS 在收到发起者的 startActivity 请求后执行 ActivityStackSupervisor 的 startSpecificActivityLocked 方法
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { } } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
这里调用了 AMS 的 getProcessRecordLocked 方法来查是否在 AMS 中有相关的记录(应用的每个进程名字都会记录在 AMS 中),如果没有,返回的 app 为 null, 这时 调用的是 startProcessLocked 方法
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { ... if (entryPoint == null) entryPoint = "android.app.ActivityThread"; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + app.processName); checkTime(startTime, "startProcess: asking zygote to start proc"); Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); ...}
在这里创建了一个新的进程,并且调用了 ActivityThread 的 main 方法,在 main 方法里创建了 ActivityThread 对象,也就是说每个进程对应了一个 ActivityThread 对象,然后 AMS 会通知 ActivityThread 的 handleLaunchActivity 来启动 Activity:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ... Activity a = performLaunchActivity(r, customIntent); ... }
在这里调用 performLaunchActivity 创建了一个 Activity 和 Application
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ... } catch (Exception e) { ... } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... if (activity != null) { ... if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } return activity; }
在这里先创建了 Activity 实例,再创建 Appilication 实例,并调用了 Activity 的 onCreate 方法,其中,在 makeApplication 里调用了 Application 的 onCreate 方法:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { ... app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); ... instrumentation.callApplicationOnCreate(app); return app; }
总结下,由于创建了新的进程,每个进程会创建自己的 ActivityThread 实例,每个 ActivityThread 又会创建自己的 Application 实例并且会调用它的 onCreate 方法;也就是说每个进程都会有自己的 Appilication 实例,而这个实例都用的同一个类来创建的,所以你在这个类里面写的东西当然会被执行多次;
所以这就是为什么同一个应用多进程会造成 Application 的生命周期方法会调用多次;
解决办法是在 Application 的生命周期方法里对进程名进行判断,如果不是同进程就不要执行一些不必要的东西了
- 多进程导致 Application 多次执行的问题研究
- Android多进程导致多次初始化Application
- 多进程导致Application多次启动
- 记一次诡异的问题:跟多进程多次执行application的onCreate有关
- Android中多进程方式导致的全局Application的OnCreate多次被调用
- Android中多进程方式导致的全局Application的OnCreate多次被调用
- Application中方法被执行多次??进程 -- 服务的坑 !!!
- 亲自实践:.多进程Application onCreate多次执行
- Android多进程时Application中onCreate执行多次
- 关于setTimeout多次点击会多次执行方法导致运行速度加快的问题
- Android多进程app中Application回调onCreate()方法被执行多次分析及解决
- Android避免多进程Application onCreate中初始化代码执行多次
- Android 多进程会多次初始化 Application
- NSNotification多次执行的问题
- android application方法执行多次
- Android的Application中onCreate执行多次解决方案
- Android的Application中onCreate执行多次解决方案
- jQuery live 重复绑定,导致多次执行的解决方式
- twemproxy源码分析之四:处理流程
- PHP获取获取当前页面的URL相关方法
- 数学建模算法 一 简述(1)蒙特卡洛算法
- js 调用 android 方法
- inline
- 多进程导致 Application 多次执行的问题研究
- Spring-Data-Redis使用文档
- SpringBoot使用logback输出日志并打印sql信息
- select 大数据量append
- linux中的信号1——信号概述
- 初步学习Java疯狂讲义数组的用用举例
- JVM基础
- mac 系统 下AWS cloud 配置及安装 flask
- Java CSV操作(导出和导入)