新部落格 www.chenxizhiyin.com,你沒看錯,追風之子愛上音樂了
阿新 • • 發佈:2019-01-03
package android.os; import com.android.internal.os.BinderInternal; import android.util.Log; import java.util.HashMap; import java.util.Map; public final class ServiceManager { private static final String TAG = "ServiceManager"; private static IServiceManager sServiceManager; private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>(); private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } /** * Returns a reference to a service with the given name. * * @param name the name of the service to get * @return a reference to the service, or <code>null</code> if the service doesn't exist */ public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().getService(name); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } /** * Place a new @a service called @a name into the service * manager. * * @param name the name of the new service * @param service the service object */ public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } /** * Place a new @a service called @a name into the service * manager. * * @param name the name of the new service * @param service the service object * @param allowIsolated set to true to allow isolated sandboxed processes * to access this service */ public static void addService(String name, IBinder service, boolean allowIsolated) { try { getIServiceManager().addService(name, service, allowIsolated); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } /** * Retrieve an existing service called @a name from the * service manager. Non-blocking. */ public static IBinder checkService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().checkService(name); } } catch (RemoteException e) { Log.e(TAG, "error in checkService", e); return null; } } /** * Return a list of all currently running services. */ public static String[] listServices() throws RemoteException { try { return getIServiceManager().listServices(); } catch (RemoteException e) { Log.e(TAG, "error in listServices", e); return null; } } /** * This is only intended to be called when the process is first being brought * up and bound by the activity manager. There is only one thread in the process * at that time, so no locking is done. * * @param cache the cache of service references * @hide */ public static void initServiceCache(Map<String, IBinder> cache) { if (sCache.size() != 0) { throw new IllegalStateException("setServiceCache may only be called once"); } sCache.putAll(cache); } }
從原始碼中可以看出,當需要呼叫 ServiceManager 的功能時,要通過它的靜態方法 getIServiceManager() 來獲取它的 IServiceManager(sServiceManager) 物件,實際上對系統中的 Services 操作(如 getService()、addService()、checkService())是通過這個物件來完成的。 IServiceManager 類的原始碼如下
public interface IServiceManager extends IInterface { /** * Retrieve an existing service called @a name from the * service manager. Blocks for a few seconds waiting for it to be * published if it does not already exist. */ public IBinder getService(String name) throws RemoteException; /** * Retrieve an existing service called @a name from the * service manager. Non-blocking. */ public IBinder checkService(String name) throws RemoteException; /** * Place a new @a service called @a name into the service * manager. */ public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException; /** * Return a list of all currently running services. */ public String[] listServices() throws RemoteException; /** * Assign a permission controller to the service manager. After set, this * interface is checked before any services are added. */ public void setPermissionController(IPermissionController controller) throws RemoteException; static final String descriptor = "android.os.IServiceManager"; int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1; int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2; int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3; int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4; int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5; }
下圖是 Android Framework 的整體結構圖