posts - 101,  comments - 29,  trackbacks - 0

                  Android應(yīng)用程序組件Service與Activity一樣,既可以在新的進(jìn)程中啟動,也可以在應(yīng)用程序進(jìn)程內(nèi)部啟動;前面我們已經(jīng)分析了在新的進(jìn)程中啟動Service的過程,本文將要介紹在應(yīng)用程序內(nèi)部綁定Service的過程,這是一種在應(yīng)用程序進(jìn)程內(nèi)部啟動Service的方法。

                  在前面一篇文章Android進(jìn)程間通信(IPC)機(jī)制Binder簡要介紹和學(xué)習(xí)計劃中,我們就曾經(jīng)提到,在Android系統(tǒng)中,每一個應(yīng)用程序都是由一些Activity和Service組成的,一般Service運行在獨立的進(jìn)程中,而Activity有可能運行在同一個進(jìn)程中,也有可能運行在不同的進(jìn)程中;在接下來的文章中,Android系統(tǒng)在新進(jìn)程中啟動自定義服務(wù)過程(startService)的原理分析一文介紹了在新的進(jìn)程中啟動Service的過程,Android應(yīng)用程序啟動過程源代碼分析一文介紹了在新的進(jìn)程中啟動Activity的過程,而Android應(yīng)用程序內(nèi)部啟動Activity過程(startActivity)的源代碼分析一文則介紹了在應(yīng)用程序進(jìn)程內(nèi)部啟動Activity的過程;本文接過最后一棒,繼續(xù)介紹在應(yīng)用程序進(jìn)程內(nèi)部啟動Service的過程,這種過程又可以稱在應(yīng)用程序進(jìn)程內(nèi)部綁定服務(wù)(bindService)的過程,這樣,讀者應(yīng)該就可以對Android應(yīng)用程序啟動Activity和Service有一個充分的認(rèn)識了。

                  這里仍然是按照老規(guī)矩,通過具體的例子來分析Android應(yīng)用程序綁定Service的過程,而所使用的例子便是前面我們在介紹Android系統(tǒng)廣播機(jī)制的一篇文章Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡要介紹和學(xué)習(xí)計劃中所開發(fā)的應(yīng)用程序Broadcast了。

                  我們先簡單回顧一下這個應(yīng)用程序?qū)嵗壎⊿ervice的過程。在這個應(yīng)用程序的MainActivity的onCreate函數(shù)中,會調(diào)用bindService來綁定一個計數(shù)器服務(wù)CounterService,這里綁定的意思其實就是在MainActivity內(nèi)部獲得CounterService的接口,所以,這個過程的第一步就是要把CounterService啟動起來。當(dāng)CounterService的onCreate函數(shù)被調(diào)用起來了,就說明CounterService已經(jīng)啟動起來了,接下來系統(tǒng)還要調(diào)用CounterService的onBind函數(shù),跟CounterService要一個Binder對象,這個Binder對象是在CounterService內(nèi)部自定義的CounterBinder類的一個實例,它繼承于Binder類,里面實現(xiàn)一個getService函數(shù),用來返回外部的CounterService接口。系統(tǒng)得到這個Binder對象之后,就會調(diào)用MainActivity在bindService函數(shù)里面?zhèn)鬟^來的ServiceConnection實例的onServiceConnected函數(shù),并把這個Binder對象以參數(shù)的形式傳到onServiceConnected函數(shù)里面,于是,MainActivity就可以調(diào)用這個Binder對象的getService函數(shù)來獲得CounterService的接口了。

                  這個過程比較復(fù)雜,但總體來說,思路還是比較清晰的,整個調(diào)用過程為MainActivity.bindService->CounterService.onCreate->CounterService.onBind->MainActivity.ServiceConnection.onServiceConnection->CounterService.CounterBinder.getService。下面,我們就先用一個序列圖來總體描述這個服務(wù)綁定的過程,然后就具體分析每一個步驟。


          點擊查看大圖

                  Step 1. ContextWrapper.bindService

                  這個函數(shù)定義在frameworks/base/core/java/android/content/ContextWrapper.java文件中:

          public class ContextWrapper extends Context {
          	Context mBase;
          	......
          
          	@Override
          	public boolean bindService(Intent service, ServiceConnection conn,
          			int flags) {
          		return mBase.bindService(service, conn, flags);
          	}
          
          	......
          }
                  這里的mBase是一個ContextImpl實例變量,于是就調(diào)用ContextImpl的bindService函數(shù)來進(jìn)一步處理。

           

                  Step 2. ContextImpl.bindService

                  這個函數(shù)定義在frameworks/base/core/java/android/app/ContextImpl.java文件中:

          class ContextImpl extends Context {
          	......
          
          	@Override
          	public boolean bindService(Intent service, ServiceConnection conn,
          			int flags) {
          		IServiceConnection sd;
          		if (mPackageInfo != null) {
          			sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
          				mMainThread.getHandler(), flags);
          		} else {
          			......
          		}
          		try {
          			int res = ActivityManagerNative.getDefault().bindService(
          				mMainThread.getApplicationThread(), getActivityToken(),
          				service, service.resolveTypeIfNeeded(getContentResolver()),
          				sd, flags);
          			......
          			return res != 0;
          		} catch (RemoteException e) {
          			return false;
          		}
          	}
          
          	......
          
          }
                  這里的mMainThread是一個ActivityThread實例,通過它的getHandler函數(shù)可以獲得一個Handler對象,有了這個Handler對象后,就可以把消息分發(fā)到ActivityThread所在的線程消息隊列中去了,后面我們將會看到這個用法,現(xiàn)在我們暫時不關(guān)注,只要知道這里從ActivityThread處獲得了一個Handler并且保存在下面要介紹的ServiceDispatcher中去就可以了。

           

                  我們先看一下ActivityThread.getHandler的實現(xiàn),然后再回到這里的bindService函數(shù)來。

                  Step 3. ActivityThread.getHandler

                  這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

          public final class ActivityThread {
          	......
          
          	final H mH = new H();
          
          	......
          
          	private final class H extends Handler {
          		......
          
          		public void handleMessage(Message msg) {
          			......
          		}
          
          		......
          	}
          
          	......
          
          	final Handler getHandler() {
          		return mH;
          	}
          
          	......
          }
                  這里返回的Handler是在ActivityThread類內(nèi)部從Handler類繼承下來的一個H類實例變量。

           

                  回到Step 2中的ContextImpl.bindService函數(shù)中,獲得了這個Handler對象后,就調(diào)用mPackageInfo.getServiceDispatcher函數(shù)來獲得一個IServiceConnection接口,這里的mPackageInfo的類型是LoadedApk,我們來看看它的getServiceDispatcher函數(shù)的實現(xiàn),然后再回到ContextImpl.bindService函數(shù)來。

                  Step 4. LoadedApk.getServiceDispatcher

                  這個函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:

          final class LoadedApk {
          	......
          
          	public final IServiceConnection getServiceDispatcher(ServiceConnection c,
          			Context context, Handler handler, int flags) {
          		synchronized (mServices) {
          			LoadedApk.ServiceDispatcher sd = null;
          			HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
          			if (map != null) {
          				sd = map.get(c);
          			}
          			if (sd == null) {
          				sd = new ServiceDispatcher(c, context, handler, flags);
          				if (map == null) {
          					map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
          					mServices.put(context, map);
          				}
          				map.put(c, sd);
          			} else {
          				sd.validate(context, handler);
          			}
          			return sd.getIServiceConnection();
          		}
          	}
          
          	......
          
          	static final class ServiceDispatcher {
          		private final ServiceDispatcher.InnerConnection mIServiceConnection;
          		private final ServiceConnection mConnection;
          		private final Handler mActivityThread;
          		......
          
          		private static class InnerConnection extends IServiceConnection.Stub {
          			final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
          			......
          
          			InnerConnection(LoadedApk.ServiceDispatcher sd) {
          				mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
          			}
          
          			......
          		}
          
          		......
          
          		ServiceDispatcher(ServiceConnection conn,
          				Context context, Handler activityThread, int flags) {
          			mIServiceConnection = new InnerConnection(this);
          			mConnection = conn;
          			mActivityThread = activityThread;
          			......
          		}
          
          		......
          
          		IServiceConnection getIServiceConnection() {
          			return mIServiceConnection;
          		}
          
          		......
          	}
          
          	......
          }
                   在getServiceDispatcher函數(shù)中,傳進(jìn)來的參數(shù)context是一個MainActivity實例,先以它為Key值在mServices中查看一下,是不是已經(jīng)存在相應(yīng)的ServiceDispatcher實例,如果有了,就不用創(chuàng)建了,直接取出來。在我們這個情景中,需要創(chuàng)建一個新的ServiceDispatcher。在創(chuàng)建新的ServiceDispatcher實例的過程中,將上面?zhèn)飨聛鞸erviceConnection參數(shù)c和Hanlder參數(shù)保存在了ServiceDispatcher實例的內(nèi)部,并且創(chuàng)建了一個InnerConnection對象,這是一個Binder對象,一會是要傳遞給ActivityManagerService的,ActivityManagerServic后續(xù)就是要通過這個Binder對象和ServiceConnection通信的。

           

                  函數(shù)getServiceDispatcher最后就是返回了一個InnerConnection對象給ContextImpl.bindService函數(shù)?;氐紺ontextImpl.bindService函數(shù)中,它接著就要調(diào)用ActivityManagerService的遠(yuǎn)程接口來進(jìn)一步處理了。

                 Step 5. ActivityManagerService.bindService

                 這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

          class ActivityManagerProxy implements IActivityManager
          {
          	......
          
          	public int bindService(IApplicationThread caller, IBinder token,
          			Intent service, String resolvedType, IServiceConnection connection,
          			int flags) throws RemoteException {
          		Parcel data = Parcel.obtain();
          		Parcel reply = Parcel.obtain();
          		data.writeInterfaceToken(IActivityManager.descriptor);
          		data.writeStrongBinder(caller != null ? caller.asBinder() : null);
          		data.writeStrongBinder(token);
          		service.writeToParcel(data, 0);
          		data.writeString(resolvedType);
          		data.writeStrongBinder(connection.asBinder());
          		data.writeInt(flags);
          		mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
          		reply.readException();
          		int res = reply.readInt();
          		data.recycle();
          		reply.recycle();
          		return res;
          	}
          
          	......
          }
                   這個函數(shù)通過Binder驅(qū)動程序就進(jìn)入到ActivityManagerService的bindService函數(shù)去了。

           

                   Step 6. ActivityManagerService.bindService

                   這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

          public final class ActivityManagerService extends ActivityManagerNative
          		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
          	......
          
          	public int bindService(IApplicationThread caller, IBinder token,
          			Intent service, String resolvedType,
          			IServiceConnection connection, int flags) {
          		......
          
          		synchronized(this) {
          			......
          			final ProcessRecord callerApp = getRecordForAppLocked(caller);
          			......
          
          			ActivityRecord activity = null;
          			if (token != null) {
          				int aindex = mMainStack.indexOfTokenLocked(token);
          				......
          				activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
          			}
          			
          			......
          
          			ServiceLookupResult res =
          				retrieveServiceLocked(service, resolvedType,
          				Binder.getCallingPid(), Binder.getCallingUid());
          			
          			......
          
          			ServiceRecord s = res.record;
          
          			final long origId = Binder.clearCallingIdentity();
          
          			......
          
          			AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
          			ConnectionRecord c = new ConnectionRecord(b, activity,
          				connection, flags, clientLabel, clientIntent);
          
          			IBinder binder = connection.asBinder();
          			ArrayList<ConnectionRecord> clist = s.connections.get(binder);
          
          			if (clist == null) {
          				clist = new ArrayList<ConnectionRecord>();
          				s.connections.put(binder, clist);
          			}
          			clist.add(c);
          			b.connections.add(c);
          			if (activity != null) {
          				if (activity.connections == null) {
          					activity.connections = new HashSet<ConnectionRecord>();
          				}
          				activity.connections.add(c);
          			}
          			b.client.connections.add(c);
          			clist = mServiceConnections.get(binder);
          			if (clist == null) {
          				clist = new ArrayList<ConnectionRecord>();
          				mServiceConnections.put(binder, clist);
          			}
          		
          			clist.add(c);
          
          			if ((flags&Context.BIND_AUTO_CREATE) != 0) {
          				......
          				if (!bringUpServiceLocked(s, service.getFlags(), false)) {
          					return 0;
          				}
          			}
          
          			......
          		}
          
          		return 1;
          	}			
          
          	......
          }
                   函數(shù)首先根據(jù)傳進(jìn)來的參數(shù)token是MainActivity在ActivityManagerService里面的一個令牌,通過這個令牌就可以將這個代表MainActivity的ActivityRecord取回來了。

           

                  接著通過retrieveServiceLocked函數(shù),得到一個ServiceRecord,這個ServiceReocrd描述的是一個Service對象,這里就是CounterService了,這是根據(jù)傳進(jìn)來的參數(shù)service的內(nèi)容獲得的?;貞浺幌略贛ainActivity.onCreate函數(shù)綁定服務(wù)的語句:

          Intent bindIntent = new Intent(MainActivity.this, CounterService.class);
          bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
                  這里的參數(shù)service,就是上面的bindIntent了,它里面設(shè)置了CounterService類的信息(CounterService.class),因此,這里可以通過它來把CounterService的信息取出來,并且保存在ServiceRecord對象s中。

           

                  接下來,就是把傳進(jìn)來的參數(shù)connection封裝成一個ConnectionRecord對象。注意,這里的參數(shù)connection是一個Binder對象,它的類型是LoadedApk.ServiceDispatcher.InnerConnection,是在Step 4中創(chuàng)建的,后續(xù)ActivityManagerService就是要通過它來告訴MainActivity,CounterService已經(jīng)啟動起來了,因此,這里要把這個ConnectionRecord變量c保存下來,它保在在好幾個地方,都是為了后面要用時方便地取回來的,這里就不仔細(xì)去研究了,只要知道ActivityManagerService要使用它時就可以方便地把它取出來就可以了,具體后面我們再分析。

                  最后,傳進(jìn)來的參數(shù)flags的位Context.BIND_AUTO_CREATE為1(參見上面MainActivity.onCreate函數(shù)調(diào)用bindService函數(shù)時設(shè)置的參數(shù)),因此,這里會調(diào)用bringUpServiceLocked函數(shù)進(jìn)一步處理。

                  Step 7. ActivityManagerService.bringUpServiceLocked

                  這個函數(shù)定義在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;
          		ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
          
          		if (app != null && app.thread != null) {
          			try {
          				realStartServiceLocked(r, app);
          				return true;
          			} catch (RemoteException e) {
          				......
          			}
          		}
          
          		// 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) {
          				......
          		}
          
          		......
          	}
          
          	......
          }

           

                  回憶在Android應(yīng)用程序啟動過程源代碼分析一文),因此,這里取回來的app和app.thread均不為null,于是,就執(zhí)行realStartServiceLocked函數(shù)來執(zhí)行下一步操作了。

                  如果這里得到的ProcessRecord變量app為null,又是什么情況呢?在這種情況下,就會執(zhí)行后面的startProcessLocked函數(shù)來創(chuàng)建一個新的進(jìn)程,然后在這個新的進(jìn)程中啟動這個Service了,具體可以參考前面一篇文章Android系統(tǒng)在新進(jìn)程中啟動自定義服務(wù)過程(startService)的原理分析。

                  Step 8. ActivityManagerService.realStartServiceLocked

                  這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

          public final class ActivityManagerService extends ActivityManagerNative
          		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
          	......
          
          	private final void realStartServiceLocked(ServiceRecord r,
          			ProcessRecord app) throws RemoteException {
          		......
          		r.app = app;
          		......
          
          		app.services.add(r);
          		......
          
          		try {
          			......
          			app.thread.scheduleCreateService(r, r.serviceInfo);
          			......
          		} finally {
          			......
          		}
          
          		requestServiceBindingsLocked(r);
          
          		......
          	}
          
          	......
          }
                  這個函數(shù)執(zhí)行了兩個操作,一個是操作是調(diào)用app.thread.scheduleCreateService函數(shù)來在應(yīng)用程序進(jìn)程內(nèi)部啟動CounterService,這個操作會導(dǎo)致CounterService的onCreate函數(shù)被調(diào)用;另一個操作是調(diào)用requestServiceBindingsLocked函數(shù)來向CounterService要一個Binder對象,這個操作會導(dǎo)致CounterService的onBind函數(shù)被調(diào)用。

                  這里,我們先沿著app.thread.scheduleCreateService這個路徑分析下去,然后再回過頭來分析requestServiceBindingsLocked的調(diào)用過程。這里的app.thread是一個Binder對象的遠(yuǎn)程接口,類型為ApplicationThreadProxy。每一個Android應(yīng)用程序進(jìn)程里面都有一個ActivtyThread對象和一個ApplicationThread對象,其中是ApplicationThread對象是ActivityThread對象的一個成員變量,是ActivityThread與ActivityManagerService之間用來執(zhí)行進(jìn)程間通信的,具體可以參考Android應(yīng)用程序啟動過程源代碼分析一文。

                  Step 9. ApplicationThreadProxy.scheduleCreateService

                  這個函數(shù)定義在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驅(qū)動程序就進(jìn)入到ApplicationThread的scheduleCreateService函數(shù)去了。

           

                   Step 10. ApplicationThread.scheduleCreateService
                   這個函數(shù)定義在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);
          		}
          
          		......
          	}
          
          	......
          }
                   這里它執(zhí)行的操作就是調(diào)用ActivityThread的queueOrSendMessage函數(shù)把一個H.CREATE_SERVICE類型的消息放到ActivityThread的消息隊列中去。

           

                   Step 11. ActivityThread.queueOrSendMessage
                   這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

          public final class ActivityThread {
          	......
          
          	// if the thread hasn't started yet, we don't have the handler, so just
          	// save the messages until we're ready.
          	private final void queueOrSendMessage(int what, Object obj) {
          		queueOrSendMessage(what, obj, 0, 0);
          	}
          
          	private final void queueOrSendMessage(int what, Object obj, int arg1) {
          		queueOrSendMessage(what, obj, arg1, 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發(fā)送出去的,這里的mH是一個在ActivityThread內(nèi)部定義的一個類,繼承于Hanlder類,用于處理消息的。

           

                  Step 12. H.sendMessage

                  由于H類繼承于Handler類,因此,這里實際執(zhí)行的Handler.sendMessage函數(shù),這個函數(shù)定義在frameworks/base/core/java/android/os/Handler.java文件,這里我們就不看了,有興趣的讀者可以自己研究一下,調(diào)用了這個函數(shù)之后,這個消息就真正地進(jìn)入到ActivityThread的消息隊列去了,最終這個消息由H.handleMessage函數(shù)來處理,這個函數(shù)定義在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;
          			......
          			}
          		}
          	}
          
          	......
          }
                  這個消息最終由ActivityThread的handleCreateService函數(shù)來處理。

           

                  Step 13. ActivityThread.handleCreateService
                  這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

          public final class ActivityThread {
          	......
          
          	private final void handleCreateService(CreateServiceData data) {
          		......
          
          		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) {
          			......
          		}
          
          		try {
          			......
          
          			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);
          			......
          		} catch (Exception e) {
          			......
          		}
          	}
          
          	......
          }

           

                   這個函數(shù)的工作就是把CounterService類加載到內(nèi)存中來,然后調(diào)用它的onCreate函數(shù)。

                   Step 14. CounterService.onCreate

                   這個函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡要介紹和學(xué)習(xí)計劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:

          public class CounterService extends Service implements ICounterService {
          	......
          
          	@Override  
          	public void onCreate() {  
          		super.onCreate();  
          
          		Log.i(LOG_TAG, "Counter Service Created.");  
          	} 
          
          	......
          }
                  這樣,CounterService就啟動起來了。

           

                  至此,應(yīng)用程序綁定服務(wù)過程中的第一步MainActivity.bindService->CounterService.onCreate就完成了。

                  這一步完成之后,我們還要回到Step  8中去,執(zhí)行下一個操作,即調(diào)用ActivityManagerService.requestServiceBindingsLocked函數(shù),這個調(diào)用是用來執(zhí)行CounterService的onBind函數(shù)的。

                  Step 15. ActivityManagerService.requestServiceBindingsLocked

                  這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

          public final class ActivityManagerService extends ActivityManagerNative
          		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
          	......
          
          	private final void requestServiceBindingsLocked(ServiceRecord r) {
          		Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
          		while (bindings.hasNext()) {
          			IntentBindRecord i = bindings.next();
          			if (!requestServiceBindingLocked(r, i, false)) {
          				break;
          			}
          		}
          	}
          
          	private final boolean requestServiceBindingLocked(ServiceRecord r,
          			IntentBindRecord i, boolean rebind) {
          		......
          		if ((!i.requested || rebind) && i.apps.size() > 0) {
          		  try {
          			  ......
          			  r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
          			  ......
          		  } catch (RemoteException e) {
          			  ......
          		  }
          		}
          		return true;
          	}
          
          	......
          }
                  這里的參數(shù)r就是我們在前面的Step 6中創(chuàng)建的ServiceRecord了,它代表剛才已經(jīng)啟動了的CounterService。函數(shù)requestServiceBindingsLocked調(diào)用了requestServiceBindingLocked函數(shù)來處理綁定服務(wù)的操作,而函數(shù)requestServiceBindingLocked又調(diào)用了app.thread.scheduleBindService函數(shù)執(zhí)行操作,前面我們已經(jīng)介紹過app.thread,它是一個Binder對象的遠(yuǎn)程接口,類型是ApplicationThreadProxy。

           

                  Step 16. ApplicationThreadProxy.scheduleBindService

                  這個函數(shù)定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:

          class ApplicationThreadProxy implements IApplicationThread {
          	......
          	
          	public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
          			throws RemoteException {
          		Parcel data = Parcel.obtain();
          		data.writeInterfaceToken(IApplicationThread.descriptor);
          		data.writeStrongBinder(token);
          		intent.writeToParcel(data, 0);
          		data.writeInt(rebind ? 1 : 0);
          		mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
          			IBinder.FLAG_ONEWAY);
          		data.recycle();
          	}
          
          	......
          }
                   這里通過Binder驅(qū)動程序就進(jìn)入到ApplicationThread的scheduleBindService函數(shù)去了。

           

                   Step 17. ApplicationThread.scheduleBindService
                   這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

          public final class ActivityThread {
          	......
          
          	public final void scheduleBindService(IBinder token, Intent intent,
          			boolean rebind) {
          		BindServiceData s = new BindServiceData();
          		s.token = token;
          		s.intent = intent;
          		s.rebind = rebind;
          
          		queueOrSendMessage(H.BIND_SERVICE, s);
          	}
          
          	......
          }
                  這里像上面的Step 11一樣,調(diào)用ActivityThread.queueOrSendMessage函數(shù)來發(fā)送消息。
                  Step 18. ActivityThread.queueOrSendMessage

           

                  參考上面的Step 11,不過這里的消息類型是H.BIND_SERVICE。

                  Step 19. H.sendMessage

                  參考上面的Step 12,不過這里最終在H.handleMessage函數(shù)中,要處理的消息類型是H.BIND_SERVICE:

          public final class ActivityThread {
          	......
          
          	private final class H extends Handler {
          		......
          
          		public void handleMessage(Message msg) {
          			......
          			switch (msg.what) {
          			......
          			case BIND_SERVICE:
          				handleBindService((BindServiceData)msg.obj);
          				break;
          			......
          			}
          		}
          	}
          
          	......
          }
                   這里調(diào)用ActivityThread.handleBindService函數(shù)來進(jìn)一步處理。

           

                   Step 20. ActivityThread.handleBindService

                   這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:

          public final class ActivityThread {
          	......
          
          	private final void handleBindService(BindServiceData data) {
          		Service s = mServices.get(data.token);
          		if (s != null) {
          			try {
          				data.intent.setExtrasClassLoader(s.getClassLoader());
          				try {
          					if (!data.rebind) {
          						IBinder binder = s.onBind(data.intent);
          						ActivityManagerNative.getDefault().publishService(
          							data.token, data.intent, binder);
          					} else {
          						......
          					}
          					......
          				} catch (RemoteException ex) {
          				}
          			} catch (Exception e) {
          				......
          			}
          		}
          	}
          
          	......
          }
                  在前面的Step 13執(zhí)行ActivityThread.handleCreateService函數(shù)中,已經(jīng)將這個CounterService實例保存在mServices中,因此,這里首先通過data.token值將它取回來,保存在本地變量s中,接著執(zhí)行了兩個操作,一個操作是調(diào)用s.onBind,即CounterService.onBind獲得一個Binder對象,另一個操作就是把這個Binder對象傳遞給ActivityManagerService。

           

                  我們先看CounterService.onBind操作,然后再回到ActivityThread.handleBindService函數(shù)中來。

                  Step 21. CounterService.onBind

                  這個函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡要介紹和學(xué)習(xí)計劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:

          public class CounterService extends Service implements ICounterService {
          	......
          
          	private final IBinder binder = new CounterBinder();  
          
          	public class CounterBinder extends Binder {  
          		public CounterService getService() {  
          			return CounterService.this;  
          		}  
          	}  
          
          	@Override  
          	public IBinder onBind(Intent intent) {  
          		return binder;  
          	}  
          
          	......
          }
                  這里的onBind函數(shù)返回一個是CounterBinder類型的Binder對象,它里面實現(xiàn)一個成員函數(shù)getService,用于返回CounterService接口。

           

                  至此,應(yīng)用程序綁定服務(wù)過程中的第二步CounterService.onBind就完成了。

                  回到ActivityThread.handleBindService函數(shù)中,獲得了這個CounterBinder對象后,就調(diào)用ActivityManagerProxy.publishService來通知MainActivity,CounterService已經(jīng)連接好了。
                  Step 22. ActivityManagerProxy.publishService

                  這個函數(shù)定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

          class ActivityManagerProxy implements IActivityManager
          {
          	......
          
          	public void publishService(IBinder token,
          	Intent intent, IBinder service) throws RemoteException {
          		Parcel data = Parcel.obtain();
          		Parcel reply = Parcel.obtain();
          		data.writeInterfaceToken(IActivityManager.descriptor);
          		data.writeStrongBinder(token);
          		intent.writeToParcel(data, 0);
          		data.writeStrongBinder(service);
          		mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
          		reply.readException();
          		data.recycle();
          		reply.recycle();
          	}
          
          	......
          }
                   這里通過Binder驅(qū)動程序就進(jìn)入到ActivityManagerService的publishService函數(shù)中去了。

           

                   Step 23. ActivityManagerService.publishService

                   這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

          public final class ActivityManagerService extends ActivityManagerNative
          		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
          	......
          
          	public void publishService(IBinder token, Intent intent, IBinder service) {
          		......
          		synchronized(this) {
          			......
          			ServiceRecord r = (ServiceRecord)token;
          			......
          
          			......
          			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;
          					if (r.connections.size() > 0) {
          						Iterator<ArrayList<ConnectionRecord>> it
          							= r.connections.values().iterator();
          						while (it.hasNext()) {
          							ArrayList<ConnectionRecord> clist = it.next();
          							for (int i=0; i<clist.size(); i++) {
          								ConnectionRecord c = clist.get(i);
          								......
          								try {
          									c.conn.connected(r.name, service);
          								} catch (Exception e) {
          									......
          								}
          							}
          						}
          					}
          				}
          
          				......
          			}
          		}
          	}
          
          	......
          }
                  這里傳進(jìn)來的參數(shù)token是一個ServiceRecord對象,它是在上面的Step 6中創(chuàng)建的,代表CounterService這個Service。在Step 6中,我們曾經(jīng)把一個ConnectionRecord放在ServiceRecord.connections列表中:

           

              ServiceRecord s = res.record;
          
              ......
          
              ConnectionRecord c = new ConnectionRecord(b, activity,
          		connection, flags, clientLabel, clientIntent);
          
              IBinder binder = connection.asBinder();
              ArrayList<ConnectionRecord> clist = s.connections.get(binder);
          
              if (clist == null) {
          	clist = new ArrayList<ConnectionRecord>();
          	s.connections.put(binder, clist);
              }
                  因此,這里可以從r.connections中將這個ConnectionRecord取出來:

           

              Iterator<ArrayList<ConnectionRecord>> it
          	= r.connections.values().iterator();
              while (it.hasNext()) {
          	ArrayList<ConnectionRecord> clist = it.next();
          	for (int i=0; i<clist.size(); i++) {
          	        ConnectionRecord c = clist.get(i);
          		......
          		try {
          			c.conn.connected(r.name, service);
          		} catch (Exception e) {
          			......
          		}
          	}
              }
                  每一個ConnectionRecord里面都有一個成員變量conn,它的類型是IServiceConnection,是一個Binder對象的遠(yuǎn)程接口,這個Binder對象又是什么呢?這就是我們在Step 
          4中創(chuàng)建的LoadedApk.ServiceDispatcher.InnerConnection對象了。因此,這里執(zhí)行c.conn.connected函數(shù)后就會進(jìn)入到LoadedApk.ServiceDispatcher.InnerConnection.connected函數(shù)中去了。

           

                  Step 24. InnerConnection.connected

                  這個函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:

          final class LoadedApk {
          	......
          
          	static final class ServiceDispatcher {
          		......
          
          		private static class InnerConnection extends IServiceConnection.Stub {
          			......
          
          			public void connected(ComponentName name, IBinder service) throws RemoteException {
          				LoadedApk.ServiceDispatcher sd = mDispatcher.get();
          				if (sd != null) {
          					sd.connected(name, service);
          				}
          			}
          			......
          		}
          
          		......
          	}
          
          	......
          }
                   這里它將操作轉(zhuǎn)發(fā)給ServiceDispatcher.connected函數(shù)。

           

                   Step 25. ServiceDispatcher.connected

                   這個函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:

          final class LoadedApk {
          	......
          
          	static final class ServiceDispatcher {
          		......
          
          		public void connected(ComponentName name, IBinder service) {
          			if (mActivityThread != null) {
          				mActivityThread.post(new RunConnection(name, service, 0));
          			} else {
          				......
          			}
          		}
          
          		......
          	}
          
          	......
          }
                  我們在前面Step 4中說到,這里的mActivityThread是一個Handler實例,它是通過ActivityThread.getHandler函數(shù)得到的,因此,調(diào)用它的post函數(shù)后,就會把一個消息放到ActivityThread的消息隊列中去了。

           

                  Step 26. H.post

                  由于H類繼承于Handler類,因此,這里實際執(zhí)行的Handler.post函數(shù),這個函數(shù)定義在frameworks/base/core/java/android/os/Handler.java文件,這里我們就不看了,有興趣的讀者可以自己研究一下,調(diào)用了這個函數(shù)之后,這個消息就真正地進(jìn)入到ActivityThread的消息隊列去了,與sendMessage把消息放在消息隊列不一樣的地方是,post方式發(fā)送的消息不是由這個Handler的handleMessage函數(shù)來處理的,而是由post的參數(shù)Runnable的run函數(shù)來處理的。這里傳給post的參數(shù)是一個RunConnection類型的參數(shù),它繼承了Runnable類,因此,最終會調(diào)用RunConnection.run函數(shù)來處理這個消息。

                 Step 27. RunConnection.run

                 這個函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:

          final class LoadedApk {
          	......
          
          	static final class ServiceDispatcher {
          		......
          
          		private final class RunConnection implements Runnable {
          			......
          
          			public void run() {
          				if (mCommand == 0) {
          					doConnected(mName, mService);
          				} else if (mCommand == 1) {
          					......
          				}
          			}
          
          			......
          		}
          
          		......
          	}
          
          	......
          }
                  這里的mCommand值為0,于是就執(zhí)行ServiceDispatcher.doConnected函數(shù)來進(jìn)一步操作了。

           

                  Step 28. ServiceDispatcher.doConnected
                  這個函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:

          final class LoadedApk {
          	......
          
          	static final class ServiceDispatcher {
          		......
          
          		public void doConnected(ComponentName name, IBinder service) {
          			......
          
          			// If there is a new service, it is now connected.
          			if (service != null) {
          				mConnection.onServiceConnected(name, service);
          			}
          		}
          
          
          		......
          	}
          
          	......
          }
                  這里主要就是執(zhí)行成員變量mConnection的onServiceConnected函數(shù),這里的mConnection變量的類型的ServiceConnection,它是在前面的Step 4中設(shè)置好的,這個ServiceConnection實例是MainActivity類內(nèi)部創(chuàng)建的,在調(diào)用bindService函數(shù)時保存在LoadedApk.ServiceDispatcher類中,用它來換取一個IServiceConnection對象,傳給ActivityManagerService。

           

                  Step 29. ServiceConnection.onServiceConnected

                  這個函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡要介紹和學(xué)習(xí)計劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/MainActivity.java文件中:

          public class MainActivity extends Activity implements OnClickListener {  
          	......
          
          	private ServiceConnection serviceConnection = new ServiceConnection() {  
          		public void onServiceConnected(ComponentName className, IBinder service) {  
          			counterService = ((CounterService.CounterBinder)service).getService();  
          
          			Log.i(LOG_TAG, "Counter Service Connected");  
          		}  
          		......
          	};  
          	
          	......
          }
                  這里傳進(jìn)來的參數(shù)service是一個Binder對象,就是前面在Step 21中從CounterService那里得到的ConterBinder對象,因此,這里可以把它強(qiáng)制轉(zhuǎn)換為CounterBinder引用,然后調(diào)用它的getService函數(shù)。

           

                  至此,應(yīng)用程序綁定服務(wù)過程中的第三步MainActivity.ServiceConnection.onServiceConnection就完成了。

                  Step 30. CounterBinder.getService

                  這個函數(shù)定義在Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡要介紹和學(xué)習(xí)計劃中一文中所介紹的應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/CounterService.java文件中:

          public class CounterService extends Service implements ICounterService {  
          	......
          
          	public class CounterBinder extends Binder {  
          		public CounterService getService() {  
          			return CounterService.this;  
          		}  
          	}  
          
          	......
          }
                  這里就把CounterService接口返回給MainActivity了。

           

                  至此,應(yīng)用程序綁定服務(wù)過程中的第四步CounterService.CounterBinder.getService就完成了。

                  這樣,Android應(yīng)用程序綁定服務(wù)(bindService)的過程的源代碼分析就完成了,總結(jié)一下這個過程:

                  1. Step 1 -  Step 14,MainActivity調(diào)用bindService函數(shù)通知ActivityManagerService,它要啟動CounterService這個服務(wù),ActivityManagerService于是在MainActivity所在的進(jìn)程內(nèi)部把CounterService啟動起來,并且調(diào)用它的onCreate函數(shù);

                  2. Step 15 - Step 21,ActivityManagerService把CounterService啟動起來后,繼續(xù)調(diào)用CounterService的onBind函數(shù),要求CounterService返回一個Binder對象給它;

                  3. Step 22 - Step 29,ActivityManagerService從CounterService處得到這個Binder對象后,就把它傳給MainActivity,即把這個Binder對象作為參數(shù)傳遞給MainActivity內(nèi)部定義的ServiceConnection對象的onServiceConnected函數(shù);

                  4. Step 30,MainActivity內(nèi)部定義的ServiceConnection對象的onServiceConnected函數(shù)在得到這個Binder對象后,就通過它的getService成同函數(shù)獲得CounterService接口。

          作者:Luoshengyang 發(fā)表于2011-9-7 0:57:45 原文鏈接
          閱讀:6292 評論:23 查看評論
          posted on 2012-04-17 21:32 mixer-a 閱讀(1051) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 中牟县| 晴隆县| 大兴区| 高州市| 徐闻县| 彭水| 分宜县| 道孚县| 合作市| 静乐县| 鸡东县| 鄂州市| 汶上县| 安丘市| 舞钢市| 周口市| 宝山区| 肥乡县| 彩票| 保山市| 商水县| 张家口市| 航空| 济宁市| 延庆县| 涟源市| 阿拉善盟| 神木县| 光山县| 昌吉市| 孝昌县| 延长县| 长宁区| 海南省| 深水埗区| 宿迁市| 福清市| 高安市| 毕节市| 银川市| 邯郸县|