1 常用系統服務
1.1 ConnectivityManager網絡連接的服務
常用來判斷網絡是否可用,當前網絡類型如:WIFI、4G、3G、2G等。
簡單舉例 移步工具類--NetworkUtil
/**
* 獲取可用的網絡信息
*
* @param context
* @return
*/
private static NetworkInfo getActiveNetworkInfo(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo();
} catch (Exception e) {
return null;
}
}
/**
* 判斷是否有網絡可用
*
* @param context
* @return
*/
public static boolean isNetAvailable(Context context) {
NetworkInfo networkInfo = getActiveNetworkInfo(context);
if (networkInfo != null) {
return networkInfo.isAvailable();
} else {
return false;
}
}
1.2 NotificationManager狀態欄的服務
//8.0 定位前臺服務通知
private final static int GRAY_SERVICE_ID = -1002;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//這里啟動一個后臺notification,前臺運行
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String id = "ipc";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel mChannel = new NotificationChannel(id, "ipc", importance);
mNotificationManager.createNotificationChannel(mChannel);
Notification notification = new Notification.Builder(context, id)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle("IPC")
.setContentText("IPC通知")
.setAutoCancel(false)
.build();
//mNotificationManager.notify(GRAY_SERVICE_ID, notification);
startForeground(GRAY_SERVICE_ID, notification);
} else {
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("IPC")
//設置內容
.setContentText("IPC通知")
//設置小圖標
.setSmallIcon(R.mipmap.ic_launcher)
//設置通知時間
.setWhen(System.currentTimeMillis())
//首次進入時顯示效果
.setTicker("IPC通知--------------")
//設置通知方式,聲音,震動,呼吸燈等效果,這里通知方式為聲音
.setDefaults(Notification.DEFAULT_SOUND);
//mNotificationManager.notify(GRAY_SERVICE_ID, builder.build());
startForeground(GRAY_SERVICE_ID, notification);
}
1.3 PowerManager鎖屏保持運行
//獲取電源鎖,保持該服務在屏幕熄滅時仍然獲取CPU時,保持運行
private void acquireWakeLock() {
if (null == wakeLock) {
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "PostLocationService");
if (null != wakeLock) {
wakeLock.acquire();
}
}
}
//釋放設備電源鎖
private void releaseWakeLock() {
if (null != wakeLock) {
wakeLock.release();
wakeLock = null;
}
}
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.DEVICE_POWER"/>
第一個方法是獲取鎖,第二個方法是釋放鎖,一旦獲取鎖后,及時屏幕在熄滅或鎖屏長時間后,系統后臺一直可以保持獲取到鎖的應用程序運行。獲取到PowerManager的實例pm后,再通過newWakeLock方法獲取wakelock的實例,其中第一個參數是指定要獲取哪種類型的鎖,不同的鎖對系統CPU、屏幕和鍵盤有不同的影響,第二個參數是自定義名稱。
1.4 系統相應服務
getSystemService是Android很重要的一個API,根據傳入的NAME來取得對應的Object,然后轉換成相應的服務對象。
傳入的Name | 返回的對象 | 說明 |
---|---|---|
WINDOW_SERVICE | WindowManager | 管理打開的窗口程序 |
LAYOUT_INFLATER_SERVICE | LayoutInflater | 取得xml里定義的view |
ACTIVITY_SERVICE | ActivityManager | 管理應用程序的系統狀態 |
POWER_SERVICE | PowerManger | 電源的服務 |
ALARM_SERVICE | AlarmManager | 鬧鐘的服務 |
NOTIFICATION_SERVICE | NotificationManager | 狀態欄的服務 |
KEYGUARD_SERVICE | KeyguardManager | 鍵盤鎖的服務 |
LOCATION_SERVICE | LocationManager | 位置的服務,如GPS |
SEARCH_SERVICE | SearchManager | 搜索的服務 |
VEBRATOR_SERVICE | Vebrator | 手機震動的服務 |
CONNECTIVITY_SERVICE | ConnectivityManager | 網絡連接的服務 |
WIFI_SERVICE | WifiManager | Wi-Fi服務 |
TELEPHONY_SERVICE | TeleponyManager | 電話服務 |
2 獲取服務端的ServiceManager的service--getSystemService追蹤
2.1 ContextImpl.getSystemService
[ContextImpl.java]
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
2.2 SystemServiceRegistry.getSystemService
[SystemServiceRegistry.java]
2.2.1 加載SystemServiceRegistry類
類加載機制
初始化靜態變量和靜態代碼塊
// Service registry information.
// This information is never changed once static initialization has completed.
private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
new HashMap<Class<?>, String>();
private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new HashMap<String, ServiceFetcher<?>>();
//維護注冊各種服務service,這里只選出上述幾個serviceName
static {
registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
@Override
public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
return new ConnectivityManager(context, service);
}});
registerService(Context.NOTIFICATION_SERVICE, NotificationManager.class,
new CachedServiceFetcher<NotificationManager>() {
@Override
public NotificationManager createService(ContextImpl ctx) {
final Context outerContext = ctx.getOuterContext();
return new NotificationManager(
new ContextThemeWrapper(outerContext,
Resources.selectSystemTheme(0,
outerContext.getApplicationInfo().targetSdkVersion,
com.android.internal.R.style.Theme_Dialog,
com.android.internal.R.style.Theme_Holo_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
ctx.mMainThread.getHandler());
}});
registerService(Context.POWER_SERVICE, PowerManager.class,
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
IPowerManager service = IPowerManager.Stub.asInterface(b);
return new PowerManager(ctx.getOuterContext(),
service, ctx.mMainThread.getHandler());
}});
}
private static <T> void registerService(String serviceName, Class<T> serviceClass,
ServiceFetcher<T> serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
在registerService中將ServiceFetcher添加到SYSTEM_SERVICE_FETCHERS。
2.2.2 SystemServiceRegistry.getSystemService
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
2.2.3 fetcher.getService(ctx)
根據上面初始化,每個根據serviceName取出的fetcher會根據靜態代碼塊中的fetcher去調用。
下面分別看看上述三個fetcher的get.service
fetcher都是SystemServiceRegistry的靜態內部類
static abstract class StaticApplicationContextServiceFetcher<T> implements ServiceFetcher<T> {
private T mCachedInstance;
@Override
public final T getService(ContextImpl ctx) {
synchronized (StaticApplicationContextServiceFetcher.this) {
if (mCachedInstance == null) {
Context appContext = ctx.getApplicationContext();
// If the application context is null, we're either in the system process or
// it's the application context very early in app initialization. In both these
// cases, the passed-in ContextImpl will not be freed, so it's safe to pass it
// to the service. http://b/27532714 .
try {
mCachedInstance = createService(appContext != null ? appContext : ctx);
} catch (ServiceNotFoundException e) {
onServiceNotFound(e);
}
}
return mCachedInstance;
}
}
public abstract T createService(Context applicationContext) throws ServiceNotFoundException;
}
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {
private final int mCacheIndex;
public CachedServiceFetcher() {
mCacheIndex = sServiceCacheSize++;
}
@Override
@SuppressWarnings("unchecked")
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
// Fetch or create the service.
Object service = cache[mCacheIndex];
if (service == null) {
try {
service = createService(ctx);
cache[mCacheIndex] = service;
} catch (ServiceNotFoundException e) {
onServiceNotFound(e);
}
}
return (T)service;
}
}
public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
}
- 通過上面可以看出在getService中最初都是調用createService,而createService是在靜態代碼塊中重寫的。
2.2.4 POWER_SERVICE的createService
@Override
public PowerManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
IPowerManager service = IPowerManager.Stub.asInterface(b);
return new PowerManager(ctx.getOuterContext(),
service, ctx.mMainThread.getHandler());
}});
2.2.4.1 ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
[ServiceManager.java]
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name);
if (binder != null) {
return binder;
} else {
throw new ServiceNotFoundException(name);
}
}
這里直接調用ServiceManager的getService返回binder
詳細請看Android跨進程通信IPC之18——Binder之Framework層Java篇--獲取服務
2.2.4.2 IPowerManager.Stub.asInterface(b);
一看這個調用就是aidl
詳細過程移步
Android跨進程通信IPC之19——AIDL
2.2.4.3 new PowerManager()
public PowerManager(Context context, IPowerManager service, Handler handler) {
mContext = context;
mService = service;
mHandler = handler;
}
只是做了一些賦值操作。
致此getSystemService完成
3 調用服務端的方法,以PowerManager為例使用
例子 1.3
private void acquireWakeLock() {
if (null == wakeLock) {
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "PostLocationService");
if (null != wakeLock) {
wakeLock.acquire();
}
}
}
直接看wakeLock.acquire()
其他細節不是咱么關注的重點。
3.1 wakeLock.acquire()
public void acquire() {
synchronized (mToken) {
acquireLocked();
}
}
3.2 acquireLocked()
private void acquireLocked() {
mInternalCount++;
mExternalCount++;
if (!mRefCounted || mInternalCount == 1) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
try {
mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
mHistoryTag);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
mHeld = true;
}
}
最終使用 mService.acquireWakeLock()使用服務端的服務。
參考
# android servicemanager與binder源碼分析二 ------ servicemanager服務提供者