在Android应用中一般都是通过另一个已经启动的Activity对象,调用其startActivity()或startActivityForResult()方法来启动一个Activity,或者通过Service对象,Application对象的startActivity()方法也可以启动Activity。
startActivity()方法的定义
startActivity()方法其实是Context类中的方法。它的定义如下。
public void startActivity(Intent intent)
然而Context只是一个抽象类,并没有实现startActivity()这个方法,它的实现是在继承它的子类中实现的。
常见的Context及子类的继承关系如下。
在ContextImpl,ContextWrapper和Activity类中都有startActivity()方法的实现,而Service,ContextThemeWrapper和Application类只是继承了ContextWrapper类中的startActivity()方法。
再来看ContextWrapper中的实现。ContextWrapper类从名字可以看出它是Context的封装类,它的的内部有一个Context成员变量mBase,startActivity()的实现方法调用的是mBase的startActivity()方法。而这个mBase成员变量通常就是ContextImpl对象。
// ContextWrapper类中的startActivity()方法
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
所以这6个类中,只有ContextImpl和Activity中有startActivity()方法的具体实现,其他4个类中的startActivity()则实际调用的是ContextImpl中的startActivity()。ContextImpl和Activity中的startActivity()方法最终调用的都是Instrumentation类中的execStartActivity()方法,Activity中的startActivity()比ContextImpl中的startActivity()多了一些关于parent Activity, Activity options,Activity result的处理流程。
startActivity()方法的使用
startActivity()方法只有一个Intent参数,Intent对象中包含了要启动Activity的各项信息。使用startActivity()方法关键就在构造需要的Intent对象。在介绍如何构造Intent对象之前,这里打算先介绍下另一个启动Activity的方法startActivityForResult()。
startActivityForResult()方法的定义
startActivityForResult()方法是Activity类中的方法,在Application,Service中没有此方法,所以在Application,Service中是不能用startActivityForResult()方法启动Activity的。startActivityForResult()的定义如下。
public void startActivityForResult(Intent intent, int requestCode);
startActivityForResult()方法的使用
可以看到startActivityForResult()有两个参数,intent和requestCode,intent的含义和用法和startActivity()的intent完全相同,会在后文介绍。requestCode则是用来标记此次请求的请求码,可以由调用的Activity自由定义,但是它的取值范围并非整个整数集,而是必须在[0,65535]之间,否则在执行startActivityForResult()时会产生异常。
和startActivity()的区别是,startActivityForResult()启动一个Activity后,允许在新启动的Activity中返回结果,在调用startActivityForResult()的Activity中可以获取到这个结果。
在被启动的Activity中可以通过setResult()方法来返回需要的结果和数据。
setResult()有两个重载的方法,分别定义如下。
public final void setResult(int resultCode);
public final void setResult(int resultCode, Intent data);
resultCode表示返回的结果,data则表示返回的数据。当调用setResult(resultCode)时,表示只需要返回结果,没有数据,等同于setResult(resultCode, null);
在主调Activity中可以通过重写其onActivityResult()方法来得到被启动的Activity中返回的结果。onActivityResult()方法定义如下。
protected void onActivityResult(int requestCode, int resultCode, Intent data);
requestCode是之前调用startActivityForResult()时传入的参数,它的作用就是用来区分不同的startActivityForResult()调用。resultCode和data就是在被启动的Activity中通过setResult()返回的结果和数据。
在Activity中预定义了两个表示结果的常量,RESULT_CANCELED和RESULT_OK。很多时候我们并不需要在被调用的Activity返回时表达很多的返回结果,例如只需要告知主调Activity结果是成功还是失败,需要处理数据还是不需要处理等。这时就可以不需要再额外定义新的常量表示返回结果,直接使用这两个常量即可。值得注意的是RESULT_CANCELED的值是0,而RESULT_OK的值是-1,和通常情况下用0或正值表示成功,负值表示失败的用法不同。
使用setResult()和onActivityResult()还有如下几点需要注意:
如果主调Activity是通过startActivity()来启动一个Activity,则被启动的Activity中无论是否有执行setResult(),主调Activity的onActivityResult()都不会被调用。
如果主调Activity是通过startActivityForResult()来启动一个Activity,则被启动的Activity中无论是否有执行setResult(),主调Activity的onActivityResult()都会被调用。如果被启动的Activity没有执行setResult(),则主调Activity的onActivityResult()中的resultCode等于RESULT_CANCELED(0),data为null。
被调用的Activity要想返回结果和数据,则必须在Activity finish之前执行setResult(),如果Activi