Android 进程启动源码解析

在android中,进程的概念被弱化了,主要是四大组件,但是四大组件也运行于进程中;AMS负责管理和调度进程,主要体现在启动进程,动态地根据组件调整进程在mLruProcesses列表中的位置,还可以调整进程的优先级,这2项都和系统的内存回收相关。

1, 启动进程



启动进程实在AMS的startProcessLocked方法中,当客户端调用startActivity时,会直接调用Activity.java的对应函数

1.   private final voidstartProcessLocked(ProcessRecord app, String hostingType,

2.   String hostingNameStr, String abiOverride,String entryPoint, String[] entryPointArgs) {

3.           long startTime =SystemClock.elapsedRealtime();

4.           ···

5.       Process.ProcessStartResultstartResult = Process.start(entryPoint,

6.       app.processName, uid, uid, gids, debugFlags,mountExternal,

7.       app.info.targetSdkVersion, app.info.seinfo,requiredAbi, instructionSet,

8.                       app.info.dataDir, entryPointArgs);

9.      ···

10.  }

直接看最主要的Process.start方法,

11.  public static final ProcessStartResultstart(final String processClass,

12.                                    final StringniceName,

13.                                    int uid, intgid, int[] gids,

14.                                    intdebugFlags, int mountExternal,

15.                                    inttargetSdkVersion,

16.                                    StringseInfo,

17.                                    String abi,

18.                                    StringinstructionSet,

19.                                    StringappDataDir,

20.                                    String[]zygoteArgs) {

21.          try {

22.              return startViaZygote(processClass, niceName, uid, gid, gids,

23.                      debugFlags, mountExternal,targetSdkVersion, seInfo,

24.                      abi, instructionSet,appDataDir, zygoteArgs);

25.          } catch (ZygoteStartFailedEx ex) {

26.              Log.e(LOG_TAG, "Starting VMprocess through Zygote failed");

27.              throw new RuntimeException(

28.                      "Starting VM processthrough Zygote failed", ex);

29.          }

30.      }

31.   

 

32.  private static ProcessStartResultstartViaZygote(final String processClass,

33.                                    final StringniceName,

34.                                    final intuid, final int gid,

35.                                    final int[]gids,

36.                                    intdebugFlags, int mountExternal,

37.                                    int targetSdkVersion,

38.                                    StringseInfo,

39.                                    String abi,

40.                                    StringinstructionSet,

41.                                    StringappDataDir,

42.                                    String[]extraArgs)

43.                                    throwsZygoteStartFailedEx {

44.          synchronized(Process.class) {

45.              ArrayList<String>argsForZygote = new ArrayList<String>();

46.   

47.              // --runtime-args, --setuid=,--setgid=,

48.              // and --setgroups= must go first

49.              argsForZygote.add("--runtime-args");

50.              argsForZygote.add("--setuid="+ uid);

51.              argsForZygote.add("--setgid="+ gid);

52.              if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING)!= 0) {

53.                  argsForZygote.add("--enable-jni-logging");

54.              }

55.              if ((debugFlags &Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {

56.                  argsForZygote.add("--enable-safemode");

57.              }

58.              if ((debugFlags &Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {

59.                  argsForZygote.add("--enable-debugger");

60.              }

61.              if ((debugFlags &Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {

62.                  argsForZygote.add("--enable-checkjni");

63.              }

64.              if ((debugFlags &Zygote.DEBUG_ENABLE_JIT) != 0) {

65.                  argsForZygote.add("--enable-jit");

66.              }

67.              if ((debugFlags &Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {

68.                  argsForZygote.add("--generate-debug-info");

69.              }

70.              if ((debugFlags &Zygote.DEBUG_ENABLE_ASSERT) != 0) {

71.                  argsForZygote.add("--enable-assert");

72.              }

73.              if (mountExternal ==Zygote.MOUNT_EXTERNAL_DEFAULT) {

74.                  argsForZygote.add("--mount-external-default");

75.              } else if (mountExternal ==Zygote.MOUNT_EXTERNAL_READ) {

76.                  argsForZygote.add("--mount-external-read");

77.              } else if (mountExternal ==Zygote.MOUNT_EXTERNAL_WRITE) {

78.                  argsForZygote.add("--mount-external-write");

79.              }

80.              argsForZygote.add("--target-sdk-version="+ targetSdkVersion);

81.   

82.              //TODO optionally enable debuger

83.              //argsForZygote.add("--enable-debugger");

84.   

85.              // --setgroups is a comma-separatedlist

86.              if (gids != null &&gids.length > 0) {

87.                  StringBuilder sb = newStringBuilder();

88.                  sb.append("--setgroups=");

89.   

90.                  int sz = gids.length;

91.                  for (int i = 0; i < sz; i++) {

92.                      if (i != 0) {

93.                          sb.append(',');

94.                      }

95.                      sb.append(gids[i]);

96.                  }

97.   

98.                  argsForZygote.add(sb.toString());

99.              }

100. 

101.            if (niceName != null) {

102.               argsForZygote.add("--nice-name=" + niceName);

103.           }

104. 

105.           if (seInfo != null) {

106.               argsForZygote.add("--seinfo=" + seInfo);

107.           }

108. 

109.           if (instructionSet != null) {

110.               argsForZygote.add("--instruction-set=" + instructionSet);

111.           }

112. 

113.           if (appDataDir != null) {

114.               argsForZygote.add("--app-data-dir=" + appDataDir);

115.           }

116. 

117.            argsForZygote.add(processClass);

118. 

119.           if (extraArgs != null) {

120.                for (String arg : extraArgs) {

121.                    argsForZygote.add(arg);

122.                }

123.           }

124. 

125.           return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),argsForZygote);

126.       }

127.    }

ProcessStartResult方法主要是保存所要启动进程的各种信息,然后通过zygoteSendArgsAndGetResult方法将这些信息发送到zygoteState进程中。

128.private static ProcessStartResultzygoteSendArgsAndGetResult(

129.           ZygoteState zygoteState, ArrayList<String> args)

130.           throws ZygoteStartFailedEx {

131.       try {

132.           /**

133.            * See com.android.internal.os.ZygoteInit.readArgumentList()

134.            * Presently the wire format to the zygote process is:

135.            * a) a count of arguments (argc, in essence)

136.            * b) a number of newline-separated argument strings equal to count

137.            *

138.            * After the zygote process reads these it will write the pid of

139.            * the child or -1 on failure, followed by boolean to

140.            * indicate whether a wrapper process was used.

141.            */

142.           final BufferedWriter writer = zygoteState.writer;

143.           final DataInputStream inputStream = zygoteState.inputStream;

144. 

145.           writer.write(Integer.toString(args.size()));

146.           writer.newLine();

147. 

148.           int sz = args.size();

149.           for (int i = 0; i < sz; i++) {

150.                String arg = args.get(i);

151.                if (arg.indexOf('\n') >= 0){

152.                    throw new ZygoteStartFailedEx(

153.                            "embeddednewlines not allowed");

154.                }

155.               writer.write(arg);

156.                writer.newLine();

157.           }

158. 

159.           writer.flush();

160. 

161.           // Should there be a timeout on this?

162.           ProcessStartResult result = new ProcessStartResult();

163.           result.pid = inputStream.readInt();

164.           if (result.pid < 0) {

165.                throw newZygoteStartFailedEx("fork() failed");

166.           }

167.           result.usingWrapper = inputStream.readBoolean();

168.           return result;

169.       } catch (IOException ex) {

170.           zygoteState.close();

171.           throw new ZygoteStartFailedEx(ex);

172.       }

173.    }

174. 

zygoteSendArgsAndGetResult通过socket向zygoteState进程发送创建进程的请求,实际创建进程的是zygoteState进程中。在zygoteState进程中创建进程在此就不论述了。

 

2, 进程运行

zygoteState创建好进程并且完成初始化操作之后,会调用进程的ActivityThread的main方法, main方法是一个进程最开始执行的地方。


175.public static void main(String[] args) {

176.       Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"ActivityThreadMain");

177.       SamplingProfilerIntegration.start();

178.       CloseGuard.setEnabled(false);

179. 

180.       Environment.initForCurrentUser();

181. 

182.       // Set the reporter for event logging in libcore

183.       EventLogger.setReporter(new EventLoggingReporter());

184. 

185.       AndroidKeyStoreProvider.install();

186. 

187.       // Make sure TrustedCertificateStore looks in the right place for CAcertificates

188.       final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());

189.       TrustedCertificateStore.setDefaultUserDirectory(configDir);

190. 

191.       Process.setArgV0("<pre-initialized>");

192. 

193.       Looper.prepareMainLooper();

194. 

195.       ActivityThread thread = new ActivityThread();

196.       thread.attach(false);

197. 

198.       if (sMainThreadHandler == null) {

199.           sMainThreadHandler =thread.getHandler();

200.       }

201. 

202.       if (false) {

203.           Looper.myLooper().setMessageLogging(new

204.                    LogPrinter(Log.DEBUG,"ActivityThread"));

205.       }

206. 

207.       // End of event ActivityThreadMain.

208.       Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

209.       Looper.loop();

210. 

211.       throw new RuntimeException("Main thread loop unexpectedlyexited");

212.    }

主要完成2见事情,

1,实例化ActivityThread类并且调用其attach方法;

2,开始主线程的消息循环。

 

213.private void attach(boolean system) {

214.       sCurrentActivityThread = this;

215.       ···

216.           final IActivityManager mgr = ActivityManagerNative.getDefault();

217.           try {

218.                mgr.attachApplication(mAppThread);

219.           } catch (RemoteException ex) {

220.                // Ignore

221.           }

222.           ···

223.    }

224. 

进程刚启动时,什么组件都没有,只能通过Binder机制向AMS所在进程发出请求了

 

225.public final void attachApplication(IApplicationThreadthread) {

226.       synchronized (this) {

227.           int callingPid = Binder.getCallingPid();

228.           final long origId = Binder.clearCallingIdentity();

229.           attachApplicationLocked(thread,callingPid);

230.            Binder.restoreCallingIdentity(origId);

231.       }

232.    }

233. 

 

234.private final booleanattachApplicationLocked(IApplicationThread thread,

235.           int pid) {

236.       ···

237.       thread.bindApplication(processName, appInfo,providers, app.instrumentationClass,

238.          profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,

239.                 app.instrumentationUiAutomationConnection,testMode, enableOpenGlTrace,

240.                    isRestrictedBackupMode ||!normalMode, app.persistent,

241.                    newConfiguration(mConfiguration), app.compat,

242.                   getCommonServicesLocked(app.isolated),

243.                   mCoreSettingsObserver.getCoreSettingsLocked());

244.           updateLruProcessLocked(app, false,null);

245.       ···

246.        if (mStackSupervisor.attachApplicationLocked(app)){

247.                    didSomething = true;

248.                }

249.         ···

250.        try {

251.                didSomething |= mServices.attachApplicationLocked(app, processName);

252.           }

253.        ···

254.         try {

255.                didSomething |= sendPendingBroadcastsLocked(app);

256.           }

257.        ···

258.}

主要做3件事情,

1,启动application和数据库

2,调用updateLruProcessLocked方法调整进程在mLruProcesses列表中的位置

3,分别调用对应方法启动activity,service以及广播三类组件。

在此主要论述第一件事,其他的省略。

259.public final void bindApplication(StringprocessName, ApplicationInfo appInfo,

260.                List<ProviderInfo>providers, ComponentName instrumentationName,

261.                ProfilerInfo profilerInfo,Bundle instrumentationArgs,

262.                IInstrumentationWatcherinstrumentationWatcher,

263.                IUiAutomationConnectioninstrumentationUiConnection, int debugMode,

264.           boolean enableOpenGlTrace, boolean isRestrictedBackupMode, booleanpersistent,

265.       Configuration config, CompatibilityInfo compatInfo, Map<String,IBinder> services,

266.                Bundle coreSettings) {

267.          ···

268.           AppBindData data = new AppBindData();

269.           data.processName = processName;

270.           data.appInfo = appInfo;

271.           data.providers = providers;

272.           data.instrumentationName = instrumentationName;

273.           data.instrumentationArgs = instrumentationArgs;

274.           data.instrumentationWatcher = instrumentationWatcher;

275.           data.instrumentationUiAutomationConnection =instrumentationUiConnection;

276.           data.debugMode = debugMode;

277.           data.enableOpenGlTrace = enableOpenGlTrace;

278.           data.restrictedBackupMode = isRestrictedBackupMode;

279.            data.persistent = persistent;

280.           data.config = config;

281.           data.compatInfo = compatInfo;

282.           data.initProfilerInfo = profilerInfo;

283.           sendMessage(H.BIND_APPLICATION,data);

284.       }

 

285.private void handleBindApplication(AppBindDatadata) {

286.         ···

287.         ContextImpl instrContext =ContextImpl.createAppContext(this, pi);

288. 

289.           try {

290.                java.lang.ClassLoader cl =instrContext.getClassLoader();

291.                mInstrumentation =(Instrumentation)

292.                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();

293.           } catch (Exception e) {

294.                throw new RuntimeException(

295.                    "Unable to instantiateinstrumentation "

296.                    + data.instrumentationName+ ": " + e.toString(), e);

297.           }

298.           mInstrumentation.init(this,instrContext, appContext,

299.             new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,

300.                  data.instrumentationUiAutomationConnection);

301. 

302. 

303.        Application app = data.info.makeApplication(data.restrictedBackupMode,null);

304.           mInitialApplication = app;

305. 

306.       if (!data.restrictedBackupMode) {

307.                List<ProviderInfo>providers = data.providers;

308.                if (providers != null) {

309.                    installContentProviders(app, providers);

310.                    // For process thatcontains content providers, we want to

311.                    // ensure that the JIT isenabled "at some point".

312.                   mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);

313.                }

314.           }

315.       ···

316.       mInstrumentation.callApplicationOnCreate(app);

317. 

1,创建ContextImpl和Instrumentation,Application

2,启动数据库

3,启动Application

2.1 启动数据库

installContentProviders方法和installProvider方法在数据库文章中已经分析过了,在installProvider方法中,在构造contentprovider之后会调用

318.localProvider.attachInfo(c, info);

 

319.public void attachInfo(Context context,ProviderInfo info) {

320.       attachInfo(context, info, false);

321.}

 

322.private void attachInfo(Context context,ProviderInfo info, boolean testing) {

323.       mNoPerms = testing;

324.       if (mContext == null) {

325.           mContext = context;

326.           if (context != null) {

327.                mTransport.mAppOpsManager =(AppOpsManager) context.getSystemService(

328.                       Context.APP_OPS_SERVICE);

329.           }

330.           mMyUid = Process.myUid();

331.           if (info != null) {

332.                setReadPermission(info.readPermission);

333.               setWritePermission(info.writePermission);

334.               setPathPermissions(info.pathPermissions);

335.                mExported = info.exported;

336.                mSingleUser = (info.flags &ProviderInfo.FLAG_SINGLE_USER) != 0;

337.                setAuthorities(info.authority);

338.           }

339.           ContentProvider.this.onCreate();

340.       }

341.    }

看到了吧,最后终于会调用ContentProvider的onCreate方法了,其实是调用各自类的onCreate方法,至此,数据库已经启动了。

2.2启动Application

在handleBindApplication方法中,会调用Instrumentation的callApplicationOnCreate方法

1.   mInstrumentation.callApplicationOnCreate(app);

 

2.   public voidcallApplicationOnCreate(Application app) {

3.           app.onCreate();

4.       }

干脆直接的调用Application的onCreate方法。

 

3, 小结

进程的创建主要分为3大步:

1,AMS向zygoteState发送启动进程的请求

2, zygoteState创建并初始化进程

3,进程初始化(启动组件)

进程是四大组件的载体,在进程启动四大组件时,首先启动contentprovider,然后是Application,最后才是activity,service和广播。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值