Android筑基——Service的启动过程之同进程启动(基于api21)

1. 前言

本文主要介绍在不跨进程时 Service 的启动过程。因为跨进程启动 Service 会涉及新的进程的创建,比较复杂,不利于较快地掌握 Service 的启动过程。
Service 启动角色图:
在这里插入图片描述

Service 同进程启动时序图如下:
在这里插入图片描述

2. 正文

下面是我们分析代码开始的地方:

public class MyService extends Service {

    private static final String TAG = "MyStartService";
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: intent=" + intent + ", flags=" + flags + ", startId=" + startId);
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }
}

点击按钮启动 Service 的代码如下:

public void startService(View view) {
    Intent intent = new Intent(MainActivity.this, MyService.class);
    startService(intent);
}

在 AndroidManifest.xml 文件里面注册 Service:

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

在 Activity 里面启动 Service,并且是同进程启动的。

点击按钮后,打印日志如下:

D/MyService: onCreate: 
D/MyService: onStartCommand: intent=Intent { cmp=com.wzc.chapter_9/.MyService }, flags=0, startId=1

ok,要分析的代码有了,现在我们开始学习 Service 的启动过程吧。

2.1 ContextWrapper.startService() 方法

我们在 MainActivity 里面调用了 startService() 方法,而 Activity 继承了 ContextWrapper,实际调用的是 ContextWrapperstartService() 方法。

这里其实是装饰器设计模式的应用了,类结构图如下所示:

在这里插入图片描述

  • Intent service: new Intent(MainActivity.this, MyService.class);
@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}

这里的 mBase 实际上是一个 ContextImpl 对象。为什么这样说呢?

查看 mBase 是在 Activityattach 方法里赋值的,把传递给 attach() 方法 Context context 参数的值赋值给了 mBase 对象。

ActivityThreadperformLaunchActivity() 方法里,调用了 Activity 对象的 attach 方法,传递给它的 Context 对象是通过 createBaseContextForActivity() 方法创建的。

private Context createBaseContextForActivity(ActivityClientRecord r,
        final Activity activity) {
    ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
    appContext.setOuterContext(activity);
    Context baseContext = appContext;
    return baseContext;
}

很明显,该方法返回的是一个 ContextImpl 对象。

2.2 ContextImpl.startService() 方法

  • Intent service: new Intent(MainActivity.this, MyService.class);
public ComponentName startService(Intent service) {
    return startServiceCommon(service, mUser);
}

2.3 ContextImpl.startServiceCommon() 方法

  • Intent service: new Intent(MainActivity.this, MyService.class);
  • UserHandle user: mUser,在 ContextImpl 构造中初始化的,值为 Process.myUserHandle()。
private ComponentName startServiceCommon(Intent service, UserHandle user) {
    try {
    	// 验证 intent
        validateServiceIntent(service);
        service.prepareToLeaveProcess();
        // 调用到这里,开启服务
        ComponentName cn = ActivityManagerNative.getDefault().startService(
            mMainThread.getApplicationThread(), service,
            service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
        // 对结果进行检查
        if (cn != null) {
            if (cn.getPackageName().equals("!")) {
                throw new SecurityException(
                        "Not allowed to start service " + service
                        + " without permission " + cn.getClassName());
            } else if (cn.getPackageName().equals("!!")) {
                throw new SecurityException(
                        "Unable to start service " + service
                        + ": " + cn.getClassName());
            }
        }
        return cn;
    } catch (RemoteException e) {
        return null;
    }
}

2.3.1 ActivityManagerNative.getDefault() 方法

// ActivityManagerNative 类:
static public IActivityManager getDefault() {
    return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        IActivityManager am = asInterface(b);
        return am;
    }
};
// 因为这里客户端和服务端不处于同一个进程,所以这个方法返回的是 ActivityManagerProxy 对象。
static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    return new ActivityManagerProxy(obj);
}
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

这里采用的是局部单例技术,保证获取到的 IActivityManager 对象总是一个对象,实际上是 ActivityManagerProxy 对象。

2.4 ActivityManagerProxy.startService() 方法

  • IApplicationThread caller, ApplicationThread 对象
  • Intent service, new Intent(MainActivity.this, MyService.class)
  • String resolvedType, 通过 resolveTypeIfNeeded() 方法获得
  • int userId, 通过 UserHandle.getIdentifier() 方法获得。
// ActivityManagerProxy
public ComponentName startService(IApplicationThread caller, Intent service,
       String resolvedType, int userId) throws RemoteException
{
   Parcel data = Parcel.obtain();
   Parcel reply = Parcel.obtain();
   data.writeInterfaceToken(IActivityManager.descriptor);
   data.writeStrongBinder(caller != null ? caller.asBinder() : null);
   service.writeToParcel(data, 0);
   data.writeString(resolvedType);
   data.writeInt(userId);
   mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
   reply.readException();
   ComponentName res = ComponentName.readFromParcel(reply);
   data.recycle();
   reply.recycle();
   return res;
}

mRemote.transact() 是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ActivityManagerNativeonTransact() 方法。

2.5 ActivityManagerNative.onTransact() 方法

这个方法是运行在服务端进程里面的,服务端进程就是 system_server 进程。

@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
	switch (code) {
		...
		case START_SERVICE_TRANSACTION: {
			data.enforceInterface(IActivityManager.descriptor);
			IBinder b = data.readStrongBinder();
			// 这里获取的是 ApplicationThreadProxy 对象。
			IApplicationThread app = ApplicationThreadNative.asInterface(b);
			Intent service = Intent.CREATOR.createFromParcel(data);
			String resolvedType = data.readString();
			int userId = data.readInt();
			// 调用到这里,见[2.6]
			ComponentName cn = startService(app, service, resolvedType, userId);
			reply.writeNoException();
			ComponentName.writeToParcel(cn, reply);
			return true;
		}
	}
}

客户端进程(即 App 进程)通过 Binder 接口(即 IActivityManager 接口)向服务端进程(即 ActivityManagerService 进程)发起请求服务;
服务端进程(即 ActivityManagerService 进程)通过 IBinder 接口(即 IApplicationThread 接口)向客户端进程(即 App 进程)发起请求服务。

这样,就构成了客户端进程和服务端进程的双向通信结构了。

ActivityManagerNative 是抽象类,startService() 是它的一个抽象方法。

ActivityManagerService 继承了 ActivityManagerNative,实现了 startService() 这个抽象方法。

2.6 ActivityManagerService.startService() 方法

  • IApplicationThread caller, ApplicationThreadProxy 对象
  • Intent service, new Intent(MainActivity.this, MyService.class)
  • String resolvedType, 通过 resolveTypeIfNeeded() 方法获得
  • int userId, 通过 UserHandle.getIdentifier() 方法获得。
// ActivityManagerService
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, int userId) {
    // 当调用者是孤立进程,就抛出异常。
    enforceNotIsolatedCaller("startService");
    // Refuse possible leaked file descriptors 拒绝可能泄露的文件描述符。
    if (service != null && service.hasFileDescriptors() == true) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    
    synchronized(this) {
        final int callingPid = Binder.getCallingPid(); // 获取调用者的 pid
        final int callingUid = Binder.getCallingUid(); // 获取调用者的 uid
        final long origId = Binder.clearCallingIdentity();
        // 调用到这里,见[2.7]
        ComponentName res = mServices.startServiceLocked(caller, service,
                resolvedType, callingPid, callingUid, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}

mServices 是一个 ActiveServices 类型的对象,它是 ActivityManagerService 的成员变量,在其构造函数中进行了该变量的初始化。

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	final ActiveServices mServices;
	public ActivityManagerService(Context systemContext) {
		// 创建 ActiveServices 对象,把 ActivityManagerService 对象传递给了 ActiveServices 对象。
		mServices = new ActiveServices(this);
	}
}

2.7 ActiveServices.startServiceLocked() 方法

  • IApplicationThread caller, ApplicationThreadProxy 对象
  • Intent service, new Intent(MainActivity.this, MyService.class)
  • String resolvedType, 通过 resolveTypeIfNeeded() 方法获得
  • int callingPid, 调用者的 pid
  • int callingUid, 调用者的 uid
  • int userId 通过 UserHandle.getIdentifier() 方法获得
ComponentName startServiceLocked(IApplicationThread caller,
        Intent service, String resolvedType,
        int callingPid, int callingUid, int userId) {
    final boolean callerFg;
    if (caller != null) { // 进入此分支
		// 获取调用者进程记录对象
        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
        callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
    } else {
        callerFg = true;
    }
	// 检索服务信息,见[2.7.1]
    ServiceLookupResult res =
        retrieveServiceLocked(service, resolvedType,
                callingPid, callingUid, userId, true, callerFg);
	// 对 ServiceLookupResult 对象进行 check
    if (res == null) {
        return null;
    }
    if (res.record == null) {
        return new ComponentName("!", res.permission != null
                ? res.permission : "private to package");
    }
    ServiceRecord r = res.record;
    if (!mAm.getUserManagerLocked().exists(r.userId)) {
		// 检查是否存在启动服务的 user,不存在,则会进入此分支。
        return null;
    }
    NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
            callingUid, r.packageName, service, service.getFlags(), null, r.userId);
    
    r.lastActivity = SystemClock.uptimeMillis();
    r.startRequested = true;
    r.delayedStop = false;
    r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
            service, neededGrants));
    final ServiceMap smap = getServiceMap(r.userId);
    boolean addToStarting = false;
	// 这里 callerFg 应该是 true,callerForeground 的缩写吧。
	// r.app 的值是 null
	// mAm.mStartedUsers.get(r.userId) 根据 userId,获取是否存在 UserStartedState 对象,本次存在
	// 所以不会进入 if 分支
    if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
        ...
    } else if (DEBUG_DELAYED_STARTS) {
        ...
    }
	// 调用到这里,见[2.8]
    return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}

2.7.1 ActiveServices.retrieveServiceLocked() 方法

  • Intent service, new Intent(MainActivity.this, MyService.class)
  • String resolvedType, 通过 resolveTypeIfNeeded() 方法获得
  • int callingPid, 调用者的 pid
  • int callingUid, 调用者的 uid
  • int userId, 通过 UserHandle.getIdentifier() 方法获得
  • boolean createIfNeeded, true
  • boolean callingFromFg 应该是 true
private ServiceLookupResult retrieveServiceLocked(Intent service,
        String resolvedType, int callingPid, int callingUid, int userId,
        boolean createIfNeeded, boolean callingFromFg) {
    ServiceRecord r = null;
	// 获取 userId
    userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
            false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
	// 根据 userId,获取 ServiceMap 对象
    ServiceMap smap = getServiceMap(userId);
	// 尝试从 ServiceMap 对象里获取 ServiceRecord 对象
    final ComponentName comp = service.getComponent();
    if (comp != null) {
        r = smap.mServicesByName.get(comp);
    }
    if (r == null) {
        Intent.FilterComparison filter = new Intent.FilterComparison(service);
        r = smap.mServicesByIntent.get(filter);
    }
	// 没有获取到 ServiceRecord 对象,会进入 if 分支
    if (r == null) {
        try {
			// 从清单文件里解析出 ServiceInfo 对象
            ResolveInfo rInfo =
                AppGlobals.getPackageManager().resolveService(
                            service, resolvedType,
                            ActivityManagerService.STOCK_PM_FLAGS, userId);
            ServiceInfo sInfo =
                rInfo != null ? rInfo.serviceInfo : null;
            if (sInfo == null) {
                return null;
            }
            ComponentName name = new ComponentName(
                    sInfo.applicationInfo.packageName, sInfo.name);
            if (userId > 0) {
                if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                        sInfo.name, sInfo.flags)
                        && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                    userId = 0;
                    smap = getServiceMap(0);
                }
                sInfo = new ServiceInfo(sInfo);
                sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
            }
            r = smap.mServicesByName.get(name);
            if (r == null && createIfNeeded) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(service.cloneFilter());
                ServiceRestarter res = new ServiceRestarter();
          
				// 创建 ServiceRecord 对象。
                r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                res.setService(r);
                smap.mServicesByName.put(name, r);
                smap.mServicesByIntent.put(filter, r);
                for (int i=mPendingServices.size()-1; i>=0; i--) {
                    ServiceRecord pr = mPendingServices.get(i);
                    if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                            && pr.name.equals(name)) {
                        mPendingServices.remove(i);
                    }
                }
            }
        } catch (RemoteException ex) {
        }
    }
    if (r != null) {
		// 作权限检查
        if (mAm.checkComponentPermission(r.permission,
                callingPid, callingUid, r.appInfo.uid, r.exported)
                != PackageManager.PERMISSION_GRANTED) {
           ...
        }
		// 作 intent firewall 检查
        if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                resolvedType, r.appInfo)) {
            return null;
        }
		// 把 ServiceRecord 封装在 ServiceLookupResult 对象里面返回。
        return new ServiceLookupResult(r, null);
    }
    return null;
}

2.8 ActiveServices.startServiceInnerLocked() 方法

  • ServiceMap smap, ServiceMap 对象,根据 userId 获取到的
  • Intent service, new Intent(MainActivity.this, MyService.class)
  • ServiceRecord r,
  • boolean callerFg, true
  • boolean addToStarting false
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
        ServiceRecord r, boolean callerFg, boolean addToStarting) {
    ProcessStats.ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
    }
    r.callStart = false;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked(); // 用于耗电统计,开启运行状态
    }
	// 调用到这里,见[2.9]
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
    if (error != null) {
        return new ComponentName("!!", error);
    }
    if (r.startRequested && addToStarting) { // addToStarting 为 false,不会进入此分支
        ...
    } else if (callerFg) {
        smap.ensureNotStartingBackground(r);
    }
    return r.name;
}

2.9 ActiveServices.bringUpServiceLocked() 方法

  • ServiceRecord r, Service 记录对象
  • int intentFlags, Intent 里的 flags
  • boolean execInFg, true
  • boolean whileRestarting false
private final String bringUpServiceLocked(ServiceRecord r,
        int intentFlags, boolean execInFg, boolean whileRestarting) {
	// r.app 为 null,本次不会进入此分支
    if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
    }
	// 等待延时重启,本次不会进入此分支
    if (!whileRestarting && r.restartDelay > 0) {
        // If waiting for a restart, then do nothing.
        return null;
    }
    // 启动service前,把service从重启服务队列中移除
    if (mRestartingServices.remove(r)) {
        clearRestartingIfNeededLocked(r);
    }
    // 确保服务不再是 delayed 状态,因为现在在启动它了.
    if (r.delayed) {
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }
    // 确保服务的拥有者已经启动了,否则就停止启动服务.
    if (mAm.mStartedUsers.get(r.userId) == null) {
        bringDownServiceLocked(r);
        return msg;
    }
    // 服务在被启动,设置 package 停止状态为 false.
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(
                r.packageName, false, r.userId);
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
    }
    final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
    final String procName = r.processName;
    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);
				// 调用到这里,去真正启动服务,见[2.10]
                realStartServiceLocked(r, app, execInFg);
                return null;
            } catch (RemoteException e) {
            }
        }
    } else {
        ...
    }
    if (app == null) { // 本次目标进程存在,所以不会进入此分支
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = "Unable to launch app "
                    + r.appInfo.packageName + "/"
                    + r.appInfo.uid + " for service "
                    + r.intent.getIntent() + ": process is bad";
            Slog.w(TAG, msg);
            bringDownServiceLocked(r);
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }
    return null;
}

2.10 ActiveServices.realStartServiceLocked() 方法

  • ServiceRecord r, Service 记录对象
  • ProcessRecord app, 目标进程记录对象
  • boolean execInFg true,表示在前台执行。
private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
    if (app.thread == null) {
        throw new RemoteException();
    }
    // 把目标进程对象 app 赋值给 ServiceRecord 的 app 属性
    r.app = app;
    r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
	// 把 ServiceRecord 对象添加给 services 集合。
    app.services.add(r);
	// 发送延时消息
    bumpServiceExecutingLocked(r, execInFg, "create");
    mAm.updateLruProcessLocked(app, false, null);
    mAm.updateOomAdjLocked();
    boolean created = false;
    try {
        String nameTerm;
        int lastPeriod = r.shortName.lastIndexOf('.');
        nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
        synchronized (r.stats.getBatteryStats()) {
            r.stats.startLaunchedLocked();
        }
        mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
		// 调用到这里,交由 ApplicationThreadProxy 安排创建 Service,见[2.11]
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
        r.postNotification();
        created = true;
    } catch (DeadObjectException e) {
        mAm.appDiedLocked(app);
    } finally {
        if (!created) {
            app.services.remove(r);
            r.app = null;
            scheduleServiceRestartLocked(r, false);
            return;
        }
    }
    requestServiceBindingsLocked(r, execInFg);
    updateServiceClientActivitiesLocked(app, null, true);
    if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                null, null));
    }
	// 发送服务参数,见[2.17]
    sendServiceArgsLocked(r, execInFg, true);
}

2.11 ApplicationThreadProxy.scheduleCreateService() 方法

  • IBinder token, ServiceRecord 对象,它继承了 Binder,而 Binder 实现了 IBinder 接口。
  • ServiceInfo info, 清单文件中的 service 节点信息
  • CompatibilityInfo compatInfo,
  • int processState
class ApplicationThreadProxy implements IApplicationThread {
	public final void scheduleCreateService(IBinder token, ServiceInfo info,
        CompatibilityInfo compatInfo, int processState) throws RemoteException {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		data.writeStrongBinder(token);
		info.writeToParcel(data, 0);
		compatInfo.writeToParcel(data, 0);
		data.writeInt(processState);
		// 调用到这里,远程调用 ApplicationThreadNative 的 onTransact() 方法
		mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
				IBinder.FLAG_ONEWAY);
		data.recycle();
	}
}

mRemote.transact() 是服务端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 客户端 ApplicationThreadNativeonTransact() 方法。

2.12 ApplicationThreadNative.onTransact() 方法

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
	@Override
	public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
			throws RemoteException {
		case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
			data.enforceInterface(IApplicationThread.descriptor);
			IBinder token = data.readStrongBinder();
			ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
			CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
			int processState = data.readInt();
			// 见[2.13]
			scheduleCreateService(token, info, compatInfo, processState);
			return true;
		}
	}
}

ApplicationThreadNative 是一个抽象类,scheduleCreateService() 方法是一个抽象方法;ApplicationThread 继承了 ApplicationThreadNative 类,实现了 scheduleCreateService() 这个抽象方法。

因此,scheduleCreateService() 方法的实现是在 ApplicationThread 中。

2.13 ApplicationThread.scheduleCreateService() 方法

  • IBinder token, ServiceRecord 对象,它继承了 Binder,而 Binder 实现了 IBinder 接口。
  • ServiceInfo info, 清单文件中的 service 节点信息
  • CompatibilityInfo compatInfo,
  • int processState
private class ApplicationThread extends ApplicationThreadNative {
	public final void scheduleCreateService(IBinder token,
        ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
		updateProcessState(processState, false);
		// 把 token,info 等封装在 CreateServiceData 对象中。
		CreateServiceData s = new CreateServiceData();
		s.token = token;
		s.info = info;
		s.compatInfo = compatInfo;
		sendMessage(H.CREATE_SERVICE, s);
	}
}

2.14 H.handleMessage() 方法

public final class ActivityThread {
	final H mH = new H();
	private class H extends Handler {
		public void handleMessage(Message msg) {
			case CREATE_SERVICE:
				Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
				// 调用到这里,见[2.15]
				handleCreateService((CreateServiceData)msg.obj);
				Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
				break;
		}
	}
}

这里就从客户端进程的 Binder 线程切到了主线程。

2.16 ActivityThread.handleCreateService() 方法

  • CreateServiceData data 封装了token,info 等信息的对象
private void handleCreateService(CreateServiceData data) {
    unscheduleGcIdler();
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
		// 通过反射创建目标 Service 对象
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
    }
    try {
		// 创建 ContextImpl 对象
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
		// 创建 Application 对象或者直接返回已有的 Application 对象
        Application app = packageInfo.makeApplication(false, mInstrumentation);
		// 调用 Service 对象的 attach 方法,把 Context 对象,AMS,ProcessRecord 等和 Service 对象关联起来。
        service.attach(context, this, data.info.name, data.token, app,
                ActivityManagerNative.getDefault());
		// 回调 Service 对象的 onCreate 方法
        service.onCreate();
		// 将 service 的 token 和 对象存在 ActivityThread 的 map 中。
        mServices.put(data.token, service);
        try {
            ActivityManagerNative.getDefault().serviceDoneExecuting(
                    data.token, 0, 0, 0);
        } catch (RemoteException e) {
            // nothing to do.
        }
    } catch (Exception e) {
    }
}

2.17 ActiveServices.sendServiceArgsLocked() 方法

  • ServiceRecord r, Service 记录对象
  • boolean execInFg, true
  • boolean oomAdjusted true
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
        boolean oomAdjusted) {
    final int N = r.pendingStarts.size();
    if (N == 0) {
        return;
    }
    while (r.pendingStarts.size() > 0) {
        try {
            ServiceRecord.StartItem si = r.pendingStarts.remove(0);
           
            if (si.intent == null && N > 1) {
                continue;
            }
            si.deliveredTime = SystemClock.uptimeMillis();
            r.deliveredStarts.add(si);
            si.deliveryCount++;
            if (si.neededGrants != null) {
                mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
                        si.getUriPermissionsLocked());
            }
            bumpServiceExecutingLocked(r, execInFg, "start");
            int flags = 0;
            if (si.deliveryCount > 1) {
                flags |= Service.START_FLAG_RETRY;
            }
            if (si.doneExecutingCount > 0) {
                flags |= Service.START_FLAG_REDELIVERY;
            }
			// r.app 是 ProcessRecord 对象
			// r.app.thread 是 IApplicationThread 对象,实际上是 ApplicationThreadProxy 对象
			// 见[2.18]
            r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
        } catch (RemoteException e) {
            // Remote process gone...  we'll let the normal cleanup take
            // care of this.
            if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
            break;
        } catch (Exception e) {
            Slog.w(TAG, "Unexpected exception", e);
            break;
        }
    }
}

2.18 ApplicationThreadProxy.scheduleServiceArgs() 方法

  • IBinder token, ServiceRecord 对象
  • boolean taskRemoved,
  • int startId,
  • int flags,
  • Intent args
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
        int flags, Intent args) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    data.writeInt(taskRemoved ? 1 : 0);
    data.writeInt(startId);
    data.writeInt(flags);
    if (args != null) {
        data.writeInt(1);
        args.writeToParcel(data, 0);
    } else {
        data.writeInt(0);
    }
    // 见[2.19]
    mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}

2.19 ApplicationThreadNative.onTransact()方法

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
	@Override
	public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
			throws RemoteException {
		case SCHEDULE_SERVICE_ARGS_TRANSACTION:
		{
			data.enforceInterface(IApplicationThread.descriptor);
			IBinder token = data.readStrongBinder();
			boolean taskRemoved = data.readInt() != 0;
			int startId = data.readInt();
			int fl = data.readInt();
			Intent args;
			if (data.readInt() != 0) {
				args = Intent.CREATOR.createFromParcel(data);
			} else {
				args = null;
			}
			// 见[2.20]
			scheduleServiceArgs(token, taskRemoved, startId, fl, args);
			return true;
		}
	}
}

2.20 ApplicationThread.scheduleServiceArgs() 方法

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
    int flags ,Intent args) {
    ServiceArgsData s = new ServiceArgsData();
    s.token = token;
    s.taskRemoved = taskRemoved;
    s.startId = startId;
    s.flags = flags;
    s.args = args;
    sendMessage(H.SERVICE_ARGS, s);
}

2.21 H.handleMessage() 方法

public final class ActivityThread {
	final H mH = new H();
	private class H extends Handler {
		public void handleMessage(Message msg) {
			case SERVICE_ARGS:
				Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
				handleServiceArgs((ServiceArgsData)msg.obj);
				Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
				break;
		}
	}
}

2.22 ActivityThread.handleServiceArgs() 方法

private void handleServiceArgs(ServiceArgsData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
        try {
            if (data.args != null) {
                data.args.setExtrasClassLoader(s.getClassLoader());
                data.args.prepareToEnterProcess();
            }
            int res;
            if (!data.taskRemoved) {
				// 回调 Service 的 onStartCommand 方法。
                res = s.onStartCommand(data.args, data.flags, data.startId);
            } else {
                s.onTaskRemoved(data.args);
                res = Service.START_TASK_REMOVED_COMPLETE;
            }
            QueuedWork.waitToFinish();
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, 1, data.startId, res);
            } catch (RemoteException e) {
                // nothing to do.
            }
            ensureJitEnabled();
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to start service " + s
                        + " with " + data.args + ": " + e.toString(), e);
            }
        }
    }
}

3. 最后

Service 的同进程启动,使用自己的语言总结一下:

通过 startService 方法来启动 Service,实际调用的是 ContextImplstartService 方法,内部调用的是 startServiceCommon 方法,通过 AMPstartService 方法发起 binder 跨进程调用,进入到 system_server 进程的 AMSstartService 方法。

在 system_server 进程的 AMSstartService 方法中,会调用 ActiveServicesstartServiceLocked 方法,在这个方法里面,会先通过 retrieveServiceLocked 方法获取到 ServiceLookupResult 对象(里面封装了从清单文件中解析出来的 service 信息),接着调用 startServiceInnerLocked 方法,内部调用 bringUpServiceLocked 方法进行一系列的检查后,目标进程存在时调用 realStartServiceLocked 真正开启服务。

realStartServiceLocked 中,通过 ATPscheduleCreateService 方法发起 binder 跨进程调用,进入到应用进程的 ApplicationThreadscheduleCreateService 方法中(这个方法是运行在应用进程的binder线程中),再通过 mH 将数据切换到应用进程的主线程中,由 ActivityThreadhandleCreateService 来处理数据:通过反射创建 service 对象,回调 service 的 onCreate 方法。

如果 service 的创建没有超时的话,system_server 进程的 ActiveServices 会再调用 sendServiceArgsLocked 方法向 service 发送参数,这又是一次跨进程调用:通过 ATPscheduleServiceArgs 方法发起 binder 跨进程调用,会进入到应用进程的 ApplicationThreadscheduleServiceArgs 方法中(这个方法是运行在应用进程的binder线程中),再通过 mH 将数据切换到应用进程的主线程中,由 ActivityThreadhandleServiceArgs 方法来处理数据,会把数据回调给 service 的 onStartCommand 方法。

本文到这里就结束了,希望能够帮助到同学们。

参考

  1. Android重学系列 Service 启动和绑定原理
  2. Service启动流程
  3. startService启动过程分析-袁辉辉
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

willwaywang6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值