android api 26 ActivityManagerNative類被棄用。代理類ActivityManagerProxy已經被刪除。改用AIDL方式。
阿新 • • 發佈:2019-02-09
今天擼原始碼:startActivity()。
發現了在API 26中: ActivityManagerNative類被棄用,代理類ActivityManagerProxy已經被刪除。
本篇文章主要是記下,API26和API25的不同。
看到Instrumentation類的exeStartActivity時候,原始碼如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()//注意這一行,和參考文章不同!
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
發現參考文章使用的如圖:
怎麼兩句話不同呢?其實原來我使用的api是26,而26之前的程式碼使用的是原作者寫的。
繼續深入看兩個不同的程式碼:
26:
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);//注意這一行
return am;
}
};
25:
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
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;
}
};
發現兩個程式碼都是返回的IActivityManager。不同的是:
25中使用的是:靜態方法asInterface,該方法屬於ActivityManagerNative類。原始碼:
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
參考文章中說明了ActivityManagerNative類,還有ActivityManagerProxy類,是如何實現和AMS程序間通訊的。最終使用ActivityManagerProxy代理類實現了startActivity。具體見參考文章:Activity啟動過程詳解。
26中使用的是:
IActivityManager.Stub.asInterface(b);
而我們再看api26中的ActivityManagerNative類。原始碼已經很少:
/**
* {@hide}
* @deprecated will be removed soon. See individual methods for alternatives.//注意解釋
*/
@Deprecated
public abstract class ActivityManagerNative {
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*
* @deprecated use IActivityManager.Stub.asInterface instead.//注意解釋
*/
static public IActivityManager asInterface(IBinder obj) {
return IActivityManager.Stub.asInterface(obj);
}
/**
* Retrieve the system's default/global activity manager.
*
* @deprecated use ActivityManager.getService instead.
*/
static public IActivityManager getDefault() {
return ActivityManager.getService();
}
/**
* Convenience for checking whether the system is ready. For internal use only.
*
* @deprecated use ActivityManagerInternal.isSystemReady instead.
*/
static public boolean isSystemReady() {
return ActivityManager.isSystemReady();
}
/**
* @deprecated use ActivityManager.broadcastStickyIntent instead.
*/
static public void broadcastStickyIntent(Intent intent, String permission, int userId) {
broadcastStickyIntent(intent, permission, AppOpsManager.OP_NONE, userId);
}
/**
* Convenience for sending a sticky broadcast. For internal use only.
* If you don't care about permission, use null.
*
* @deprecated use ActivityManager.broadcastStickyIntent instead.
*/
static public void broadcastStickyIntent(Intent intent, String permission, int appOp,
int userId) {
ActivityManager.broadcastStickyIntent(intent, appOp, userId);
}
/**
* @deprecated use ActivityManager.noteWakeupAlarm instead.
*/
static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
String tag) {
ActivityManager.noteWakeupAlarm(ps, sourceUid, sourcePkg, tag);
}
/**
* @deprecated use ActivityManager.noteAlarmStart instead.
*/
static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
ActivityManager.noteAlarmStart(ps, sourceUid, tag);
}
/**
* @deprecated use ActivityManager.noteAlarmFinish instead.
*/
static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
ActivityManager.noteAlarmFinish(ps, sourceUid, tag);
}
}
解釋說這個類已經被棄用,方法都可以用ActivityManager來中的代替。
而且代理類ActivityManagerProxy已經被刪除!
小結:API26中啟動Activity時候,和AMS通訊機制已經被改成AIDL方式!
擴充套件思考:
1、其實通過看aidl 自動生成檔案,可以看出,
stub.asInterface其實呼叫的也是queryLocalInterface,api25和api26的本質是一樣的。
2、api26中只有ServiceManagerNative還沒有被棄用。
25中使用的:
ApplicationThreadNative、
ActivityManagerNative、
BulkCursorNative、
ContentProviderNative、
都已經不在使用。