Android系统四大组件源代码情景分析之Service

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/litao55555/article/details/83961729

1. Service用法

好文:https://blog.csdn.net/sy755754582/article/details/53924642
效果:后台播放音乐

1.1 定义Service

public class MyService extends Service {
    MediaPlayer mediaPlayer;
    @Override
    public IBinder onBind(Intent intent) {		//必须要实现此方法,IBinder对象用于交换数据,此处暂时不实现
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        mediaPlayer =MediaPlayer.create(this,R.raw.citylights);
        Log.e("TAG","create");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        play();
        Log.e("TAG","start");
        return super.onStartCommand(intent, flags, startId);
    }
    private void play() {		    //封装播放
        mediaPlayer.start();
    }
    @Override
    public void onDestroy() {		//service被关闭之前调用
        super.onDestroy();
        mediaPlayer.stop();
        Log.e("TAG","destoryed");
    }
}

1.2 注册Service

AndroidManifest.xml中对Service进行注册

<service android:name=".MyService"></service>

1.3 使用Service

在Activity的onCreate函数中执行

Intent intent=new Intent(this,MyService.class);
startService(intent);		//启动服务,调用Service.onCreate的方法
stopService(intent);		//停止服务,调用Service.onDestory方法

1.4 Service用法总结

a. 继承Service,复写onCreate、onBind、onStartCommand、onDestroy
b. AdnroidManifest.xml中注册Service
c. 启动或停止Service:
参考http://www.cnblogs.com/huihuizhang/p/7623760.html
c.1 启动方式1
startService():onCreate - onStartCommand - 运行
stopService() :onDestroy - 停止
c.2 启动方式2
bindService() :onCreate - onBind - 运行
unbindService():onUnbind - onDestroy - 停止

2. Service原理分析

Activity,Service,Application都是ContextWrapper的子类,ContextWrapper里面有一个Context类型的成员变量mBase,当然它实际的类型是ContextImpl
上述结论分析参考装饰者模式:https://blog.csdn.net/litao55555/article/details/83868852

2.1 分析StartService

Intent intent = new Intent(this, MyService.class);
startService(intent);		---------------------------------------------------//intent = new Intent(this, MyService.class);
                                                                          |
frameworks\base\core\java\android\content\ContextWrapper.java             |
public class ContextWrapper extends Context {                             |
		public ComponentName startService(Intent service) {		<----------------
        return mBase.startService(service);		--------------------------------------------------
    }                                                                                          |
}                                                                                              |
                                                                                               |
frameworks\base\core\java\android\app\ContextImpl.java                                         |
class ContextImpl extends Context {                                                            |
		public ComponentName startService(Intent service) {		<-------------------------------------
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);		----------------------------------------------
    }                                                                                                    |
    private ComponentName startServiceCommon(Intent service, boolean requireForeground,		<---------------
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManager.getService().startService(			---------------------------------------------
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(                                 |
                            getContentResolver()), requireForeground,                                                     |
                            getOpPackageName(), user.getIdentifier());                                                    |
            ...                                                                                                           |
            return cn;                                                                                                    |
        } catch (RemoteException e) {                                                                                     |
            ...                                                                                                           |
        }                                                                                                                 |
    }                                                                                                                     |
}                                                                                                                         |
                                                                                                                          |
分析ActivityManager.getService()                                                                                          |
frameworks\base\core\java\android\app\ActivityManager.java                                                                |
public class ActivityManager {                                                                                            |
		private static final Singleton<IActivityManager> IActivityManagerSingleton =                                          |
            new Singleton<IActivityManager>() {                                                                           |
                @Override                                                                                                 |
                protected IActivityManager create() {                                                                     |
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);                                |
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);                                     |
                    return am;                                                                                            |
                }                                                                                                         |
            };                                                                                                            |
    public static IActivityManager getService() {                                                                         |
        return IActivityManagerSingleton.get();                                                                           |
    }                                                                                                                     |
}                                                                                                                         |
		||                                                                                                                    |
		\/AIDL                                                                                                                |
																																																													|
分析ActivityManager.getService().startService(...)																																				|
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java                                      |
public class ActivityManagerService extends IActivityManager.Stub                                                         |
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {                                                   |
		final ActiveServices mServices;                                                                                       |
		public ComponentName startService(IApplicationThread caller, Intent service,			<------------------------------------
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ...
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
                res = mServices.startServiceLocked(caller, service, 		--------------------------------------------------------------
                        resolvedType, callingPid, callingUid,                                                                        |
                        requireForeground, callingPackage, userId);                                                                  |
            } finally {                                                                                                              |
                Binder.restoreCallingIdentity(origId);                                                                               |
            }                                                                                                                        |
            return res;                                                                                                              |
        }                                                                                                                            |
    }                                                                                                                                |
}                                                                                                                                    |
                                                                                                                                     |
frameworks\base\services\core\java\com\android\server\am\ActiveServices.java                                                         |
public final class ActiveServices {                                                                                                  |
		ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,		<-----------------------------//service = new Intent(this, MyService.class);
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
				...
				ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false);		//此函数的功能是创建ServiceRecord并保存到res.record
        ServiceRecord r = res.record;											//获得ServiceRecord
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;
        r.delayedStop = false;
        r.fgRequired = fgRequired;
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants, callingUid));
        final ServiceMap smap = getServiceMapLocked(r.userId);
				ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);		----------------
        return cmp;                                                                                              |
    }                                                                                                            |
    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,		<-------------------
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        ...
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);		------------------------------
    }                                                                                                                      |
    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,		<-----------------------------
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ...
        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        String hostingType = "service";
        ProcessRecord app;
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);		----------------------------------------------------------
                    return null;                                                                                         |
                } catch (TransactionTooLargeException e) {                                                               |
                    ...                                                                                                  |
                } catch (RemoteException e) {                                                                            |
                    ...                                                                                                  |
                }                                                                                                        |
            }                                                                                                            |
        } else {                                                                                                         |
            ...                                                                                                          |
        }                                                                                                                |
    }                                                                                                                    |
    private final void realStartServiceLocked(ServiceRecord r,		<-------------------------------------------------------
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
        try {
        		app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
				}
				sendServiceArgsLocked(r, execInFg, true);
		}
}

2.1.1 分析app.thread.scheduleCreateService(…);

由于app是ProcessRecord实例化对象,在ProcessRecord中成员变量thread是IApplicationThread实例化对象,所以由AIDL机制可知
调用ApplicationThread.scheduleCreateService
		||
		\/AIDL
frameworks\base\core\java\android\app\ActivityThread.java
public final class ActivityThread {
		private class ApplicationThread extends IApplicationThread.Stub {
				public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;
            sendMessage(H.CREATE_SERVICE, s);					------------------------------------------
        }                                                                                      |
		}                                                                                          |
		private class H extends Handler {                                                          |
				public void handleMessage(Message msg) {						<-----------------------------------
						switch (msg.what) {
								case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);		---------------------------------------
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                                         |
                    break;                                                                                    |
            }                                                                                                 |
        }                                                                                                     |
    }                                                                                                         |
    private void handleCreateService(CreateServiceData data) {     <-------------------------------------------
    		LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();		//通过ClassLoader加载service的实例
        } catch (Exception e) {
            ...
        }
        try {
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);		//创建ContextImpl对象context
            context.setOuterContext(service);
            Application app = packageInfo.makeApplication(false, mInstrumentation);		//创建Application对象并调用其onCreate方法
            service.attach(context, this, data.info.name, data.token, app,						//通过Service的attach方法将Service和ContextImpl对象context关联起来(与Activity类似)
                    ActivityManager.getService());
            service.onCreate();										//重点1:调用Service的onCreate方法
            mServices.put(data.token, service);																				//将Service对象存入ActivityThread.mServies
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
						...
        }
    }
}

2.1.2 分析sendServiceArgsLocked(r, execInFg, true);

frameworks\base\services\core\java\com\android\server\am\ActiveServices.java
public final class ActiveServices {
		private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
				ArrayList<ServiceStartArgs> args = new ArrayList<>();
        while (r.pendingStarts.size() > 0) {
            ServiceRecord.StartItem si = r.pendingStarts.remove(0);
            si.deliveredTime = SystemClock.uptimeMillis();
            r.deliveredStarts.add(si);
            si.deliveryCount++;
            if (si.neededGrants != null) {
                mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
                        si.getUriPermissionsLocked());
            }
            mAm.grantEphemeralAccessLocked(r.userId, si.intent,
                    r.appInfo.uid, UserHandle.getAppId(si.callingId));
            bumpServiceExecutingLocked(r, execInFg, "start");
            ...
            args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
        }
				try {
            r.app.thread.scheduleServiceArgs(r, slice); 		------------------------------------------------------------------------
        }                                                                                                                          |
		}                                                                                                                              |
}                                                                                                                                  |
                                                                                                                                   |
由于app是ProcessRecord实例化对象,在ProcessRecord中成员变量thread是IApplicationThread实例化对象,所以由AIDL机制可知                |
调用ApplicationThread.scheduleCreateService                                                                                        |
		||                                                                                                                             |
		\/AIDL                                                                                                                         |
frameworks\base\core\java\android\app\ActivityThread.java                                                                          |
public final class ActivityThread {                                                                                                |
		private class ApplicationThread extends IApplicationThread.Stub {                                                              |
				public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {		<-----------------------------------------
            List<ServiceStartArgs> list = args.getList();
            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;
                sendMessage(H.SERVICE_ARGS, s);		-------------------------------------
            }                                                                         |
        }                                                                             |
		}                                                                                 |
		private void sendMessage(int what, Object obj) {		<------------------------------
        sendMessage(what, obj, 0, 0, false);		--------------------------------------------------------------
    }                                                                                                        |
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {		<-------------------
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);		---------------------------------------
    }                                                                 |
		private class H extends Handler {                                 |
				public void handleMessage(Message msg) {		<------------------
						switch (msg.what) {
								case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                    handleServiceArgs((ServiceArgsData)msg.obj); 		--------------------------------------
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                                    |
                    break;                                                                               |
            }                                                                                            |
        }                                                                                                |
    }                                                                                                    |
    private void handleServiceArgs(ServiceArgsData data) {		<-------------------------------------------
        Service s = mServices.get(data.token);
        res = s.onStartCommand(data.args, data.flags, data.startId);		//重点2:调用Service的onStartCommand方法
    }
}

2.1.3 StartService启动Service总结

IPC调用AMS.startService(),最终调用ActiveServices.realStartServiceLocked启动Service,在此方法中分别执行
a. scheduleCreateService(…)最终执行onCreate()
b. sendServiceArgsLocked(…)最终执行onStartCommand()

2.2 分析bindService

参考:https://blog.csdn.net/zjws23786/article/details/51865238
Activity成员变量:

private boolean isBound = false;
private BindService bindService = null;
private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {			//连接服务时调用
        isBound = true;
        BindService.MyBinder binder = (BindService.MyBinder) service;
        bindService = binder.getService();
        int num = bindService.getRandomNumber();
        Log.v("hjz","numA="+num);
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {										//断开服务时调用
        Log.v("hjz","onServiceDisconnected  A");
    }
};

Activity.onCreate执行:

Intent intent = new Intent(this,MyService.class);
bindService(intent, conn, BIND_AUTO_CREATE);		--------------------------------------
                                                                                     |
frameworks\base\core\java\android\content\ContextWrapper.java                        |
public class ContextWrapper extends Context {                                        |
		public boolean bindService(Intent service, ServiceConnection conn,		<-----------
            int flags) {
        return mBase.bindService(service, conn, flags);		---------------------------------------------
    }                                                                                                 |
}                                                                                                     |
                                                                                                      |
frameworks\base\core\java\android\app\ContextImpl.java                                                |
class ContextImpl extends Context {                                                                   |
		public boolean bindService(Intent service, ServiceConnection conn,		<----------------------------
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), 		----------------------------------------
                Process.myUserHandle());                                                                                   |
    }                                                                                                                      |
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler		<-----------------------
            handler, UserHandle user) {
        try {
            IBinder token = getActivityToken();
            service.prepareToLeaveProcess(this);
            int res = ActivityManager.getService().bindService(			-------------------------------------------------------
                mMainThread.getApplicationThread(), getActivityToken(), service,                                          |
                service.resolveTypeIfNeeded(getContentResolver()),                                                        |
                sd, flags, getOpPackageName(), user.getIdentifier());                                                     |
            return res != 0;                                                                                              |
        } catch (RemoteException e) {                                                                                     |
            ...                                                                                                           |
        }                                                                                                                 |
    }                                                                                                                     |
}                                                                                                                         |
                                                                                                                          |
分析ActivityManager.getService()                                                                                          |
frameworks\base\core\java\android\app\ActivityManager.java                                                                |
public class ActivityManager {                                                                                            |
		private static final Singleton<IActivityManager> IActivityManagerSingleton =                                          |
            new Singleton<IActivityManager>() {                                                                           |
                @Override                                                                                                 |
                protected IActivityManager create() {                                                                     |
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);                                |
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);                                     |
                    return am;                                                                                            |
                }                                                                                                         |
            };                                                                                                            |
    public static IActivityManager getService() {                                                                         |
        return IActivityManagerSingleton.get();                                                                           |
    }                                                                                                                     |
}                                                                                                                         |
		||                                                                                                                    |
		\/AIDL                                                                                                                |
																																																													|
分析ActivityManager.getService().bindService(...)																																					|
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java                                      |
public class ActivityManagerService extends IActivityManager.Stub                                                         |
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {                                                   |
		final ActiveServices mServices;                                                                                       |
		public int bindService(IApplicationThread caller, IBinder token, Intent service,     	<--------------------------------
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
        synchronized(this) {
            return mServices.bindServiceLocked(caller, token, service,		--------------------------------------------------------------
                    resolvedType, connection, flags, callingPackage, userId);                                                          |
        }                                                                                                                              |
    }                                                                                                                                  |
}                                                                                                                                      |
                                                                                                                                       |
frameworks\base\services\core\java\com\android\server\am\ActiveServices.java                                                           |
public final class ActiveServices {                                                                                                    |
		int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,		<-------------------------------------------------
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
				if ((flags&Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, 		-----------------------------------
                    permissionsReviewRequired) != null) {                                                         |
                return 0;                                                                                         |
            }                                                                                                     |
        }                                                                                                         |
		}                                                                                                             |
		private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,		<--------------------
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
        ...
        if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
            if (app != null && app.thread != null) {
                try {
                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
                    realStartServiceLocked(r, app, execInFg);		---------------------------------------------------
                    return null;                                                                                  |
                } catch (TransactionTooLargeException e) {                                                        |
                    ...                                                                                           |
                } catch (RemoteException e) {                                                                     |
                    ...                                                                                           |
                }                                                                                                 |
            }                                                                                                     |
        } else {                                                                                                  |
            ...                                                                                                   |
        }                                                                                                         |
    }                                                                                                             |
    private final void realStartServiceLocked(ServiceRecord r,		<------------------------------------------------
            ProcessRecord app, boolean execInFg) throws RemoteException {
        ...
        app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
        requestServiceBindingsLocked(r, execInFg);
    }
}

2.2.1 分析app.thread.scheduleCreateService(…)

由于app是ProcessRecord实例化对象,在ProcessRecord中成员变量thread是IApplicationThread实例化对象,所以由AIDL机制可知
调用ApplicationThread.scheduleCreateService
		||
		\/AIDL
frameworks\base\core\java\android\app\ActivityThread.java
public final class ActivityThread {
		private class ApplicationThread extends IApplicationThread.Stub {
				public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;
            sendMessage(H.CREATE_SERVICE, s);					------------------------------------------
        }                                                                                      |
		}                                                                                          |
		private class H extends Handler {                                                          |
				public void handleMessage(Message msg) {						<-----------------------------------
						switch (msg.what) {
								case CREATE_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                    handleCreateService((CreateServiceData)msg.obj);		---------------------------------------
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                                         |
                    break;                                                                                    |
            }                                                                                                 |
        }                                                                                                     |
    }                                                                                                         |
    private void handleCreateService(CreateServiceData data) {     <-------------------------------------------
    		LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();		//通过ClassLoader加载service的实例
        } catch (Exception e) {
            ...
        }
        try {
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);		//创建ContextImpl对象context
            context.setOuterContext(service);
            Application app = packageInfo.makeApplication(false, mInstrumentation);		//创建Application对象并调用其onCreate方法
            service.attach(context, this, data.info.name, data.token, app,						//通过Service的attach方法将Service和ContextImpl对象context关联起来(与Activity类似)
                    ActivityManager.getService());
            service.onCreate();										//重点1:调用Service的onCreate方法
            mServices.put(data.token, service);																				//将Service对象存入ActivityThread.mServies
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
						...
        }
    }
}

2.2.2 分析requestServiceBindingsLocked(r, execInFg);

frameworks\base\services\core\java\com\android\server\am\ActiveServices.java
public final class ActiveServices {
    private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
            throws TransactionTooLargeException {
        for (int i=r.bindings.size()-1; i>=0; i--) {
            IntentBindRecord ibr = r.bindings.valueAt(i);
            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {		--------------------------------------
                break;                                                                                           |
            }                                                                                                    |
        }                                                                                                        |
    }                                                                                                            |
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,		<-------------------
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
        ...
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,		------------------------------------------
                        r.app.repProcState);                                                                                 |
                if (!rebind) {                                                                                               |
                    i.requested = true;                                                                                      |
                }                                                                                                            |
                i.hasBound = true;                                                                                           |
                i.doRebind = false;                                                                                          |
            } catch (TransactionTooLargeException e) {                                                                       |
                ...                                                                                                          |
            } catch (RemoteException e) {                                                                                    |
                ...                                                                                                          |
            }                                                                                                                |
        }                                                                                                                    |
        return true;                                                                                                         |
    }                                                                                                                        |
}                                                                                                                            |
                                                                                                                             |
由于app是ProcessRecord实例化对象,在ProcessRecord中成员变量thread是IApplicationThread实例化对象,所以由AIDL机制可知          |
调用ApplicationThread.scheduleBindService                                                                                    |
		||                                                                                                                       |
		\/AIDL                                                                                                                   |
frameworks\base\core\java\android\app\ActivityThread.java                                                                    |
public final class ActivityThread {                                                                                          |
		private class ApplicationThread extends IApplicationThread.Stub {                                                        |
				public final void scheduleBindService(IBinder token, Intent intent,		<-----------------------------------------------
                boolean rebind, int processState) {
            updateProcessState(processState, false);
            BindServiceData s = new BindServiceData();
            s.token = token;
            s.intent = intent;
            s.rebind = rebind;
            sendMessage(H.BIND_SERVICE, s);		-------------------------------
        }                                                                   |
		}                                                                       |
		private void sendMessage(int what, Object obj) {		<--------------------
        sendMessage(what, obj, 0, 0, false);		------------------------------------------------------
    }                                                                                                |
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {		<-----------
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);		----------------------------------
    }                                                            |
		private class H extends Handler {                            |
				public void handleMessage(Message msg) {		<-------------
						switch (msg.what) {
								case BIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                    handleBindService((BindServiceData)msg.obj);		------------------------------
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                            |
                    break;                                                                       |
            }                                                                                    |
        }                                                                                        |
    }                                                                                            |
    private void handleBindService(BindServiceData data) {		<-----------------------------------
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                try {
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);							//重点2:调用Service的onBind方法
                        ActivityManager.getService().publishService(		---------------------------------------------------
                                data.token, data.intent, binder);                                                         |
                    } else {                                                                                              |
                    		...                                                                                               |
                    }                                                                                                     |
                    ensureJitEnabled();                                                                                   |
                } catch (RemoteException ex) {                                                                            |
                		...                                                                                                   |
                }                                                                                                         |
            } catch (Exception e) {                                                                                       |
            		...                                                                                                       |
            }                                                                                                             |
        }                                                                                                                 |
    }                                                                                                                     |
}                                                                                                                         |
                                                                                                                          |
分析ActivityManager.getService()                                                                                          |
frameworks\base\core\java\android\app\ActivityManager.java                                                                |
public class ActivityManager {                                                                                            |
		private static final Singleton<IActivityManager> IActivityManagerSingleton =                                          |
            new Singleton<IActivityManager>() {                                                                           |
                @Override                                                                                                 |
                protected IActivityManager create() {                                                                     |
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);                                |
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);                                     |
                    return am;                                                                                            |
                }                                                                                                         |
            };                                                                                                            |
    public static IActivityManager getService() {                                                                         |
        return IActivityManagerSingleton.get();                                                                           |
    }                                                                                                                     |
}                                                                                                                         |
		||                                                                                                                    |
		\/AIDL                                                                                                                |
																																																													|
分析ActivityManager.getService().publishService(...)																																			|
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java                                      |
public class ActivityManagerService extends IActivityManager.Stub                                                         |
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {                                                   |
		final ActiveServices mServices;                                                                                       |
		public void publishService(IBinder token, Intent intent, IBinder service) {		<----------------------------------------
        synchronized(this) {
        		...
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);		----------------------------
        }                                                                                                        |
    }                                                                                                            |
}                                                                                                                |
                                                                                                                 |
frameworks\base\services\core\java\com\android\server\am\ActiveServices.java                                     |
public final class ActiveServices {                                                                              |
		void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {		<-----------------------------
				for (int conni=r.connections.size()-1; conni>=0; conni--) {
            ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
            for (int i=0; i<clist.size(); i++) {
                ConnectionRecord c = clist.get(i);
                ...
                try {
                    c.conn.connected(r.name, service, false);		------------------------------------//c的类型就是Connectionrecord,而c.conn的类型就是ServiceDispatcher.InnerConnection对象
                } catch (Exception e) {                                                            |
                    ...                                                                            |
                }                                                                                  |
            }                                                                                      |
        }                                                                                          |
		}                                                                                              |
}                                                                                                  |
                                                                                                   |
frameworks\base\core\java\android\app\LoadedApk.java                                               |
public final class LoadedApk {                                                                     |
		static final class ServiceDispatcher {                                                         |
				private static class InnerConnection extends IServiceConnection.Stub {                     |
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;                          |
            InnerConnection(LoadedApk.ServiceDispatcher sd) {                                      |
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);                  |
            }                                                                                      |
            public void connected(ComponentName name, IBinder service, boolean dead) 		<-----------
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);		-------------------------------------
                }                                                                             |
            }                                                                                 |
        }                                                                                     |
        public void connected(ComponentName name, IBinder service, boolean dead) {		<--------
            if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));		-------------------------//ServiceDispatcher的mActivityThread就是一个handler,对应ActivityThread中的H类,这样RunConnection经过H.post运行在主线程中
            } else {                                                                                        |
                doConnected(name, service, dead);                                                           |
            }                                                                                               |
        }                                                                                                   |
        private final class RunConnection implements Runnable {                                             |
            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {                 |
                mName = name;                                                                               |
                mService = service;                                                                         |
                mCommand = command;                                                                         |
                mDead = dead;                                                                               |
            }                                                                                               |
            public void run() {		<--------------------------------------------------------------------------
                if (mCommand == 0) {
                    doConnected(mName, mService, mDead);		-----------------------------------------------------------------
                } else if (mCommand == 1) {                                                                                 |
                    doDeath(mName, mService);                                                                               |
                }                                                                                                           |
            }                                                                                                               |
            final ComponentName mName;                                                                                      |
            final IBinder mService;                                                                                         |
            final int mCommand;                                                                                             |
            final boolean mDead;                                                                                            |
        }                                                                                                                   |
        public void doConnected(ComponentName name, IBinder service, boolean dead) {		<------------------------------------
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;
            synchronized (this) {
                old = mActiveConnections.get(name);
                if (service != null) {
                    info = new ConnectionInfo();
                    info.binder = service;
                    info.deathMonitor = new DeathMonitor(name, service);
                    try {
                        service.linkToDeath(info.deathMonitor, 0);
                        mActiveConnections.put(name, info);
                    } catch (RemoteException e) {
                    		...
                    }
                } else {
                    mActiveConnections.remove(name);
                }
                if (old != null) {
                    old.binder.unlinkToDeath(old.deathMonitor, 0);
                }
            }
            // If there was an old service, it is now disconnected.
            if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
            if (dead) {
                mConnection.onBindingDied(name);
            }
            // If there is a new service, it is now connected.
            if (service != null) {
                mConnection.onServiceConnected(name, service);					//重点3:调用ServiceConnection的onServiceConnected方法,此方法在应用程序Activity成员变量中定义
            }
        }
		}
}

2.1.3 bindService启动Service总结

IPC调用AMS.bindService(),最终调用ActiveServices.realStartServiceLocked启动Service,在此方法中分别执行
a. scheduleCreateService(…)最终执行onCreate()
b. requestServiceBindingsLocked(…)最终执行onBind(),IPC调用AMS.publishService(…)最终执行ServiceConnection的onServiceConnected方法

3. Service总结

3.1 StartService启动Service

IPC调用AMS.startService(),最终调用ActiveServices.realStartServiceLocked启动Service,在此方法中分别执行
a. scheduleCreateService(…)最终执行onCreate()
b. sendServiceArgsLocked(…)最终执行onStartCommand()

3.2 bindService启动Service

IPC调用AMS.bindService(),最终调用ActiveServices.realStartServiceLocked启动Service,在此方法中分别执行
a. scheduleCreateService(…)最终执行onCreate()
b. requestServiceBindingsLocked(…)最终执行onBind(),IPC调用AMS.publishService(…)最终执行ServiceConnection的onServiceConnected方法

猜你喜欢

转载自blog.csdn.net/litao55555/article/details/83961729