看到同一个应用程序的Activity一般都是在同一个进程中启动,事实上,Activity也可以像Service一样在新的进程中启动,这样,一个应用程序就可以跨越好几个进程了,本文就分析一下在新的进程中启动Activity的方法和过程。

        在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中。在前面我们已经介绍了Android应用程序在Launcher桌面启动一个Activity需要启动一个进程,也介绍了在进程内部启动Activity过程(startActivity)。而现在,我们就来看一下同一个Android应用程序如何在新的进程中启动新的Activity。


要做到这个其实很简单,只需要在AndroidManifest.xml中将主Activity和要启动的Activity的android:process属性设置为不同的

[html]

1. <?xml version="1.0" encoding="utf-8"?>
2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3. package="shy.luo.task"
4. android:versionCode="1"
5. android:versionName="1.0">
6. <application android:icon="@drawable/icon" android:label="@string/app_name">
7. <activity android:name=".MainActivity"
8. android:label="@string/app_name">
9. android:process=":com.example.process.main"
10. <intent-filter>
11. <action android:name="android.intent.action.MAIN" />
12. <category android:name="android.intent.category.LAUNCHER" />
13. </intent-filter>
14. </activity>
15. <activity android:name=".SubActivity"
16. android:label="@string/sub_activity"
17. android:process=":shy.luo.process.sub">
18. <intent-filter>
19. <action android:name="com.example.process.subactivity"/>
20. <category android:name="android.intent.category.DEFAULT"/>
21. </intent-filter>
22. </activity>
23. </application>
24. </manifest>


同一个应用程序的Activity组件都是运行在同一个进程中,但是,如果Activity配置了android:process这个属性,那么,它就会运行在自己的进程中。如果android:process属性的值以":"开头,则表示这个进程是私有的;如果android:process属性的值以小写字母开头,则表示这是一个全局进程,允许其它应用程序组件也在这个进程中运行。

        因此,这里我们以":"开头,表示创建的是私有的进程。事实上,这里我们不要前面的":"也是可以的,但是必须保证这个属性性字符串内至少有一个"."字符。

具体解析AndroidManifest.xml会在安装apk的时候在PKMS调用PackageParser的parseBaseApplication来解析。具体代码我们会在后续博客(专门讲PKMS安装apk)中再分析。

这样processName不一样之后,在AMS启动一个Activity时开启一个进程。当再启动一个Activity的时候,因为processName不一样,发现没有进程的processName是这个name。所以就要再起一个进程,具体代码我们之前博客也分析过,是在ActivityStackSupervisor的startSpecificActivityLocked函数中,发现没有这个processName的进程后。会调用mService.startProcessLocked函数重启启动一个进程,也会新建一个ProcessRecord保存这个进程的信息。

[cpp] 

1. void
2.         boolean andResume, boolean checkConfig) {  
3. // Is this activity's application already running?
4.     ProcessRecord app = mService.getProcessRecordLocked(r.processName,  
5. true);  
6.   
7.     r.task.stack.setLaunchTime(r);  
8.   
9. if (app != null && app.thread
10. try
11. if
12. "android".equals(r.info.packageName)) {  
13. // Don't add this if it is a platform component that is marked
14. // to run in multiple processes, because this is actually
15. // part of the framework so doesn't make sense to track as a
16. // separate apk in the process.
17.                 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,  
18.                         mService.mProcessStats);  
19.             }  
20.             realStartActivityLocked(r, app, andResume, checkConfig);  
21. return;  
22. catch
23. "Exception when starting activity "
24.                     + r.intent.getComponent().flattenToShortString(), e);  
25.         }  
26.   
27. // If a dead object exception was thrown -- fall through to
28. // restart the application.
29.     }  
30.   
31. true, 0,  
32. "activity", r.intent.getComponent(), false, false, true);  
33. }