前面我们在分析Activity启动过程的时候,看到同一个应用程序的Activity一般都是在同一个进程中启动,事实上,Activity也可以像Service一样在新的进程中启动,这样,一个应用程序就可以跨越好几个进程了,本文就分析一下在新的进程中启动Activity的方法和过程。在前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文中,我们提到,在Android系统中,每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中。在前面Android系统在新进程中启动自定义服务过程(startService)的原理分析一文中,我们已经介绍了使用Activity.startService接口来在新进程中启动Service的过程,然后又在前面Android应用程序内部启动Activity过程(startActivity)的源代码分析一文中介绍了使用Activity.startActivity接口来在原来的进程中启动Activity的过程,现在,我们就来看一下同一个Android应用程序如何在新的进程中启动新的Activity。老规矩,我们通过例子来介绍Android应用程序在新的进程中启动新的Activity的方法以及分析其过程。首先在Android源代码工程中创建一个Android应用程序工程,名字就称为Process吧。关于如何获得Android源代码工程,请参考在Ubuntu上下载、编译和安装Android最新源代码一文;关于如何在Android源代码工程中创建应用程序工程,请参考在Ubuntu上为Android系统内置Java应用程序测试ApplicationFrameworks层的硬件服务一文。这个应用程序工程定义了一个名为shy.luo.process的package,这个例子的源代码主要就是实现在这里了。下面,将会逐一介绍这个package里面的文件。应用程序的默认Activity定义在src/shy/luo/process/MainActivity.java文件中:viewplain1.packageshy.luo.process;2.3.importandroid.app.Activity;4.importandroid.content.Intent;5.importandroid.os.Bundle;6.importandroid.util.Log;7.importandroid.view.View;8.importandroid.view.View.OnClickListener;9.importandroid.widget.Button;10.11.publicclassMainActivityextendsActivityimplementsOnClickListener{12.privatefinalstaticStringLOG_TAG=shy.luo.process.MainActivity;13.14.privateButtonstartButton=null;15.16.@Override17.publicvoidonCreate(BundlesavedInstanceState){18.super.onCreate(savedInstanceState);19.setContentView(R.layout.main);20.21.startButton=(Button)findViewById(R.id.button_start);22.startButton.setOnClickListener(this);23.24.Log.i(LOG_TAG,MainActivityCreated.);25.}26.27.@Override28.publicvoidonClick(Viewv){29.if(v.equals(startButton)){30.Intentintent=newIntent(shy.luo.process.subactivity);31.startActivity(intent);32.}33.}34.}和前面文章的例子一样,它的实现很简单,当点击它上面的一个按钮的时候,就会启动另外一个名字为“shy.luo.process.subactivity”的Actvity。名字为“shy.luo.process.subactivity”的Actvity实现在src/shy/luo/process/SubActivity.java文件中:viewplain1.packageshy.luo.process;2.3.importandroid.app.Activity;4.importandroid.os.Bundle;5.importandroid.util.Log;6.importandroid.view.View;7.importandroid.view.View.OnClickListener;8.importandroid.widget.Button;9.10.publicclassSubActivityextendsActivityimplementsOnClickListener{11.privatefinalstaticStringLOG_TAG=shy.luo.process.SubActivity;12.13.privateButtonfinishButton=null;14.15.@Override16.publicvoidonCreate(BundlesavedInstanceState){17.super.onCreate(savedInstanceState);18.setContentView(R.layout.sub);19.20.finishButton=(Button)findViewById(R.id.button_finish);21.finishButton.setOnClickListener(this);22.23.Log.i(LOG_TAG,SubActivityCreated.);24.}25.26.@Override27.publicvoidonClick(Viewv){28.if(v.equals(finishButton)){29.finish();30.}31.}32.}它的实现也很简单,当点击上面的一个铵钮的时候,就结束自己,回到前面一个Activity中去。再来重点看一下应用程序的配置文件AndroidManifest.xml:viewplain1.?xmlversion=1.0encoding=utf-8?2.manifestxmlns:android==shy.luo.task4.android:versionCode=15.android:versionName=1.06.applicationandroid:icon=@drawable/iconandroid:label=@string/app_name7.activityandroid:name=.MainActivity8.android:label=@string/app_name9.android:process=:shy.luo.process.main10.intent-filter11.actionandroid:name=android.intent.action.MAIN/12.categoryandroid:name=android.intent.category.LAUNCHER/13./intent-filter14./activity15.activityandroid:name=.SubActivity16.android:label=@string/sub_activity17.android:process=:shy.luo.process.sub18.intent-filter19.actionandroid:name=shy.luo.task.subactivity/20.categoryandroid:name=android.intent.category.DEFAULT/21./intent-filter22./activity23./application24./manifest为了使MainActivity和SubActivity在不同的进程中启动,我们分别配置了这两个Activity的android:process属性。在官方文档中,是这样介绍Activity的android:process属性的:Thenameoftheprocessinwhichtheactivityshouldrun.Normally,allcomponentsofanapplicationruninthedefaultprocesscreatedfortheapplication.Ithasthesamenameastheapplicationpackage.Theapplicationelement'sprocessattributecansetadifferentdefaultforallcomponents.Buteachcomponentcanoverridethedefault,allowingyoutospreadyourapplicationacrossmultipleprocesses.Ifthenameassignedtothisattributebeginswithacolon(':'),anewprocess,privatetotheapplication,iscreatedwhenit'sneededandtheactivityrunsinthatprocess.Iftheprocessnamebeginswithalowercasecharacter,theactivitywillruninaglobalprocessofthatname,providedthatithaspermissiontodoso.Thisallowscomponentsindifferentapplicationstoshareaprocess,reducingresourceusage.大意为,一般情况下,同一个应用程序的Activity组件都是运行在同一个进程中,但是,如果Activity配置了android:process这个属性,那么,它就会运行在自己的进程中。如果android:process属性的值以:开头,则表示这个进程是私有的;如果android:process属性的值以小写字母开头,则表示这是一个全局进程,允许其它应用程序组件也在这个进程中运行。因此,这里我们以:开头,表示创建的是私有的进程。事实上,这里我们不要前面的:也是可以的,但是必须保证这个属性性字符串内至少有一个.字符,具体可以看一下解析AndroidManiefst.xml文件的源代码,在frameworks/base/core/java/android/content/pm/PackageParser.java文件中:viewplain1.publicclassPackageParser{2.3.......4.5.privatebooleanparseApplication(Packageowner,Resourcesres,6.XmlPullParserparser,AttributeSetat