一、四大组件的运行状态
1、Activity(展示型组件)
Activity的主要作用是展示一个界面并和用户交互,它扮演的是一种前台界面的角色。
(1)需要在AndroidManifest中注册。
(2)需要借助Intent启动。有显示Intent和隐式Intent。隐式Intent指向一个或多个目标Activity组件,当然也可能没有任何一个Activity组件可以处理这个隐式Intent。
(3)对用户而言是可见的。
(4)可以具有特定的启动模式,比如singleTop、singleTask等。
(5)通过Activity的finish方法来结束一个Activity组件的运行。
2、Service(计算型组件)
Service用于在后台执行一系列计算任务。
(1)需要在AndroidManifest中注册。
(2)需要借助Intent启动。
(3)用户无法感知。
(4)两种状态:启动状态和绑定状态。
(5)启动状态:做后台计算,不需要和外界有直接的交互。尽管Service组件用于执行后台计算,但它本身是运行在主线程中的,因此耗时的后台计算仍然需要在单独的线程中去完成。
(6)绑定状态:这个时候Service内部同样可以进行后台计算,但是处于这种状态时外界可以很方便的和Service组件进行通信。IPC啊~
(7)灵活采用stopService和unBindService这两个方法才能完全停止一个Service组件。
3、BroadcastReceiver(消息型组件)
BroadcastReceiver用于在不同的组件乃至不同的应用之间传递消息。
(1)可以在AndroidManifest中静态注册,这种注册方式不需要应用启动就可以收到相应的广播;也可以在代码中动态注册,Context.registerReceiver()和 Context.unRegisterReceiver(),必须要启动应用才能注册并接收广播。
(2)需要借助Intent启动。
(3)用户无法感知。
(4)在实际开发中通过Context的一系列send方法来发送广播,被发送的广播会被系统发送给感兴趣的广播接收者,发送和接收过程的匹配是通过广播接收者的<intent-filter>来描述的。所以呢,BroadcastReceiver组件可以用来实现低耦合的观察者模式,观察者和被观察者之间可以没有任何耦合。
(5)不适合用来执行耗时操作。
(6)BroadcastReceiver组件一般来说不需要停止,它也没有停止的概念。
4、ContentProvider(数据共享型组件)
ContentProvider用于向其他组件乃至其他应用共享数据。
(1)需要在AndroidManifest中注册。
(2)无需借助Intent启动。
(3)用户无法感知。
(4)它的内部需要实现增删查改这四种操作,在它的内部维持着一份数据集合,这个数据集合既可以通过数据库来实现,也可以采用其他任何类型来实现,比如List和Map,ContentProvider对数据集合的具体实现并没有任何要求。
(5)注意点!!!ContentProvider内部的insert、deleted、update和query方法需要处理好线程同步,因为这几个方法是在Binder线程池中被调用的。
(6)ContentProvider无需手动停止。
二、Activity的工作过程
1、启动Activity
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
2、Activity的启动过程
(1)startActivity:startActivity方法有好几种重载方式,但是它们最终都会调用startActivityForResult方法。
在Activity.java文件中:
@Override
public void startActivity(Intent intent, Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
(2)startActivityForResult方法:在Activity.java文件中。
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
/*
* mParent代表的是ActivityGroup,
* ActivityGroup最开始被用来在一个界面中嵌入多个Activity,
* 但是其在API13中已经被废弃了,系统推荐采用Fragment来代替ActivityGroup。
* */
if (mParent == null) {
/*
* mMainThread.getApplicationThread()这个参数,它的类型是ApplicationThread,
* ApplicationThread是ActivityThread的一个内部类,
* 在后面的分析中可以发现,ApplicationThread和ActivityThread在Activity的启动过程中发挥着很重要的作用。
* */
Instrumentation.ActivityResult ar =
/*
* 所以说Activity的启动过程转移到了Instrumentation中的execStartActivity方法:
* */
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
(3)Instrumentation的execStartActivity方法:在Instrumentation.java文件中。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
/*
* 所以启动Activity的真正实现由ActivityManagerNative.getDefault().startActivity方法来完成。
*
* ActivityManagerService继承自ActivityManagerNative,
* 而ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,
* 因此ActivityManagerService也是一个Binder,它是IActivityManager的具体实现。
*
* 由于ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,
* 因此它的具体实现是ActivityManagerService。
* 所以说Activity的启动过程又转移到了ActivityManagerService中,
* 然后再去看ActivityManagerService的startActivity方法。
* */
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
/*
* 检查启动Activity的结果:
* */
c