您的位置:首页 > 移动开发 > Android开发

Android 进程启动源码解析

2016-10-21 20:32 246 查看
在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和广播。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息