안 드 로 이 드 자바 층 ServiceManager
ServiceManager 는 Android 프로 세 스 간 통신 binder 체제 의 중요 한 역할 로 native 층 에서 실 행 됩 니 다.c+언어 로 실 행 됩 니 다.모든 Service 가 사용 되 기 전에 음악 을 재생 하 는 MediaService,예 를 들 어 activity 를 관리 하 는 Activity Manager Service 는 SM 에 등록 해 야 합 니 다.같은 시간 에 클 라 이언 트 가 특정한 서 비 스 를 사용 할 때서비스 관리자 에 게 이 서비스 가 등록 되 었 는 지 확인 해 야 한다.
ServiceManager 역할
1.Binder driver 와 통신 하고 순환 을 유지 하 며 커 널 binder driver 를 계속 읽 습 니 다.서비스 에 대한 작업 요청 이 있 는 지 계속 읽 어 보 는 것 입 니 다.
2.svclist 목록 을 유지 하여 service 정 보 를 저장 합 니 다.
3.클 라 이언 트 에 Service 를 제공 하 는 대리,즉 BinderProxy 입 니 다.
연장:클 라 이언 트 가 서비스 관리자 에 게 서 비 스 를 찾 고 BinderProxy 를 가 져 오 며 BinderProxy 를 통 해 서비스 단 과 의 통신 을 실현 합 니 다.
4.서비스 등록 서비스 제공
사실은 ServiceManager 는 하나의 경로 와 같다.먼저,Service 는 자신 을 ServiceManager 에 등록 하고 호출 자(클 라 이언 트)는 ServiceManager 를 통 해 서 비 스 를 조회 한다.
그것 의 실현 은 서비스manager.c。자바 의 ServiceManager.자바 는 서비스 에 불과 합 니 다.manager.c 의 패키지.여기,우 리 는 service 에 대해 토론 하지 않 습 니 다.manager.c 가 어떻게 Binder driver 와 아래로 통신 하 는 지,service 의 구체 적 인 논 리 를 등록 하고 찾 는 것 도 토론 하지 않 습 니 다.자바 차원,즉 안 드 로 이 드 프레임 워 크 차원 에서 ServceManager.자바 서 비 스 를 어떻게 사용 하 는 지 논의 하 는 것 이다.
ServiceManager.java 의 원본 코드 는 매우 간단 합 니 다.다음 과 같 습 니 다.
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap sCache = new HashMap();
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 null
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.
* @return an array of all currently running services, or null
in
* case of an exception
*/
public static String[] listServices() {
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 cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
}
1、 addService() , native
2、 getService() , native
3、 Map
getService() native Binder, Stub.asInterface() BinderProxy, BinderProxy 。 , AIDL Service , 。 native , addService() getService() native native 。 native :
Android Framework ( ) ServiceManager Native
Android Framework ( ) ServiceManager Native
App
Android SystemServer , getSystemService() , ServiceFetcher.createService() XXManager,XXManager BinderProxy, , XXManager BinderProxy 。 ServiceManager.getService() , 。
ActivityManager,ActivityManager , BinderProxy , :
@Deprecated
public List getRunningTasks(int maxNum)
throws SecurityException {
try {
return ActivityManagerNative.getDefault().getTasks(maxNum, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
Activity Manager Native.getDefault().getTasks()방법 을 호출 하여 Activity Manager Native.getDefault()를 되 돌려 주 는 것 을 볼 수 있 습 니 다.
BinderProxy,따라 들 어가 보 겠 습 니 다.
ActivityManagerNative.getDefault() /**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
getDefault()가 무엇 인지 보 세 요:private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
아니 나 다 를 까 ServiceManager 에서 가 져 온 IBinder 를 BinderProxy 로 전환 했다.
XXManager,BluetoothManager 를 다시 보 세 요.그 중 하 나 는 논리 적 인 방법 이 있 습 니 다.getConnected Sevices()는 다음 과 같 습 니 다.public List getConnectedDevices(int profile) {
if (DBG) Log.d(TAG,"getConnectedDevices");
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
throw new IllegalArgumentException("Profile not supported: " + profile);
}
List connectedDevices = new ArrayList();
try {
IBluetoothManager managerService = mAdapter.getBluetoothManager();
IBluetoothGatt iGatt = managerService.getBluetoothGatt();
if (iGatt == null) return connectedDevices;
connectedDevices = iGatt.getDevicesMatchingConnectionStates(
new int[] { BluetoothProfile.STATE_CONNECTED });
} catch (RemoteException e) {
Log.e(TAG,"",e);
}
return connectedDevices;
}
mAdapter 를 통 해 IBluetoothManager 인 터 페 이 스 를 얻 을 수 있 습 니 다.즉,BinderProxy 입 니 다.BluetoothAdapter 를 따라 갑 니 다./*package*/ IBluetoothManager getBluetoothManager() {
return mManagerService;
}
mManager Service 를 되 돌려 줍 니 다.이 변 수 는 BluetoothAdapter 를 구성 할 때 들 어 옵 니 다.BluetoothAdapter 에 BluetoothAdapter 를 만 드 는 방법 getDefaultAdapter 가 포함 되 어 있 는 것 을 발 견 했 습 니 다.다음 과 같 습 니 다.public static synchronized BluetoothAdapter getDefaultAdapter() {
if (sAdapter == null) {
IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
if (b != null) {
IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
sAdapter = new BluetoothAdapter(managerService);
} else {
Log.e(TAG, "Bluetooth binder is null");
}
}
return sAdapter;
}
이 를 통 해 알 수 있 듯 이 ServiceManager.getService()를 통 해 IBinder 를 얻 고 adInterface(b)방법 을 통 해 BinderProxy 로 전환 할 수 있 습 니 다.
물론 모든 XXManager 가 원 격 서 비 스 를 필요 로 하 는 것 은 아니다.일부 XXManager 의 업무 방법 은 ContentProvider 를 통 해 이 루어 진다.
이 를 통 해 저 희 는 XXManager 에 포 함 된 BinderProxy 는 ServiceManager.getService()에서 얻 고 asInterface()를 통 해 얻 은 것 임 을 검 증 했 습 니 다.
시스템 서버 엔 드
다음 에 저 희 는 등록 서비스 가 ServiceManager.addService()를 통 해 이 루어 졌 다 는 것 을 검증 하 겠 습 니 다.지난 글 에서 Android SystemServer 를 분석 한 결과 각 XX Manager Service 는 SystemServer.자바 의 정적 코드 블록 을 통 해 onStart()를 만 들 고 호출 하 는 방법 으로 시작 되 었 습 니 다.ServiceManager.addService()와 연락 이 없 는 것 처럼 보 입 니 다.급 하지 않 습 니 다.SystemServer.startOtherService()방법 에 다음 코드 가 존재 하 는 것 을 볼 수 있 습 니 다.telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
ServiceManager.addService()를 통 해 native 에 서 비 스 를 등록 하 는 것 을 발견 할 수 있 습 니 다.
또한 AMS 에서 핵심 Service 를 등록 하 는 코드 도 발견 할 수 있 습 니 다.ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
등록 서비스 라 고 하 는데 사실은 IBinder 를 등록 하 는 것 입 니 다.이 IBinder 는 자신의 신분 을 표시 합 니 다.우 리 는 addService()의 두 번 째 매개 변 수 는 모두 Binder 입 니 다.예 를 들 어 VibratorService:public class VibratorService extends IVibratorService.Stub
implements InputManager.InputDeviceListener {
....
예 를 들 어 TelephonyRegistry:class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static final String TAG = "TelephonyRegistry";
.....
또한 XXManager Service 의 부모 클래스 SystemService 에서 도 ServiceManager 에 등록 하 는 방법 을 제공 했다. protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.