Android 从进程角度看Service启动流程

本文基于Android api 26
主要从进程角度记录启动Service的流程

1 第一次跨进程调用:ContextImpl —> AMS

调用栈

Activity#startService()
ContextImpl#startService()
ContextImpl#startServiceCommon()

ContextImpl#startServiceCommon()

ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
1.1 AMS中的startService()

调用过程

AMS#startService()
ActiveServices#startServiceLocked()
ActiveServices#startServiceInnerLocked()
ActiveServices#bringUpServiceLocked()
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);
                    //1 不用生成新的Process,直接在已有的进程内运行服务
                    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;
            if (WebViewZygote.isMultiprocessEnabled()
                    && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
                hostingType = "webview_service";
            }
        }

        // Not running -- get it started, and enqueue this service record
        // to be executed when the app comes up.
        if (app == null && !permissionsReviewRequired) {
             //2 通过AMS创建新进程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, 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;
            }
        }
 }

AMS#startProcessLocked()

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {


	if (app == null) {
         checkTime(startTime, "startProcess: creating new process record");
         //1 创建ProcessRecord对象
         app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
         if (app == null) {
             Slog.w(TAG, "Failed making new process record for "
                     + processName + "/" + info.uid + " isolated=" + isolated);
             return null;
         }
     }
	 
	 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
	 //2 请求Zygote生成android.app.ActivityThread进程
	 startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, debugFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, entryPointArgs);	
     //3 以pid为键 将ProcessRecord保存到AMS中的mPidsSelfLocked中                 
	 this.mPidsSelfLocked.put(startResult.pid, app);

}
1.2 ActivityThread启动新进程
public final class ActivityThread {
     //创建ApplicationThread对象
	final ApplicationThread mAppThread = new ApplicationThread();
	final H mH = new H();


	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;
	                case BIND_SERVICE:
	                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
	                    handleBindService((BindServiceData)msg.obj);
	                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
	                    break;
	                case UNBIND_SERVICE:
	                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
	                    handleUnbindService((BindServiceData)msg.obj);
	                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
	                    break;
	            }
			}
	}
	public static void main(String[] args) {
		Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
		Looper.loop();
	
	}

	final Handler getHandler() {
        return mH;
    }
}

2 第二次跨进程调用:ActivityThread —> AMS

传递ApplicationThread对象

ActivityThread#attach()

private void attach(boolean system) {
	final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
}
2.1 AMS中的attachApplication()

AMS#attachApplication()

@Override
public final void attachApplication(IApplicationThread thread) {
     synchronized (this) {
         int callingPid = Binder.getCallingPid();
         final long origId = Binder.clearCallingIdentity();
         attachApplicationLocked(thread, callingPid);
         Binder.restoreCallingIdentity(origId);
     }
 }

AMS#attachApplicationLocked()

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
    //获取生成ActivityThread的pid值的ProcessRecord
	ProcessRecord app;
	app = mPidsSelfLocked.get(pid);
	
	//内部赋值即:app.thread = thread
	app.makeActive(thread, mProcessStats);
}

ActiveServices#attachApplicationLocked()

boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
            ServiceRecord sr = null;
            for (int i=0; i<mPendingServices.size(); i++) {
               //获取运行服务的ServiceRecord
               sr = mPendingServices.get(i);
               mPendingServices.remove(i);
               i--;
               proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
                       mAm.mProcessStats);
               realStartServiceLocked(sr, proc, sr.createdFromFg);
            
           }
}

3 第三次跨进程调用: AMS —> ApplicationThread

3.1 ActiveServices中的realStartServiceLocked

ActiveServices#realStartServiceLocked()

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);
}
3.2 ApplicationThread中的scheduleCreateService()

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);
}
3.3 调用Service的生命周期方法
private void handleCreateService(CreateServiceData data) {
	oadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
	java.lang.ClassLoader cl = packageInfo.getClassLoader();
    service = (Service) cl.loadClass(data.info.name).newInstance();
    service.onCreate();
}

4 AMS中的mPidsSelfLocked

此对象是用于保存pid和ApplicationThread对象映射关系

final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();

其key为pidValue为ProcessRecord对象,ProcessRecord对象中有ApplicationThread成员变量,所以AMS可以通过pid获取到对应的ApplicationThread对象进而控制Activity,Service等的生命周期

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值