BroadcastReceiver工作过程

概述

BroadcastReceiver是一种消息型组件。由于BroadcastReceiver可以在不同的组件甚至不同的应用之间传递消息,所以其可以脱离Activity实现,
除了要在AndroidManifest.xml中注册广播类名外,还需要添加intentfilter,这样就可以让receiver选择性的接收广播。当注册完成之后,即使没有Activity启动,
也可以接收广播。在实现 BroadcastReceiver时,需要继承 BroadcastReceiver抽象类,但是不需要重写onCreat()方法,只需重写onReceive()方法,
因此,Service没有启动和停止的概念,更像是一个系统级的监听器。

流程分析

广播的注册分为静态注册和动态注册,其中静态注册的广播在应用安装时由系统自动完成注册,具体来说是由PMS(PackageManagerService)来完成整个注册过程的。

注册过程

动态注册的过程是从ContextWrapper的registerReceiver方法开始的。

我们从该方法开始

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//ContextWrapper.java

public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}


//ContextImpl.java

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//返回ReceiverDispatcher
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//ActivityManagerService注册
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

Read More

Activity

由来

我们在做带UI的软件时,一般的做法是先创建一个窗口,然后在窗口上添加各种Button、Text、List等其他UI控件。Android、iOS也是类似,但代码的设计上跟PC端
有些差别,Android使用Activity来管理UI、iOS使用ViewController。一般软件的入口都是main函数开始,Android中则通过描述文件AndroidManifest.xml配置
一个Activity的属性作为入口。用户操作手机的时候使得一个界面可能处于可视状态,也可能处理隐藏状态,对应着Activity会有自己的生命周期。不同UI的嵌套
也是需要维护的,所以就有了Activity任务栈,对应着不同Activity有不同的启动模式。不同的Activity之间又可能需要数据传递,因而有了Intent

生命周期

回调函数

onCreate

生命周期中的第一个函数,整个生命周期中只会调用一次。savedInstanceState参数如果不为空,表示Activity暂时销毁时有存储一些数据,此时可以恢复。

onRestart

当前Activity从不可见重新变为可见状态时,会调用。

onStart

此时准备进入前台了

Read More

Activity工作过程

概述

Activity是一种展示型组件,具有两种启动方式,一种是显示的,通过intent实现;另一种是隐式的,也需要intent,但还需要在AndroidManifest.xml
中添加intentfilter。在实现Activity时,需要继承Activity抽象类,并且重写onCreat()方法,因此,Activity具有启动和停止的概念。

流程分析

流程图

Activity的启动

从startActivity开始,代码会运行到Activity的startActivityForResult方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Activity.java

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
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;
}

cancelInputsAndStartExitTransition(options);
// 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);
}
}
}

Read More