Service
Posted ayanwan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service相关的知识,希望对你有一定的参考价值。
相关源码目录
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
/frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
/frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/core/java/android/app/IActivityManager.java
/frameworks/base/core/java/android/app/ActivityManagerNative.java (内含ActivityManagerProxy类)
/frameworks/base/core/java/android/app/ActivityManager.java
/frameworks/base/core/java/android/app/IApplicationThread.java
/frameworks/base/core/java/android/app/ApplicationThreadNative.java (内含ApplicationThreadProxy类)
/frameworks/base/core/java/android/app/ActivityThread.java (内含ApplicationThread类)
/frameworks/base/core/java/android/app/ContextImpl.java
先看Service与AMS的UML图:
(1)ActivityManagerService是Android的Java framework的服务框架最重要的服务之一。对于Andorid的Activity、Service、Broadcast、ContentProvider四剑客的管理,包含其生命周期都是通过ActivityManagerService来完成的。
(2)ActivityThread,App的真正入口,其中有一个main()用于开启消息循环线程,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作;(3)ApplicationThread。简单的说就是应用进程需要调用ActivityManagerService提供的功能,而ActivityManagerService也需要主动调用应用进程以控制应用进程并完成指定操作。这样ActivityManagerService也需要应用进程的一个Binder代理对象,而这个代理对象就是ApplicationThreadProxy对象。
(4)ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。
我们在来看一下Service的生命周期图。
1、startService分析
启动服务的流程图:
图中涉及的首字母缩写:
AMP:ActivityManagerProxy
AMN:ActivityManagerNative
AMS:ActivityManagerService
AT:ApplicationThread
ATP:ApplicationThreadProxy
ATN:ApplicationThreadNative
startService与startActivity流程及其相似,这里就不重复了。
2、bindService分析
启动服务的流程图:
上图仅仅是一个简化的流程图,因为图中没有出现zygote,ActvityThread#main等关键流程,就是生命周期中onCreate()的回掉过程。这一部分与startService是一致的。下面先分析这一部分内容。
2.1 onCreate()会调过程
2.1.1 ActiveServices#bringUpServiceLocked
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting)
...
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 (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 (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;
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
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;
if (!mPendingServices.contains(r))
mPendingServices.add(r);
if (r.delayedStop)
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested)
if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
stopServiceLocked(r);
return null;
2.1.2 ActivityManagerService#startProcessLocked
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)
...
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);//关键
checkTime(startTime, "startProcess: returned from zygote!");
....
Process.start的第一个参数entryPoint = "android.app.ActivityThread";这就是启动ActivityThread.main的过程。
2.1.3 Process#start
public static final ProcessStartResult start(…… )
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, targetSdkVersion, zygoteArgs);
//Starts a new process via the zygote mechanism.
private static ProcessStartResult startViaZygote(…… )
synchronized(Process.class)
ArrayList<String> argsForZygote = new ArrayList<String>();
//参数设置
// --runtime-init, --setuid=, --setgid=,……
//--runtime-init这里决定上面所提到创建新的进程的启动方式
argsForZygote.add("--runtime-init");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
//……
argsForZygote.add(processClass);
for (String arg : extraArgs)
argsForZygote.add(arg);
return zygoteSendArgsAndGetResult(argsForZygote);
//Sends an argument list to the zygote process, which starts a new child
//and returns the child's pid
private static ProcessStartResult zygoteSendArgsAndGetResult
(ArrayList<String> args)
//open socket to Zygote process if not already open
openZygoteSocketIfNeeded();
//write Argument
sZygoteWriter.write(Integer.toString(args.size()));
sZygoteWriter.newLine();
sZygoteWriter.flush();
……
通过上面这一段代码,向Zygote发送创建进程的请求,设置相关的参数。其中有argsForZygote.add("--runtime-init"); 决定新创建进程的启动方式为RuntimeInit.zygoteInit方式启动:找到目标类main函数执行。
接下去的流程就是AMP进行attach操作, 再调到AS.realStartServiceLocked,进而完成Service.onCreate()回调。
2.1.4 ActiveServices#realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException
...
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
//发送delay消息
bumpServiceExecutingLocked(r, execInFg, "create");
boolean created = false;
try
...
mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//服务进入 onCreate()
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
catch (DeadObjectException e)
mAm.appDiedLocked(app); //应用死亡处理
throw e;
finally
if (!created)
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
if (newService)
app.services.remove(r);
r.app = null;
//尝试重新启动服务
if (!inDestroying)
scheduleServiceRestartLocked(r, false);
requestServiceBindingsLocked(r, execInFg); //关键,进行onBind的回调
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));
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed)
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
...
app.thread.scheduleCreateService就是ApplicationThreadProxy.scheduleCreateService,进而进入ApplicationThread服务的对应方法中,
2.1.5 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);
通过handler机制, 将H.CREATE_SERVICE消息发送给远程服务进程的主线程的handler来处理。
private void handleCreateService(CreateServiceData data)
//当应用处于后台即将进行GC,而此时被调回到活动状态,则跳过本次gc。
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//通过反射创建目标服务对象
Service service = (Service) cl.loadClass(data.info.name).newInstance();
...
try
//创建ContextImpl对象
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//创建Application对象
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//调用服务onCreate()方法
service.onCreate();
mServices.put(data.token, service);
//调用服务创建完成
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
catch (Exception e)
...
还记得2.1.4中的 requestServiceBindingsLocked(r, execInFg)方法么,该方法进行了onBind的回调。
2.2.1 ActiveServices#requestServiceBindingsLocked
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 (r.app == null || r.app.thread == null)
return false;
if ((!i.requested || rebind) && i.apps.size() > 0)
try
//发送bind开始的消息
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//服务进入 onBind()
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)
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
throw e;
catch (RemoteException e)
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
return false;
return true;
2.2.2 ATP#scheduleBindService
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
int processState) throws RemoteException
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
data.writeInt(rebind ? 1 : 0);
data.writeInt(processState);
mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
ATN#onTransact
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException
switch (code)
case SCHEDULE_BIND_SERVICE_TRANSACTION:
data.enforceInterface(IApplicationThread.descriptor);
IBinder token = data.readStrongBinder();
Intent intent = Intent.CREATOR.createFromParcel(data);
boolean rebind = data.readInt() != 0;
int processState = data.readInt();
//【见流程13】
scheduleBindService(token, intent, rebind, processState);
return true;
...
AT#scheduleBindService
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);
最终,通过handler机制, 将H.BIND_SERVICE消息发送给远程服务进程的主线程的handler来处理
2.2.3 AT#handleBindService
private void handleBindService(BindServiceData data)
Service s = mServices.get(data.token);
if (s != null)
try
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
if (!data.rebind)
// 执行Service.onBind()回调方法
IBinder binder = s.onBind(data.intent);
//将onBind返回值传递回去
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
else
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
ensureJitEnabled();
catch (Exception e)
...
2.3 bindService的调用关系如下:(省略了onCreate回调的流程)
CW.bindService
CI.bindService
CI.bindServiceCommon
AMP.bindService
AMS.bindService
AS.bindServiceLocked
AS.retrieveServiceLocked
SR.retrieveAppBindingLocked
AS.bringUpServiceLocked
AS.realStartServiceLocked
ATP.scheduleCreateService
AT.scheduleCreateService
AT.handleCreateService
Service.onCreate()
AMP.serviceDoneExecuting
AMS.serviceDoneExecuting
requestServiceBindingsLocked
requestServiceBindingLocked
ATP.scheduleBindService
AT.scheduleBindService
AT.handleBindService
Service.onBind()
AMP.publishService
AMS.publishService
AS.publishServiceLocked
IServiceConnection.Stub.Proxy.connected
InnerConnection.connected
ServiceDispatcher.connected
RunConnection.run
ServiceDispatcher.doConnected
ServiceConnection.onServiceConnected
AMP.serviceDoneExecuting
AMS.serviceDoneExecuting
【 如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作! 】
以上是关于Service的主要内容,如果未能解决你的问题,请参考以下文章