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

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

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

目录
  • 1. 前言
  • 2. 正文
    • 2.1 ContextWrapper.startService() 方法
    • 2.2 ContextImpl.startService() 方法
    • 2.3 ContextImpl.startServiceCommon() 方法
      • 2.3.1 ActivityManagerNative.getDefault() 方法
    • 2.4 ActivityManagerProxy.startService() 方法
    • 2.5 ActivityManagerNative.onTransact() 方法
    • 2.6 ActivityManagerService.startService() 方法
    • 2.7 ActiveServices.startServiceLocked() 方法
      • 2.7.1 ActiveServices.retrieveServiceLocked() 方法
    • 2.8 ActiveServices.startServiceInnerLocked() 方法
    • 2.9 ActiveServices.bringUpServiceLocked() 方法
    • 2.10 ActiveServices.realStartServiceLocked() 方法
    • 2.11 ApplicationThreadProxy.scheduleCreateService() 方法
    • 2.12 ApplicationThreadNative.onTransact() 方法
    • 2.13 ApplicationThread.scheduleCreateService() 方法
    • 2.14 H.handleMessage() 方法
    • 2.16 ActivityThread.handleCreateService() 方法
    • 2.17 ActiveServices.sendServiceArgsLocked() 方法
    • 2.18 ApplicationThreadProxy.scheduleServiceArgs() 方法
    • 2.19 ApplicationThreadNative.onTransact()方法
    • 2.20 ApplicationThread.scheduleServiceArgs() 方法
    • 2.21 H.handleMessage() 方法
    • 2.22 ActivityThread.handleServiceArgs() 方法
  • 3. 最后
  • 参考

1. 前言

本文主要介绍在不跨进程时 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:

    

在 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,实际调用的是 ContextWrapper 的 startService() 方法。

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

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

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

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

在 ActivityThread 的 performLaunchActivity() 方法里,调用了 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 gDefault = new Singleton() {
    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 {
    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 服务端 ActivityManagerNative的 onTransact() 方法。

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 客户端 ApplicationThreadNative的 onTransact() 方法。

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. 最后

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

参考
  1. Android重学系列 Service 启动和绑定原理
  2. Service启动流程
  3. startService启动过程分析-袁辉辉

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5659795.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存