Android系统在新进程中启动自定义服务过程startService的原理分析.docx
- 文档编号:8422036
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:30
- 大小:216.56KB
Android系统在新进程中启动自定义服务过程startService的原理分析.docx
《Android系统在新进程中启动自定义服务过程startService的原理分析.docx》由会员分享,可在线阅读,更多相关《Android系统在新进程中启动自定义服务过程startService的原理分析.docx(30页珍藏版)》请在冰豆网上搜索。
Android系统在新进程中启动自定义服务过程startService的原理分析
在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。
Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。
在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。
在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。
在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。
关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(AnonymousSharedMemory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:
viewplain
1.package shy.luo.ashmem;
2.
3.......
4.
5.public class Client extends Activity implements OnClickListener {
6. ......
7. IMemoryService memoryService = null;
8. ......
9.
10. @Override
11. public void onCreate(Bundle savedInstanceState) {
12. ......
13.
14. IMemoryService ms = getMemoryService();
15. if(ms == null) {
16. startService(new Intent("shy.luo.ashmem.server"));
17. } else {
18. Log.i(LOG_TAG, "Memory Service has started.");
19. }
20.
21. ......
22.
23. Log.i(LOG_TAG, "Client Activity Created.");
24. }
25.
26. ......
27.}
这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:
viewplain
1. android=" 2. package="shy.luo.ashmem" 3. android: sharedUserId="android.uid.system" 4. android: versionCode="1" 5. android: versionName="1.0"> 6. icon="@drawable/icon" android: label="@string/app_name"> 7. ...... 8. 9. android: enabled="true" 10. android: name=".Server" 11. android: process=".Server" > 12. 13. name="shy.luo.ashmem.server"/> 14. name="android.intent.category.DEFAULT"/> 15. 16. 17. 18.
这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:
viewplain
1.startService(new Intent("shy.luo.ashmem.server"));
就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:
viewplain
1.package shy.luo.ashmem;
2.
3.......
4.
5.public class Server extends Service {
6.
7. ......
8.
9. @Override
10. public IBinder onBind(Intent intent) {
11. return null;
12. }
13.
14. @Override
15. public void onCreate() {
16. ......
17.
18. }
19.
20. ......
21.}
下面,我们来看看Activity类中的startService成员函数是如何实现的。
先来看看Activity的类图:
从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函数。
在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用ContextImpl类的startService函数来实现。
这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式(Wrapper)。
在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。
这个ActivityManagerService类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是Binder进程间通信机制中的Server角色,它是随机启动的。
随机启动的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:
viewplain
1.class ServerThread extends Thread {
2.
3. ......
4.
5. @Override
6. public void run() {
7.
8. ......
9.
10. // Critical services...
11. try {
12.
13. ......
14.
15. context = ActivityManagerService.main(factoryTest);
16.
17. ......
18.
19. ActivityManagerService.setSystemProcess();
20.
21. ......
22.
23. } catch (RuntimeException e) {
24. Slog.e("System", "Failure starting core service", e);
25. }
26.
27. ......
28.
29. }
30.
31. ......
32.
33.}
首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:
viewplain
1.public final class ActivityManagerService extends ActivityManagerNative
2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
3.
4. ......
5.
6. static ActivityManagerService mSelf;
7.
8. ......
9.
10. public static void setSystemProcess() {
11. try {
12. ActivityManagerService m = mSelf;
13.
14. ServiceManager.addService("activity", m);
15.
16. ......
17.
18. } catch (PackageManager.NameNotFoundException e) {
19. ......
20. }
21. }
22.
23. ......
24.
25. public static final Context main(int factoryTest) {
26.
27. ......
28.
29. ActivityManagerService m = thr.mService;
30. mSelf = m;
31.
32. ......
33.
34. }
35.}
这样,ActivityManagerService就启动起来了。
回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
viewplain
1.class ActivityManagerProxy implements IActivityManager
2.{
3. ......
4.
5. public ComponentName startService(IApplicationThread caller, Intent service,
6. String resolvedType) throws RemoteException
7. {
8. Parcel data = Parcel.obtain();
9. Parcel reply = Parcel.obtain();
10. data.writeInterfaceToken(IActivityManager.descriptor);
11. data.writeStrongBinder(caller !
= null ?
caller.asBinder() :
null);
12. service.writeToParcel(data, 0);
13. data.writeString(resolvedType);
14. mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
15. reply.readException();
16. ComponentName res = ComponentName.readFromParcel(reply);
17. data.recycle();
18. reply.recycle();
19. return res;
20. }
21.
22. ......
23.}
参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。
参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。
在Android应用程序中,每一个进程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一些操作,这个我们在后面会看到它是如何用来启动服务的。
参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。
在这个例子中,我们没有指定这个Intent的MIME类型,因此,这个参数为null。
ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。
ActivityManagerService的startService函数的处理流程如下图所示:
点击查看大图
在这个序列图中,一共有20个步骤,下面说明每一步。
Step1.ActivityManagerService.startService
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
viewplain
1.public final class ActivityManagerService extends ActivityManagerNative
2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
3.
4. ......
5.
6. public ComponentName startService(IApplicationThread caller, Intent service,
7. String resolvedType) {
8. // Refuse possible leaked file descriptors
9. if (service !
= null && service.hasFileDescriptors() == true) {
10. throw new IllegalArgumentException("File descriptors passed in Intent");
11. }
12.
13. synchronized(this) {
14. final int callingPid = Binder.getCallingPid();
15. final int callingUid = Binder.getCallingUid();
16. final long origId = Binder.clearCallingIdentity();
17. ComponentName res = startServiceLocked(caller, service,
18. resolvedType, callingPid, callingUid);
19. Binder.restoreCallingIdentity(origId);
20. return res;
21. }
22. }
23.
24. ......
25.
26.}
这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。
Step2. ActivityManagerService.startServiceLocked
这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
viewplain
1.public final class ActivityManagerService extends ActivityManagerNative
2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
3.
4. ......
5.
6. ComponentName startServiceLocked(IApplicationThread caller,
7. Intent service, String resolvedType,
8. int callingPid, int callingUid) {
9. synchronized(this) {
10. ......
11.
12. ServiceLookupResult res =
13. retrieveServiceLocked(service, resolvedType,
14. callingPid, callingUid);
15.
16. ......
17.
18. ServiceRecord r = res.record;
19.
20. ......
21.
22. if (!
bringUpServiceLocked(r, service.getFlags(), false)) {
23. return new Co
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 系统 进程 启动 自定义 服务 过程 startService 原理 分析