码迷,mamicode.com
首页 > 移动开发 > 详细

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

时间:2015-06-15 20:18:22      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:

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

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

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

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系统它所要启动的服务的名字:

1.<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
2.    package="shy.luo.ashmem"  
3.    android:sharedUserId="android.uid.system"  
4.    android:versionCode="1"  
5.    android:versionName="1.0">  
6.        <application android:icon="@drawable/icon" android:label="@string/app_name">  
7.            ......  
8.            <service   
9.                android:enabled="true"   
10.                android:name=".Server"  
11.                android:process=".Server" >  
12.                    <intent-filter>  
13.                        <action android:name="shy.luo.ashmem.server"/>  
14.                        <category android:name="android.intent.category.DEFAULT"/>  
15.                    </intent-filter>  
16.            </service>  
17.        </application>  
18.</manifest> 

      这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:

startService(new Intent("shy.luo.ashmem.server"));  

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

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启动相关的代码:

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中去:

 

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文件中:

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个步骤,下面说明每一步。

         Step 1. ActivityManagerService.startService

         这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

 

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传进来的三个参数。

 

         Step 2. ActivityManagerService.startServiceLocked

         这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

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 ComponentName("!", "Service process is bad");  
24.            }  
25.            return r.name;  
26.        }  
27.    }  
28.  
29.    ......  
30.  
31.}  


       函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。

 

        Step 3. ActivityManagerService.bringUpServiceLocked

        这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

1.public final class ActivityManagerService extends ActivityManagerNative  
2.                            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
3.  
4.    ......  
5.  
6.    private final boolean bringUpServiceLocked(ServiceRecord r,  
7.                    int intentFlags, boolean whileRestarting) {  
8.  
9.        ......  
10.  
11.        final String appName = r.processName;  
12.  
13.        ......  
14.  
15.        // Not running -- get it started, and enqueue this service record  
16.        // to be executed when the app comes up.  
17.        if (startProcessLocked(appName, r.appInfo, true, intentFlags,  
18.                    "service", r.name, false) == null) {  
19.  
20.            ......  
21.  
22.            return false;  
23.        }  
24.  
25.        if (!mPendingServices.contains(r)) {  
26.            mPendingServices.add(r);  
27.        }  
28.  
29.        return true;  
30.  
31.    }  
32.  
33.    ......  
34.  
35.}  

  这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。

 

        接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

        Step 4. ActivityManagerService.startProcessLocked

        这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

 

1.public final class ActivityManagerService extends ActivityManagerNative  
2.                            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
3.  
4.    ......  
5.  
6.    private final void startProcessLocked(ProcessRecord app,  
7.                String hostingType, String hostingNameStr) {  
8.  
9.        ......  
10.  
11.        try {  
12.  
13.            ......  
14.  
15.            int pid = Process.start("android.app.ActivityThread",  
16.                            mSimpleProcessManagement ? app.processName : null, uid, uid,  
17.                            gids, debugFlags, null);  
18.  
19.            ......  
20.  
21.            if (pid == 0 || pid == MY_PID) {  
22.                  
23.                ......  
24.  
25.            } else if (pid > 0) {  
26.                app.pid = pid;  
27.                app.removed = false;  
28.                synchronized (mPidsSelfLocked) {  
29.                    this.mPidsSelfLocked.put(pid, app);  
30.                    ......  
31.                }  
32.            } else {  
33.                  
34.                ......  
35.            }  
36.  
37.        } catch (RuntimeException e) {  
38.  
39.            ......  
40.  
41.        }  
42.  
43.    }  
44.  
45.    ......  
46.  
47.}  

        这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

 

         Step 5. Process.start

         这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。

         Step 6. ActivityThread.main

         这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    public static final void main(String[] args) {  
6.  
7.        ......  
8.  
9.        Looper.prepareMainLooper();  
10.      
11.        ......  
12.  
13.        ActivityThread thread = new ActivityThread();  
14.        thread.attach(false);  
15.  
16.        ......  
17.  
18.        Looper.loop();  
19.  
20.        ......  
21.  
22.        thread.detach();  
23.      
24.        ......  
25.    }  
26.}  

   注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。

 

        前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

        Step 7. ActivityThread.attach

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    private final void attach(boolean system) {  
6.          
7.        ......  
8.  
9.        if (!system) {  
10.  
11.            ......  
12.  
13.            IActivityManager mgr = ActivityManagerNative.getDefault();  
14.            try {  
15.                mgr.attachApplication(mAppThread);  
16.            } catch (RemoteException ex) {  
17.            }  
18.        } else {  
19.          
20.            ......  
21.  
22.        }  
23.  
24.        ......  
25.  
26.    }  
27.  
28.    ......  
29.  
30.}  

  从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。

 

         调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

         Step 8. ActivityManagerProxy.attachApplication

         这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

1.class ActivityManagerProxy implements IActivityManager  
2.{  
3.    ......  
4.  
5.    public void attachApplication(IApplicationThread app) throws RemoteException  
6.    {  
7.        Parcel data = Parcel.obtain();  
8.        Parcel reply = Parcel.obtain();  
9.        data.writeInterfaceToken(IActivityManager.descriptor);  
10.        data.writeStrongBinder(app.asBinder());  
11.        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);  
12.        reply.readException();  
13.        data.recycle();  
14.        reply.recycle();  
15.    }  
16.  
17.    ......  
18.  
19.}  

 这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

        Step 9. ActivityManagerService.attachApplication

        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

1.public final class ActivityManagerService extends ActivityManagerNative  
2.                            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
3.      
4.    ......  
5.          
6.    public final void attachApplication(IApplicationThread thread)   
7.    {  
8.        synchronized (this) {  
9.            int callingPid = Binder.getCallingPid();  
10.            final long origId = Binder.clearCallingIdentity();  
11.            attachApplicationLocked(thread, callingPid);  
12.            Binder.restoreCallingIdentity(origId);  
13.        }  
14.    }  
15.      
16.    ......  
17.  
18.}  

   这里通过调用attachApplicationLocked函数进一步处理。

 

         Step 10. ActivityManagerService.attachApplicationLocked

         这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

 

1.public final class ActivityManagerService extends ActivityManagerNative  
2.                        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
3.  
4.    ......  
5.  
6.    private final boolean attachApplicationLocked(IApplicationThread thread,  
7.            int pid) {  
8.        // Find the application record that is being attached...  either via  
9.        // the pid if we are running in multiple processes, or just pull the  
10.        // next app record if we are emulating process with anonymous threads.  
11.        ProcessRecord app;  
12.        if (pid != MY_PID && pid >= 0) {  
13.            synchronized (mPidsSelfLocked) {  
14.                app = mPidsSelfLocked.get(pid);  
15.            }  
16.        } else if (mStartingProcesses.size() > 0) {  
17.            app = mStartingProcesses.remove(0);  
18.            app.setPid(pid);  
19.        } else {  
20.            app = null;  
21.        }  
22.  
23.        ......  
24.  
25.  
26.        String processName = app.processName;  
27.          
28.        ......  
29.  
30.        app.thread = thread;  
31.  
32.        ......  
33.          
34.        boolean badApp = false;  
35.  
36.        ......  
37.  
38.        // Find any services that should be running in this process...  
39.        if (!badApp && mPendingServices.size() > 0) {  
40.            ServiceRecord sr = null;  
41.            try {  
42.                for (int i=0; i<mPendingServices.size(); i++) {  
43.                    sr = mPendingServices.get(i);  
44.                    if (app.info.uid != sr.appInfo.uid  
45.                        || !processName.equals(sr.processName)) {  
46.                            continue;  
47.                    }  
48.  
49.                    mPendingServices.remove(i);  
50.                    i--;  
51.                    realStartServiceLocked(sr, app);  
52.                    didSomething = true;  
53.                }  
54.            } catch (Exception e) {  
55.  
56.                ......  
57.  
58.            }  
59.        }  
60.  
61.        ......  
62.  
63.        return true;  
64.    }  
65.  
66.    ......  
67.  
68.} 

  回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。

 

        再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。

        Step 11. ActivityManagerService.realStartServiceLocked

        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

1.class ActivityManagerProxy implements IActivityManager  
2.{  
3.    ......  
4.  
5.    private final void realStartServiceLocked(ServiceRecord r,  
6.            ProcessRecord app) throws RemoteException {  
7.          
8.        ......  
9.  
10.        r.app = app;  
11.          
12.        ......  
13.  
14.        try {  
15.  
16.            ......  
17.          
18.            app.thread.scheduleCreateService(r, r.serviceInfo);  
19.              
20.            ......  
21.  
22.        } finally {  
23.  
24.            ......  
25.  
26.        }  
27.  
28.        ......  
29.  
30.    }  
31.  
32.    ......  
33.  
34.}  

        这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。        

        Step 12. ApplicationThreadProxy.scheduleCreateService        

        这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

1.class ApplicationThreadProxy implements IApplicationThread {  
2.      
3.    ......  
4.  
5.    public final void scheduleCreateService(IBinder token, ServiceInfo info)  
6.                throws RemoteException {  
7.        Parcel data = Parcel.obtain();  
8.        data.writeInterfaceToken(IApplicationThread.descriptor);  
9.        data.writeStrongBinder(token);  
10.        info.writeToParcel(data, 0);  
11.        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,  
12.            IBinder.FLAG_ONEWAY);  
13.        data.recycle();  
14.    }  
15.  
16.    ......  
17.  
18.}  

   这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

        Step 13. ApplicationThread.scheduleCreateService

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    private final class ApplicationThread extends ApplicationThreadNative {  
6.  
7.        ......  
8.  
9.        public final void scheduleCreateService(IBinder token,  
10.        ServiceInfo info) {  
11.            CreateServiceData s = new CreateServiceData();  
12.            s.token = token;  
13.            s.info = info;  
14.  
15.            queueOrSendMessage(H.CREATE_SERVICE, s);  
16.        }  
17.  
18.        ......  
19.  
20.    }  
21.  
22.    ......  
23.  
24.}  

    这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。

 

        Step 14. ActivityThread.queueOrSendMessage

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

 

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    private final void queueOrSendMessage(int what, Object obj) {  
6.        queueOrSendMessage(what, obj, 0, 0);  
7.    }  
8.  
9.    private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {  
10.        synchronized (this) {  
11.            ......  
12.            Message msg = Message.obtain();  
13.            msg.what = what;  
14.            msg.obj = obj;  
15.            msg.arg1 = arg1;  
16.            msg.arg2 = arg2;  
17.            mH.sendMessage(msg);  
18.        }  
19.    }  
20.  
21.    ......  
22.  
23.}  

  这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。

        Step 15. H.sendMessage

        这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os/Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进行处理了。

        Step 16. H.handleMessage

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    private final class H extends Handler {  
6.          
7.        ......  
8.  
9.        public void handleMessage(Message msg) {  
10.  
11.            ......  
12.  
13.            switch (msg.what) {  
14.  
15.                ......  
16.  
17.                case CREATE_SERVICE:  
18.                    handleCreateService((CreateServiceData)msg.obj);  
19.                    break;  
20.  
21.                ......  
22.            }  
23.  
24.            ......  
25.  
26.        }  
27.  
28.        ......  
29.  
30.    }  
31.  
32.    ......  
33.  
34.}  

  这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。

 

        Step 17. ActivityThread.handleCreateService

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

1.public final class ActivityThread {  
2.      
3.    ......  
4.  
5.    private final void handleCreateService(CreateServiceData data) {  
6.        // If we are getting ready to gc after going to the background, well  
7.        // we are back active so skip it.  
8.        unscheduleGcIdler();  
9.  
10.        LoadedApk packageInfo = getPackageInfoNoCheck(  
11.            data.info.applicationInfo);  
12.        Service service = null;  
13.        try {  
14.            java.lang.ClassLoader cl = packageInfo.getClassLoader();  
15.            service = (Service) cl.loadClass(data.info.name).newInstance();  
16.        } catch (Exception e) {  
17.            if (!mInstrumentation.onException(service, e)) {  
18.                throw new RuntimeException(  
19.                    "Unable to instantiate service " + data.info.name  
20.                    + ": " + e.toString(), e);  
21.            }  
22.        }  
23.  
24.        try {  
25.            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);  
26.  
27.            ContextImpl context = new ContextImpl();  
28.            context.init(packageInfo, null, this);  
29.  
30.            Application app = packageInfo.makeApplication(false, mInstrumentation);  
31.            context.setOuterContext(service);  
32.            service.attach(context, this, data.info.name, data.token, app,  
33.                ActivityManagerNative.getDefault());  
34.            service.onCreate();  
35.            mServices.put(data.token, service);  
36.            try {  
37.                ActivityManagerNative.getDefault().serviceDoneExecuting(  
38.                    data.token, 0, 0, 0);  
39.            } catch (RemoteException e) {  
40.                // nothing to do.  
41.            }  
42.              
43.        } catch (Exception e) {  
44.            if (!mInstrumentation.onException(service, e)) {  
45.                throw new RuntimeException(  
46.                    "Unable to create service " + data.info.name  
47.                    + ": " + e.toString(), e);  
48.            }  
49.        }  
50.    }  
51.  
52.    ......  
53.  
54.}  

    这里的data.info.name就是自定义的服务类shy.luo.ashmem.Server了。

 

        Step 18. ClassLoader.loadClass

        这一步实现在上面的ActivityThread.handleCreateService函数中:

1 java.lang.ClassLoader cl = packageInfo.getClassLoader();  
2 service = (Service) cl.loadClass(data.info.name).newInstance();  


   Step 19. Obtain Service

 

        这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。

        Step 20. Service.onCreate

        这一步继续实现在上面的ActivityThread.handleCreateService函数中:

 

service.onCreate();  

        因为这里的service实际上是一个shy.luo.ashmem.Server类实例,因此,这里就是执行shy.luo.ashmem.Server类的onCreate函数了:

1.public class Server extends Service {  
2.      
3.    ......  
4.  
5.    @Override  
6.    public void onCreate() {  
7.        ......  
8.  
9.    }  
10.  
11.    ......  
12.} 

  至此,这个自定义的服务就启动起来了。

 

        这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:

        一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;

        二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;

        三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。

        学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。

转自:http://blog.csdn.net/luoshengyang/article/details/6677029

 

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

标签:

原文地址:http://www.cnblogs.com/chengzhengfu/p/4578998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!