Android Service 两种启动流程探索

android 四大组件service 有两种启动方式

第一种方式:通过StartService启动Service

通过startService启动后,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。

要创建一个这样的Service,你需要让该类继承Service类,然后重写以下方法:

  • onCreate()
    1.如果service没被创建过,调用startService()后会执行onCreate()回调;
    2.如果service已处于运行中,调用startService()不会执行onCreate()方法。
    也就是说,onCreate()只会在第一次创建service时候调用,多次执行startService()不会重复调用onCreate(),此方法适合完成一些初始化工作。

  • onStartCommand()
    如果多次执行了Context的startService()方法,那么Service的onStartCommand()方法也会相应的多次调用。onStartCommand()方法很重要,我们在该方法中根据传入的Intent参数进行实际的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。

  • onBind()
    Service中的onBind()方法是抽象方法,Service类本身就是抽象类,所以onBind()方法是必须重写的,即使我们用不到。

  • onDestory()
    在销毁的时候会执行Service该方法。

这几个方法都是回调方法,且在主线程中执行,由android操作系统在合适的时机调用。

2.三次调用startService,只触发一次onCreate回调,触发了三次onStartCommand回调, 多次startService不会重复执行onCreate回调,但每次都会执行onStartCommand回调

 

第二种方式:通过bindService启动Service

bindService启动服务特点:
1.bindService启动的服务和调用者之间是典型的client-server模式。调用者是client,service则是server端。service只有一个,但绑定到service上面的client可以有一个或很多个。这里所提到的client指的是组件,比如某个Activity。
2.client可以通过IBinder接口获取Service实例,从而实现在client端直接调用Service中的方法以实现灵活交互,这在通过startService方法启动中是无法实现的。
3.bindService启动服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。当然,client也可以明确调用Context的unbindService()方法与Service解除绑定。当没有任何client与Service绑定时,Service会自行销毁

4.bindservice 多次绑定,server 不响应。不能多次解绑 多次解绑会报错.

5.第一次开启服务 会执行服务的onCreate方法 和 onBind()方法

 

首先来看下正常的启动service

    Intent intent = new Intent(this, TestService.class);
    startService(intent);

Service的启动过程从ContextWrapper的startService开始

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

这里的mBase 具体实现是在ContextImpl。可以看到ContextWrapper 的大部分实现都教给了这个 ContextImpl 来实现。这是一种桥接模式。那么下来我们跟进ContextImpl 来看看 startService 方法

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

调用了startServiceCommon 跟进

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
	try {
		validateServiceIntent(service);
		service.prepareToLeaveProcess(this);
		ComponentName cn = ActivityManager.getService().startService(
			mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
						getContentResolver()), requireForeground,
						getOpPackageName(), 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());
			} else if (cn.getPackageName().equals("?")) {
				throw new IllegalStateException(
						"Not allowed to start service " + service + ": " + cn.getClassName());
			}
		}
		return cn;
	} catch (RemoteException e) {
		throw e.rethrowFromSystemServer();
	}
}

可以看到这段启动代码里面有明显的一句,而且重要的一句话。

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

这里 ActivityManager.getService() 获取的是 一个AMS 的binder 对象,在上一张 Activity 的启动流程分析中有介绍到。

 /**
 * @hide
 */
public static IActivityManager getService() {
	return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
		new Singleton<IActivityManager>() {
			@Override
			protected IActivityManager create() {
				final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
				final IActivityManager am = IActivityManager.Stub.asInterface(b);
				return am;
			}
		};

其实在这里 获取的是 IActivityManager Binder对象。通过这个binder对象来吧启动工作交接到AMS 来执行。

那么我们现在需要把视线移动到AMS 中的 startService 方法。

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
		String resolvedType, boolean requireForeground, String callingPackage, int userId)
		throws TransactionTooLargeException {
                ......
		try {
			res = mServices.startServiceLocked(caller, service,
					resolvedType, callingPid, callingUid,
					requireForeground, callingPackage, userId);
		} finally {
			Binder.restoreCallingIdentity(origId);
		}
		
		return res;
	}
}

在这段代码中,我们会调用mServices的startServiceLocked方法来启动,mServices对象的是ActiveServices,ActiveServices是一个辅助AMS进行Service管理的类,包含Service的启动,停止,绑定,等,在ActiveServices的startServiceLocked中,他在结尾会调用startServiceInnerLocked,startServiceInnerLocked的实现如下:

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() + mAm.mConstants.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.rescheduleDelayedStartsLocked();
		}
	} else if (callerFg || r.fgRequired) {
		smap.ensureNotStartingBackgroundLocked(r);
	}

	return r.name;
}

在上述代码中,ServiceRecord描述的是一个Service记录,ServiceRecord一直贯穿着整个Service的启动过程,startServiceInnerLocked方法并完成具体的启动工作,而是把后续的工作交给了bringUpServiceLocked方法来处理,而在bringUpServiceLocked中又调用了一个realStartServiceLocked方法,从名字含义,我们可以知道这是真正的启动一个Service:

private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
	if (app.thread == null) {
		throw new RemoteException();
	}
	if (DEBUG_MU)
		Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
				+ ", ProcessRecord.uid = " + app.uid);
	r.app = app;
	r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

	final boolean newService = app.services.add(r);
	bumpServiceExecutingLocked(r, execInFg, "create");
	mAm.updateLruProcessLocked(app, false, null);
	updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
	mAm.updateOomAdjLocked();

	boolean created = false;
	try {
		if (LOG_SERVICE_START_STOP) {
			String nameTerm;
			int lastPeriod = r.shortName.lastIndexOf('.');
			nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
			EventLogTags.writeAmCreateService(
					r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
		}
		synchronized (r.stats.getBatteryStats()) {
			r.stats.startLaunchedLocked();
		}
		mAm.notifyPackageUse(r.serviceInfo.packageName,
							 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
		app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
		app.thread.scheduleCreateService(r, r.serviceInfo,
				mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
				app.repProcState);
		r.postNotification();
		created = true;
	} catch (DeadObjectException e) {
		Slog.w(TAG, "Application dead when creating service " + r);
		mAm.appDiedLocked(app);
		throw e;
	} finally {
		if (!created) {
			// Keep the executeNesting count accurate.
			final boolean inDestroying = mDestroyingServices.contains(r);
			serviceDoneExecutingLocked(r, inDestroying, inDestroying);

			// Cleanup.
			if (newService) {
				app.services.remove(r);
				r.app = null;
			}

			// Retry.
			if (!inDestroying) {
				scheduleServiceRestartLocked(r, false);
			}
		}
	}

	if (r.whitelistManager) {
		app.whitelistManager = true;
	}

	requestServiceBindingsLocked(r, execInFg);

	updateServiceClientActivitiesLocked(app, null, true);

	// If the service is in the started state, and there are no
	// pending arguments, then fake up one so its onStartCommand() will
	// be called.
	if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
		r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
				null, null, 0));
	}

	sendServiceArgsLocked(r, execInFg, true);

	if (r.delayed) {
		if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
		getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
		r.delayed = false;
	}

	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_SERVICE,
					"Applying delayed stop (from start): " + r);
			stopServiceLocked(r);
		}
	}
}

这个方法的内容主要是 需要看下 

app.thread.scheduleCreateService(r, r.serviceInfo,
        mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
        app.repProcState);

app.thread对象是IApplicationThread类型,他实际上是一个Binder,它的具体实现是在 AcitvityThread 中,

private class ApplicationThread extends IApplicationThread.Stub {
 ...
    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);
        }
 ...
    public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;

                sendMessage(H.SERVICE_ARGS, s);
            }
    }
}

那么我们只需要把目光转回到Client 这里 对Service 的处理。

在最后发送了H.CREATE_SERVICE 的消息。

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;
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 = packageInfo.getAppFactory()
				.instantiateService(cl, data.info.name, data.intent);
	} 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,
				ActivityManager.getService());
		service.onCreate();
		mServices.put(data.token, service);
		try {
			ActivityManager.getService().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 启动的方法中

 

  1. 通过类加载器拿到service。
  2. 然后在对 service 和 context 进行attach。
  3. 然后执行了 service 的 onCreate 方法。
  4. 最后调用Service的onCreate并且将Service独享存储到ActivityThread中的一个列表
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();

...

mServices.put(data.token, service);

如果启动了多个service 都是通过 这种形式进行保存。

由于Service的onCreate方法被执行,这也意味着服务被启动了,紧接着会调用onstartCommon方法,这是通过handleServiceArgs方法去调用的

在ActiviveService 中调用 执行完上述之后, sendServiceArgsLocked(r, execInFg, true) 这局代码紧接着进场,

r.app.thread.scheduleServiceArgs(r, slice);

同理发送到 调用IApplication 来调用。 会调用onstartCommon方法,这是通过handleServiceArgs方法去调用的。

到这里,Service就算是启动了,但是这只是一种启动情况,我们不要忘记了,服务还可以被绑定的。

 

第二种方式:通过bindService 启动Service

使用bindService启动service 的方式也是从contextWapper 开始的。

@Override
public boolean bindService(Intent service, ServiceConnection conn,
		int flags) {
	return mBase.bindService(service, conn, flags);
}

整个过程和service通过startService的启动方式比较类似.这里的mBase 的具体实现是ContextImpl ,通过 ContextImpl 的具体是实现我们可以找到 bindService 方法最终会调用如下方法:

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
		handler, UserHandle user) {
	// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
	IServiceConnection sd;
	if (conn == null) {
		throw new IllegalArgumentException("connection is null");
	}
	if (mPackageInfo != null) {
		sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
	} else {
		throw new RuntimeException("Not supported in system context");
	}
	validateServiceIntent(service);
	try {
		IBinder token = getActivityToken();
		if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
				&& mPackageInfo.getApplicationInfo().targetSdkVersion
				< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
			flags |= BIND_WAIVE_PRIORITY;
		}
		service.prepareToLeaveProcess(this);
		int res = ActivityManager.getService().bindService(
			mMainThread.getApplicationThread(), getActivityToken(), service,
			service.resolveTypeIfNeeded(getContentResolver()),
			sd, flags, getOpPackageName(), user.getIdentifier());
		if (res < 0) {
			throw new SecurityException(
					"Not allowed to bind to service " + service);
		}
		return res != 0;
	} catch (RemoteException e) {
		throw e.rethrowFromSystemServer();
	}
}

这个方法主要完成两件事情:

1、通过 

sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);

将客户端的ServiceConnection 对象转化为 ServiceDispatcher.InnerConnection 对象,之所以不能直接使用ServiceConnection  是 因为服务端的绑定有可能是跨进程的,因此ServiceConnection 对象必须借助于Binder 才能让远程服务端回调自己的方法,而ServiceDispatcher.InnerConnection 刚好又充当了这一个角色,ServiceDispatcher 是什么作用呢?起始它起着连接ServiceConnection 和 InnerConnection 的桥梁作用。这个过程由LoadApk 的 getServiceDispatcher方法来完成。它的实现如下:

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
	synchronized (mServices) {
		LoadedApk.ServiceDispatcher sd = null;
		ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
		if (map != null) {
			if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
			sd = map.get(c);
		}
		if (sd == null) {
			sd = new ServiceDispatcher(c, context, handler, flags);
			if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
			if (map == null) {
				map = new ArrayMap<>();
				mServices.put(context, map);
			}
			map.put(c, sd);
		} else {
			sd.validate(context, handler);
		}
		return sd.getIServiceConnection();
	}
}
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
	= new ArrayMap<>();

通过 mService 方法内部维护了一个ArrayMap, 这个 map 保存的就是当前应用的ServiceConnection 和 ServiceDispatcher 之间的关系。

这个ServiceDispatcher 内部有一个内部类InnerConnection ,当Service和服务端连接后会通过InnerConnection 最终调用onServiceConnected方法,回调客户端,这个过程有可能是跨进程的,当serviceConnection 建立好以后,getServiceDispatcher 会返回其保存的 InnerConnection对象。

这个对象会通过参数传递到 binderService 的过程中。接着bindServiceCommon 方法会通过AMS 来完成service 的具体绑定过程。对应于AMS 的bindService 方法:

public int bindService(IApplicationThread caller, IBinder token, Intent service,
		String resolvedType, IServiceConnection connection, int flags, String callingPackage,
		int userId) throws TransactionTooLargeException {
	enforceNotIsolatedCaller("bindService");

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

	synchronized(this) {
		return mServices.bindServiceLocked(caller, token, service,
				resolvedType, connection, flags, callingPackage, userId);
	}
}

这里通过方法的逐层调用 bindServiceLocked---->bringUpServiceLocked---->realStartServiceLocked( 方法内通过 app.thread.scheduleCreateService 来创建service)----> requestServiceBindingsLocked --->requestServiceBindingLocked---> r.app.thread.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;

	if (DEBUG_SERVICE)
		Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
				+ Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
	sendMessage(H.BIND_SERVICE, s);
}

通过 sendMessage 发送消息,接收到处理消息

private void handleBindService(BindServiceData data) {
	Service s = mServices.get(data.token);
	if (DEBUG_SERVICE)
		Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
	if (s != null) {
		try {
			data.intent.setExtrasClassLoader(s.getClassLoader());
			data.intent.prepareToEnterProcess();
			try {
				if (!data.rebind) {
					IBinder binder = s.onBind(data.intent);
					ActivityManager.getService().publishService(
							data.token, data.intent, binder);
				} else {
					s.onRebind(data.intent);
					ActivityManager.getService().serviceDoneExecuting(
							data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
				}
				ensureJitEnabled();
			} catch (RemoteException ex) {
				throw ex.rethrowFromSystemServer();
			}
		} catch (Exception e) {
			if (!mInstrumentation.onException(s, e)) {
				throw new RuntimeException(
						"Unable to bind to service " + s
						+ " with " + data.intent + ": " + e.toString(), e);
			}
		}
	}
}

这里主要的是在ActivityThread 进行了 如下操作

IBinder binder = s.onBind(data.intent);
	ActivityManager.getService().publishService(
			data.token, data.intent, binder);

通过AMS  的 publishService 的方法通知客户端,服务已经bind 成功了,那么它的实现方式 如下:

public void publishService(IBinder token, Intent intent, IBinder service) {
	// Refuse possible leaked file descriptors
	if (intent != null && intent.hasFileDescriptors() == true) {
		throw new IllegalArgumentException("File descriptors passed in Intent");
	}

	synchronized(this) {
		if (!(token instanceof ServiceRecord)) {
			throw new IllegalArgumentException("Invalid service token");
		}
		mServices.publishServiceLocked((ServiceRecord)token, intent, service);
	}
}
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        final long origId = Binder.clearCallingIdentity();
        try {
            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                    + " " + intent + ": " + service);
            if (r != null) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                IntentBindRecord b = r.bindings.get(filter);
                if (b != null && !b.received) {
                    b.binder = service;
                    b.requested = true;
                    b.received = true;
                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);
                            if (!filter.equals(c.binding.intent.intent)) {
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Not publishing to: " + c);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                                if (DEBUG_SERVICE) Slog.v(
                                        TAG_SERVICE, "Published intent: " + intent);
                                continue;
                            }
                            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                            try {
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
                                Slog.w(TAG, "Failure sending service " + r.name +
                                      " to connection " + c.conn.asBinder() +
                                      " (in " + c.binding.client.processName + ")", e);
                            }
                        }
                    }
                }

                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

具体过程:publishService--->publishServiceLocked--->c.conn.connected 

这个 c  的类型是ConnectionRecord

c.conn 类型是 ServiceDispatcher.InnerConnection

private static class InnerConnection extends IServiceConnection.Stub {
	final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

	InnerConnection(LoadedApk.ServiceDispatcher sd) {
		mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
	}

	public void connected(ComponentName name, IBinder service, boolean dead)
			throws RemoteException {
		LoadedApk.ServiceDispatcher sd = mDispatcher.get();
		if (sd != null) {
			sd.connected(name, service, dead);
		}
	}
}

最终调用connected 方法。

public void connected(ComponentName name, IBinder service, boolean dead) {
	if (mActivityThread != null) {
		mActivityThread.post(new RunConnection(name, service, 0, dead));
	} else {
		doConnected(name, service, dead);
	}
}

因为这个过程是从 ActivityThread 过来的,所以逻辑会走到 上面的 if  体里。

执行这个runConnection 

private final class RunConnection implements Runnable {
	RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
		mName = name;
		mService = service;
		mCommand = command;
		mDead = dead;
	}

	public void run() {
		if (mCommand == 0) {
			doConnected(mName, mService, mDead);
		} else if (mCommand == 1) {
			doDeath(mName, mService);
		}
	}

	final ComponentName mName;
	final IBinder mService;
	final int mCommand;
	final boolean mDead;
}

 执行run 方法

最终回调

if (service != null) {
	mConnection.onServiceConnected(name, service);
}

onServiceConnected 方法。

客户端去重写这个 onServiceConnected 实现自己的逻辑就可以啦!

最后附上service 的启动分析流程图

 

 

 

 

 

 

service 启动过程分析

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值