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

本文深入分析了Android系统如何通过startService在新进程中启动自定义服务的原理,涉及Binder进程间通信、ActivityManagerService、ServiceRecord、ApplicationThread等关键组件,帮助开发者理解Service启动流程和提高应用性能。
摘要由CSDN通过智能技术生成
               

        在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!

        在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

        关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:

package shy.luo.ashmem;......public class Client extends Activity implements OnClickListener { ...... IMemoryService memoryService = null; ...... @Override public void onCreate(Bundle savedInstanceState) {  ......  IMemoryService ms = getMemoryService();  if(ms == null) {           startService(new Intent("shy.luo.ashmem.server"));  } else {   Log.i(LOG_TAG, "Memory Service has started.");  }  ......  Log.i(LOG_TAG, "Client Activity Created."); } ......}

        这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="shy.luo.ashmem" android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0">  <application android:icon="@drawable/icon" android:label="@string/app_name">   ......   <service     android:enabled="true"     android:name=".Server"    android:process=".Server" >     <intent-filter>      <action android:name="shy.luo.ashmem.server"/>      <category android:name="android.intent.category.DEFAULT"/>     </intent-filter>   </service>  </application></manifest> 
         这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:

startService(new Intent("shy.luo.ashmem.server"));
         就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:

package shy.luo.ashmem;......public class Server extends Service {  ...... @Override public IBinder onBind(Intent intent) {   return null; } @Override public void onCreate() {  ...... } ......}
        下面,我们来看看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启动相关的代码:

class ServerThread extends Thread {  ...... @Override public void run() {  ......  // Critical services...  try {   ......   context = ActivityManagerService.main(factoryTest);   ......   ActivityManagerService.setSystemProcess();   ......    } catch (RuntimeException e) {   Slog.e("System", "Failure starting core service", e);  }  ......  } ......}
          首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程ServiceManager中去:

public final class ActivityManagerService extends ActivityManagerNative  implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... static ActivityManagerService mSelf; ...... public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值