Android四大组件Service中startService过程源代码详解

在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。 在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和Binder进程间通信机制有一定的了解。

Step 1. ActivityManagerService.startService

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
                           implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	public ComponentName startService(IApplicationThread caller, Intent service,
			String resolvedType) {		
		  // Refuse possible leaked file descriptors
		  if (service != null && service.hasFileDescriptors() == true) {
			  throw new IllegalArgumentException("File descriptors passed in Intent");
		  }
 
		  synchronized(this) {
			  final int callingPid = Binder.getCallingPid();
			  final int callingUid = Binder.getCallingUid();
			  final long origId = Binder.clearCallingIdentity();
			  ComponentName res = startServiceLocked(caller, service,
				  resolvedType, callingPid, callingUid);
			  Binder.restoreCallingIdentity(origId);
			  return res;
		  }
	}
 
	......
 
}

这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。

         Step 2. ActivityManagerService.startServiceLocked
         这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
                           implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	ComponentName startServiceLocked(IApplicationThread caller,
			Intent service, String resolvedType,
			int callingPid, int callingUid) {
		synchronized(this) {
			......
 
			ServiceLookupResult res =
				retrieveServiceLocked(service, resolvedType,
				callingPid, callingUid);
			
			......
			
			ServiceRecord r = res.record;
			
			......
 
			if (!bringUpServiceLocked(r, service.getFlags(), false)) {
				return new ComponentName("!", "Service process is bad");
			}
			return r.name;
		}
	}
 
	......
 
}

数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然后继续调用bringUpServiceLocked进一步处理。

        Step 3. ActivityManagerService.bringUpServiceLocked
        这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
							implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	private final boolean bringUpServiceLocked(ServiceRecord r,
				    int intentFlags, boolean whileRestarting) {
 
		......
 
		final String appName = r.processName;
 
		......
 
		// Not running -- get it started, and enqueue this service record
		// to be executed when the app comes up.
		if (startProcessLocked(appName, r.appInfo, true, intentFlags,
					"service", r.name, false) == null) {
 
			......
 
			return false;
		}
 
		if (!mPendingServices.contains(r)) {
			mPendingServices.add(r);
		}
 
		return true;
 
	}
 
	......
 
}

 这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

        Step 4. ActivityManagerService.startProcessLocked

        这个函数同样定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
							implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	private final void startProcessLocked(ProcessRecord app,
				String hostingType, String hostingNameStr) {
 
		......
 
		try {
 
			......
 
			int pid = Process.start("android.app.ActivityThread",
							mSimpleProcessManagement ? app.processName : null, uid, uid,
							gids, debugFlags, null);
 
			......
 
			if (pid == 0 || pid == MY_PID) {
				
				......
 
			} else if (pid > 0) {
				app.pid = pid;
				app.removed = false;
				synchronized (mPidsSelfLocked) {
					this.mPidsSelfLocked.put(pid, app);
					......
				}
			} else {
				
				......
			}
 
		} catch (RuntimeException e) {
 
			......
 
		}
 
	}
 
	......
 
}

 这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

         Step 5. Process.start

         这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的main函数。

         Step 6. ActivityThread.main
         这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	public static final void main(String[] args) {
 
		......
 
		Looper.prepareMainLooper();
	
		......
 
		ActivityThread thread = new ActivityThread();
		thread.attach(false);
 
		......
 
		Looper.loop();
 
		......
 
		thread.detach();
	
		......
	}
}

注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

        Step 7. ActivityThread.attach

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final void attach(boolean system) {
		
		......
 
		if (!system) {
 
			......
 
			IActivityManager mgr = ActivityManagerNative.getDefault();
			try {
				mgr.attachApplication(mAppThread);
			} catch (RemoteException ex) {
			}
		} else {
		
			......
 
		}
 
		......
 
	}
 
	......
 
}

从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。

         调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

         Step 8. ActivityManagerProxy.attachApplication
         这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

class ActivityManagerProxy implements IActivityManager
{
	......
 
	public void attachApplication(IApplicationThread app) throws RemoteException
	{
		Parcel data = Parcel.obtain();
		Parcel reply = Parcel.obtain();
		data.writeInterfaceToken(IActivityManager.descriptor);
		data.writeStrongBinder(app.asBinder());
		mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
		reply.readException();
		data.recycle();
		reply.recycle();
	}
 
	......
 
}

这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

        Step 9. ActivityManagerService.attachApplication

        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
							implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
	
	......
		
	public final void attachApplication(IApplicationThread thread) 
	{
		synchronized (this) {
			int callingPid = Binder.getCallingPid();
			final long origId = Binder.clearCallingIdentity();
			attachApplicationLocked(thread, callingPid);
			Binder.restoreCallingIdentity(origId);
		}
	}
	
	......
 
}

这里通过调用attachApplicationLocked函数进一步处理。

         Step 10. ActivityManagerService.attachApplicationLocked

         这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

public final class ActivityManagerService extends ActivityManagerNative
						implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
	......
 
	private final boolean attachApplicationLocked(IApplicationThread thread,
			int pid) {
		// Find the application record that is being attached...  either via
		// the pid if we are running in multiple processes, or just pull the
		// next app record if we are emulating process with anonymous threads.
		ProcessRecord app;
		if (pid != MY_PID && pid >= 0) {
			synchronized (mPidsSelfLocked) {
				app = mPidsSelfLocked.get(pid);
			}
		} else if (mStartingProcesses.size() > 0) {
			app = mStartingProcesses.remove(0);
			app.setPid(pid);
		} else {
			app = null;
		}
 
		......
 
 
		String processName = app.processName;
		
		......
 
		app.thread = thread;
 
		......
		
		boolean badApp = false;
 
		......
 
		// Find any services that should be running in this process...
		if (!badApp && mPendingServices.size() > 0) {
			ServiceRecord sr = null;
			try {
				for (int i=0; i<mPendingServices.size(); i++) {
					sr = mPendingServices.get(i);
					if (app.info.uid != sr.appInfo.uid
						|| !processName.equals(sr.processName)) {
							continue;
					}
 
					mPendingServices.remove(i);
					i--;
					realStartServiceLocked(sr, app);
					didSomething = true;
				}
			} catch (Exception e) {
 
				......
 
			}
		}
 
		......
 
		return true;
	}
 
	......
 
}

 回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量app中,并且将app.processName保存在本地变量processName中。再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。

        Step 11. ActivityManagerService.realStartServiceLocked
        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

class ActivityManagerProxy implements IActivityManager
{
	......
 
	private final void realStartServiceLocked(ServiceRecord r,
			ProcessRecord app) throws RemoteException {
		
		......
 
		r.app = app;
		
		......
 
		try {
 
			......
		
			app.thread.scheduleCreateService(r, r.serviceInfo);
			
			......
 
		} finally {
 
			......
 
		}
 
		......
 
	}
 
	......
 
}

这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操作。        

        Step 12. ApplicationThreadProxy.scheduleCreateService        

        这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

class ApplicationThreadProxy implements IApplicationThread {
	
	......
 
	public final void scheduleCreateService(IBinder token, ServiceInfo info)
				throws RemoteException {
		Parcel data = Parcel.obtain();
		data.writeInterfaceToken(IApplicationThread.descriptor);
		data.writeStrongBinder(token);
		info.writeToParcel(data, 0);
		mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
			IBinder.FLAG_ONEWAY);
		data.recycle();
	}
 
	......
 
}

这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

        Step 13. ApplicationThread.scheduleCreateService

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final class ApplicationThread extends ApplicationThreadNative {
 
		......
 
		public final void scheduleCreateService(IBinder token,
		ServiceInfo info) {
			CreateServiceData s = new CreateServiceData();
			s.token = token;
			s.info = info;
 
			queueOrSendMessage(H.CREATE_SERVICE, s);
		}
 
		......
 
	}
 
	......
 
}

这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。

        Step 14. ActivityThread.queueOrSendMessage

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final void queueOrSendMessage(int what, Object obj) {
		queueOrSendMessage(what, obj, 0, 0);
	}
 
	private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
		synchronized (this) {
			......
			Message msg = Message.obtain();
			msg.what = what;
			msg.obj = obj;
			msg.arg1 = arg1;
			msg.arg2 = arg2;
			mH.sendMessage(msg);
		}
	}
 
	......
 
}

这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。

        Step 15. H.sendMessage

        这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os/Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进行处理了。

        Step 16. H.handleMessage

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final class H extends Handler {
		
		......
 
		public void handleMessage(Message msg) {
 
			......
 
			switch (msg.what) {
 
				......
 
				case CREATE_SERVICE:
					handleCreateService((CreateServiceData)msg.obj);
					break;
 
				......
			}
 
			......
 
		}
 
		......
 
	}
 
	......
 
}

这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。

        Step 17. ActivityThread.handleCreateService

        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

public final class ActivityThread {
	
	......
 
	private final 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);
		Service service = null;
		try {
			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);
 
			ContextImpl context = new ContextImpl();
			context.init(packageInfo, null, this);
 
			Application app = packageInfo.makeApplication(false, mInstrumentation);
			context.setOuterContext(service);
			service.attach(context, this, data.info.name, data.token, app,
				ActivityManagerNative.getDefault());
			service.onCreate();
			mServices.put(data.token, service);
			try {
				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);
			}
		}
	}
 
	......
 
}

这里的data.info.name就是自定义的服务类。

        Step 18. ClassLoader.loadClass

        这一步实现在上面的ActivityThread.handleCreateService函数中:

java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();

Step 19. Obtain Service

        这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过ClassLoader.loadClass来导入自定义的服务类并且创建它的一个实例后,就通过强制类型转换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。

        Step 20. Service.onCreate

        这一步继续实现在上面的ActivityThread.handleCreateService函数中:

service.onCreate();

因为这里的service就是自定义Servic类的实例,因此,这里就是执行onCreate函数了:

public class Server extends Service {
	
	......
 
	@Override
	public void onCreate() {
		......
 
	}
 
	......
}

 至此,这个自定义的服务就启动起来了。

        这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:

        一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;

        二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;

        三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。

        学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。

猜你喜欢

转载自blog.csdn.net/CallmeZhe/article/details/109800440
今日推荐