开启服务
这里只讲解主要流程和方法
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess();
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
return null;
}
}
- getDefault()
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;
}
};
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
//这里queryLocalInterface执行返回的是null,所以会执行return new ActivityManagerProxy(obj);
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
- ActivityManagerNative
开启服务其实是跨进程的,这里用到Binder机制来实现跨进程通信
class ActivityManagerProxy implements IActivityManager {
......
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType) 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);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); //mRemote是ServiceManager.getService("activity") -- ActivityManagerService;
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
......
}
- ActivityManagerService
经过上面的Binder,会执行到ActivityManagerService的startService方法来
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType) {
...
ComponentName res = startServiceLocked(caller, service,
resolvedType, callingPid, callingUid);
Binder.restoreCallingIdentity(origId);
return res;
}
}
......
}
class ActiveServices implements IActivityManager {
......
ComponentName startServiceLocked(IApplicationThread caller,Intent service, String resolvedType,int callingPid, int callingUid, int userId) {
......
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
}
- bringUpServiceLocked
private final String bringUpServiceLocked(ServiceRecord r,int intentFlags, boolean execInFg, boolean whileRestarting) {
//如果该Service已经启动。
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
}
//如果正在等待被重新启动,那么什么也不做。
if (!whileRestarting && r.restartDelay > 0) {
return null;
}
//清除等待被重新启动的状态。
if (mRestartingServices.remove(r)) {
r.resetRestartCounter();
clearRestartingIfNeededLocked(r);
}
//因为我们马上就要启动该Service,因此去掉它的延时属性。
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
//确保拥有该服务的用户是已经被启动,如果没有,说明我将不想要它运行
//个人看源码,这里处理通过绑定服务方式启动Service的处理
if (mAm.mStartedUsers.get(r.userId) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
// Service is now being launched, its package can't be stopped.
/**
(个人理解)
设置包的状态,如果是将要被启动,那么包的状态不能是停止,默认包状态是停止,系统有些广播在应用安装后在没有运行过的情况下接收不到广播,原因应该也是因为包的状态是停止,
所以,当应用运行时,不管启动四大组件的那个一个,都会设置新的包状态。设置包状态过程会写入文件保存。
*/
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.packageName + ": " + e);
}
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;//我决定flags就是配置文件里面的android:属性
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);
//如果该进程已经启动,那么调用realStartServiceLocked方法
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;
}
//如果该Service所对应的进程没有启动,那么首先启动该进程。
//比如启动的Service在单独的进程,该进程肯定没有被启动,那么系统会给该Service单独fork一个进程处理。
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;
}
}
//将该ServiceRecord加入到等待的集合当中,等到新的进程启动之后,再去启动它。
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
......
}
- realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app) throws RemoteException {
......
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
......
try {
......
//通知应用端创建Service对象。
app.thread.scheduleCreateService(r, r.serviceInfo);
......
} finally {
......
}
......
}
- bumpServiceExecutingLocked
if (r.executeNesting == 0) {
r.executeFg = fg;
ProcessStats.ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
}
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
scheduleServiceTimeoutLocked(r.app);
}
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
long now = SystemClock.uptimeMillis();
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageAtTime(msg,
proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
}
mAm.mHandler是MainHandler对象
case SERVICE_TIMEOUT_MSG: {
if (mDidDexOpt) {
mDidDexOpt = false;
Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
nmsg.obj = msg.obj;
mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
return;
}
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
void serviceTimeout(ProcessRecord proc) {
......
if (timeout != null && mAm.mLruProcesses.contains(proc)) {
Slog.w(TAG, "Timeout executing service: " + timeout);
anrMessage = "Executing service " + timeout.shortName;
} else {
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
}
}
if (anrMessage != null) {
mAm.appNotResponding(proc, null, null, false, anrMessage);
}
}
- scheduleServiceArgs
private class ApplicationThread extends ApplicationThreadNative {
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);
}
//ActivityThread
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
*/
sendServiceArgsLocked(r, execInFg, true);
......
}
- ApplicationThreadNative
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);
mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
- ActivityThread
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(); //如果后台将要进行gc回收,那么这个函数将从任务队列里面移除gc回收任务。
//得到APK相关信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//利用反射创建我们需要启动的Service对象。
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} 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);
/**
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
return new ContextImpl(null, mainThread,packageInfo, null, null, false, null, null);
}
*/
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
/**
关键函数:Service :attach
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
mThread = thread; // NOTE: unused - remove?
mClassName = className;
mToken = token;
mApplication = application;
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
mBase:ContextImpl对象,开启一个新的Activity,Service等对话创建一个ContextImpl对象,里面封装了启动Activity,Service的方法。
*/
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//执行Service的onCreate方法。
service.onCreate();
//使用token存储Service对象
mServices.put(data.token, service);
try {
/**
//Retrieve the system's default/global activity manager
//其实返回的是:ActivityManagerService对象
static public IActivityManager getDefault() {
return gDefault.get();
}
*/
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 0, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
- serviceDoneExecutingLocked
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
......
//如果沒有执行的服务,这移除消息
if (r.app.executingServices.size() == 0) {
if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
"No more executingServices of " + r.shortName);
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
} else if (r.executeFg) {
// Need to re-evaluate whether the app still needs to be in the foreground.
for (int i=r.app.executingServices.size()-1; i>=0; i--) {
if (r.app.executingServices.valueAt(i).executeFg) {
r.app.execServicesFg = true;
break;
}
}
}
......
}
- 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) {
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);
}
}
}
}
- 补充
ServiceManager
private void startBootstrapServices() {
......
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
}
ActivityManagerService
public void setSystemProcess() {
......
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
......
}
网友评论