Android系统在新进程中启动自定义服务过程startService的原理分析.docx

上传人:b****5 文档编号:8422036 上传时间:2023-01-31 格式:DOCX 页数:30 大小:216.56KB
下载 相关 举报
Android系统在新进程中启动自定义服务过程startService的原理分析.docx_第1页
第1页 / 共30页
Android系统在新进程中启动自定义服务过程startService的原理分析.docx_第2页
第2页 / 共30页
Android系统在新进程中启动自定义服务过程startService的原理分析.docx_第3页
第3页 / 共30页
Android系统在新进程中启动自定义服务过程startService的原理分析.docx_第4页
第4页 / 共30页
Android系统在新进程中启动自定义服务过程startService的原理分析.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

Android系统在新进程中启动自定义服务过程startService的原理分析.docx

《Android系统在新进程中启动自定义服务过程startService的原理分析.docx》由会员分享,可在线阅读,更多相关《Android系统在新进程中启动自定义服务过程startService的原理分析.docx(30页珍藏版)》请在冰豆网上搜索。

Android系统在新进程中启动自定义服务过程startService的原理分析.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1