Service的启动流程源码跟踪

前言:

当我们在一个Activity里面startService的时候,具体的执行逻辑是怎么样的?需要我们一步步根据源码阅读。

在阅读源码的时候,要关注思路,不要陷在具体的实现细节中,一步步整理代码的思路。

注:源码使用Api 25的

1.起点:Activity-> startService

在Activity中没有找到startService的方法,
查看Activity的继承关系:
Context->ContextWrapper->ContextThemeWrapper->Activity
回溯到ContextWrapper中,找到了startService()的方法:

    @Override
    public ComponentName startService(Intent service) {
        return mBase.startService(service);
    }

从ContextWrapper的命名和方法的实现上,我们可以猜到其实ContextWrapper只是一个包装
真正实现startService逻辑的是调用mBase.startService(service);
其中
Context mBase;是一个成员变量
由于Context是一个抽象类,startService是它的抽象方法,所以一定存在一个Context的子类实现了Context的抽象方法。
其实就是ContextImpl类,所以Context的抽象方法的具体实现由ContextImpl负责,其他Context的子类只需要在自己的方法里面调用
ContextImpl的即可。

2.ContextImpl ->startService(Intent service)

   @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, mUser);
    }

调用到startServiceCommon(service, mUser)

    private ComponentName startServiceCommon(Intent service, UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManagerNative.getDefault().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), getOpPackageName(), user.getIdentifier());
         //省略部分代码
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

可以看到是调用ActivityManagerNative的 ActivityManagerNative.getDefault().startService方法

3.ActivityManagerNative-> ActivityManagerNative.getDefault().startService

观察public abstract class ActivityManagerNative extends Binder implements IActivityManager的定义
可以猜测这是一个可以Binder进程IPC操作的类。
PS:如果你对Binder还很陌生推荐你先了解Binder,不需要深入到底层实现,不过Java层的基本用法需要了解
下面的博客都可以参考:
weishu的博客
Gityuan的博客
引用一个对Binder很精彩的描述:
Binder使得一个进程A有一个真身,它实现了具体的逻辑,然后其他进程获得的是Binder的影子(或者说是引用?句柄?)
然后其他进程通过Binder的影子调用就仿佛调用了A的真身的操作。
其实很多资料都告诉我们启动四大组件是IPC的操作,app进程必须通过IPC与另外的进程通信,完成四大组件的启动。
结合上面的描述,我们知道,那么app进程的是影子。我们找到它:
在ActivityManagerNative它有一个子类:

class ActivityManagerProxy implements IActivityManager{
//省略代码
  public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, 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.writeString(callingPackage);
        data.writeInt(userId);
        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);//挂起,通过Binder驱动IPC
        reply.readException();
        ComponentName res = ComponentName.readFromParcel(reply);
        data.recycle();
        reply.recycle();
        return res;
    }
//省略代码
}

这就是影子,我们在App进程调用的startService最终会到达这里,然后经过Binder驱动的一系列操作到达另外一个进程的真身

所以:ActivityManagerNative.getDefault()这里获取的应该就是ActivityManagerProxy 的实例,我们看一下它的实现:

static public IActivityManager getDefault() {
        return gDefault.get();
    }
….
** gDefault **这是一个单例对象
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//注意这里,通过**ServiceManager**获取的字符串"activity"的IBinder
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

我们可以看到最终获取的是:IActivityManager am = asInterface(b);

asInterface的代码:

   /**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        //如果是不是IPC调用执行下面的代码:
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //如果是IPC调用执行下面的代码:
        return new ActivityManagerProxy(obj);
    }

可以看到我们通过:return new ActivityManagerProxy(obj);
获取到了影子的实例。
一句话总结:ActivityManagerNative.getDefault().startService()
最终调用的是ActivityManagerProxy 的startService()方法
这里将有一个IPC的逻辑:
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
经过Binder驱动的各种操作
最终是运行到ActivityManagerNative的
onTransact方法里面的。

ActivityManagerNative->onTransact()

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();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
String callingPackage = data.readString();
int userId = data.readInt();
ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
//省略代码
}
最终调用的是:
ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);(注意这里已经不是运行在App的进程的,而是在system_Server进程中,system_Server是由Zygote进程孵化出来的。)
在ActivityManagerNative中找不到 startService(app, service, resolvedType, callingPackage, userId);这个方法,由于ActivityManagerNative是一个抽象类,自然想到方法的实现在子类中,其实就是ActivityManagerService

4.ActivityManagerService->startService()

    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        // Refuse possible leaked file descriptors
        if (service != null && service.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        if (callingPackage == null) {
            throw new IllegalArgumentException("callingPackage cannot be null");
        }

        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                "startService: " + service + " type=" + resolvedType);
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid, callingPackage, userId);
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }

调用的是mServices.startServiceLocked()方法
mService是:
final ActiveServices mServices;

5.ActiveServices ->startServiceLocked

最终调用的是

   ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
        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();
        }
        //调用这个方法:
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        if (error != null) {
            return new ComponentName("!!", error);
        }

        if (r.startRequested && addToStarting) {
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
            if (DEBUG_DELAYED_SERVICE) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
            } else if (DEBUG_DELAYED_STARTS) {
                Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
            }
            if (first) {
                smap.rescheduleDelayedStarts();
            }
        } else if (callerFg) {
            smap.ensureNotStartingBackground(r);
        }

        return r.name;
    }

startServiceInnerLocked()调用的是 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
bringUpServiceLocked(r, service.getFlags(), callerFg, false, false)方法:
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//省略代码
if (!isolated) {
//注意这里获取的需要启动Service的进程的信息
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) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
    } else {
        // If this service runs in an isolated process, then each time
        // we call startProcessLocked() we will get a new isolated
        // process, starting another process if we are currently waiting
        // for a previous process to come up.  To deal with this, we store
        // in the service any current isolated process it is running in or
        // waiting to have come up.
        app = r.isolatedProc;
    }
//省略代码

}

调用到了realStartServiceLocked()

 private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {
//省略代码
这里就回到的app的进程
    app.thread.scheduleCreateService(r,r.serviceInfo,mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),app.repProcState);
 //省略代码      
}

最终调用ActivityThread里面的ApplicationThread->scheduleCreateService()

 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);
        }

6.由ActivityThread的内部的Handler处理 sendMessage(H.CREATE_SERVICE, s);发送的消息

private class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
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;
//略
}
}

最终是通过反射创建一个新的Service,然后调用它的onCreate()方法

  private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

        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();//反射创建一个新的Service
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to instantiate service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }

        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            service.onCreate();//调用Service的onCreate()方法
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(service, e)) {
                throw new RuntimeException(
                    "Unable to create service " + data.info.name
                    + ": " + e.toString(), e);
            }
        }
    }

总结:

我们可以看到其实启动一个Service的过程也是挺复杂的,由于能力所限,仅跟踪了Java Framework这一层的代码,深入到底层的就不分析了。可以参考Gityuan大神的博客。

posted @ 2017-08-16 10:52  bylijian  阅读(355)  评论(0编辑  收藏  举报