下面列出了android.content.pm.ActivityInfo#LAUNCH_SINGLE_TOP 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
void save(FixedActivity fixedActivity, int launchMode) {
Set<String> fixedActivities = null;
String tag = null;
if (launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
fixedActivities = mSingleTopFixedActivities;
tag = TAG_SINGLE_TOP;
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
fixedActivities = mSingleInstanceFixedActivities;
tag = TAG_SINGLE_INSTANCE;
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
fixedActivities = mSingleTaskFixedActivities;
tag = TAG_SINGLE_TASK;
}
if (null != fixedActivities) {
int size = fixedActivities.size();
fixedActivities.add(fixedActivity.toString());
if (fixedActivities.size() > size) {
mSharedPreferences.edit()
.putStringSet(tag, fixedActivities)
.apply();
}
}
}
public static void onActivtyDestory(Activity activity) {
synchronized (mRunningActivityList) {
RunningActivityRecord value = mRunningActivityList.remove(activity);
if (value != null) {
ActivityInfo targetActivityInfo = value.targetActivityInfo;
if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
mRunningSingleStandardActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
mRunningSingleTopActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
mRunningSingleTaskActivityList.remove(value.index);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
mRunningSingleInstanceActivityList.remove(value.index);
}
}
}
}
private String launchModeToString(int launchMode) {
String mode = "standard";
if (launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
mode = "singleTop";
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
mode = "singleInstance";
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
mode = "singleTask";
}
return mode;
}
/**
* 获取 launchMode 对应的前缀
*/
private static String getLaunchModeInfix(int launchMode) {
switch (launchMode) {
case ActivityInfo.LAUNCH_SINGLE_TOP:
return "STP";
case ActivityInfo.LAUNCH_SINGLE_TASK:
return "ST";
case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
return "SI";
default:
return "NR";
}
}
public static String getLaunchMode(int mode) {
switch (mode) {
case ActivityInfo.LAUNCH_MULTIPLE:
return "Multiple";
case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
return "Single instance";
case ActivityInfo.LAUNCH_SINGLE_TASK:
return "Single task";
case ActivityInfo.LAUNCH_SINGLE_TOP:
return "Single top";
default:
return "null";
}
}
public static void onActivtyCreate(Activity activity, ActivityInfo targetActivityInfo, ActivityInfo stubActivityInfo) {
synchronized (mRunningActivityList) {
RunningActivityRecord value = new RunningActivityRecord(activity, targetActivityInfo, stubActivityInfo, findMaxIndex() + 1);
mRunningActivityList.put(activity, value);
if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
mRunningSingleStandardActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
mRunningSingleTopActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
mRunningSingleTaskActivityList.put(value.index, value);
} else if (targetActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
mRunningSingleInstanceActivityList.put(value.index, value);
}
}
}
public static void beforeStartActivity() {
synchronized (mRunningActivityList) {
for (RunningActivityRecord record : mRunningActivityList.values()) {
if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
continue;
} else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
doFinshIt(mRunningSingleTopActivityList);
} else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
doFinshIt(mRunningSingleTopActivityList);
} else if (record.stubActivityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
doFinshIt(mRunningSingleTopActivityList);
}
}
}
}
/**
* 获取一个占位activity
*
* @param pluginActivity 插件activity
* @param launchMode 插件activity启动模式
* @param isFixed 是否建立固定映射关系
* @return 占位activity
* @throws ProxyActivityLessException 占位activity不够异常
*/
private String findActivity(String pluginActivity, int launchMode, boolean isFixed)
throws ProxyActivityLessException {
String activity = MODE_STANDARD;
ActivityPool pool = null;
switch (launchMode) {
case ActivityInfo.LAUNCH_MULTIPLE:
final PhantomCore phantomCore = PhantomCore.getInstance();
final ComponentName componentName = ComponentName.unflattenFromString(pluginActivity);
if (componentName != null) {
final ActivityInfo ai = phantomCore.findActivityInfo(componentName);
final PluginInfo pluginInfo = phantomCore.findPluginInfoByActivityName(componentName);
final int themeResourceId = ai == null ? -1 : ai.getThemeResource();
if (themeResourceId != -1 && pluginInfo != null) {
final Resources resources = pluginInfo.getPluginResources();
if (resources != null) {
final Resources.Theme theme = resources.newTheme();
theme.applyStyle(themeResourceId, true);
final TypedArray sa = theme.obtainStyledAttributes(
new int[]{android.R.attr.windowIsTranslucent});
final boolean translucent = sa.getBoolean(0, false);
sa.recycle();
activity = translucent ? MODE_STANDARD_TRANSLUCENT : MODE_STANDARD;
}
}
}
break;
case ActivityInfo.LAUNCH_SINGLE_TOP:
pool = mSingleTopPool;
break;
case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
pool = mSingleInstancePool;
break;
case ActivityInfo.LAUNCH_SINGLE_TASK:
pool = mSingleTaskPool;
break;
default:
break;
}
if (null != pool) {
activity = isFixed ? pool.resolveFixedActivity(pluginActivity) : pool.resolveActivity(pluginActivity);
}
String msg = String.format("resolve %s Activity for %s proxy is %s, fixed is %s",
launchModeToString(launchMode), pluginActivity, activity, isFixed);
VLog.d(msg);
if (null == activity) {
//占位activity不够使用, 这种情况不做处理,宿主提供足够的占位activity
//这里不做主动回收,如果做主动回收可能会使程序正常执行流程发送改变
ProxyActivityLessException pae = new ProxyActivityLessException(msg);
LogReporter.reportException(pae, null);
mCache.clean();
throw pae;
}
return activity;
}
@NonNull
public static Intent wrapToActivityHostProxyIntentIfNeeded(Intent intent) {
if (intent.hasExtra(Constants.ORIGIN_INTENT)) {
VLog.v("skip ActivityHostProxy intent: %s", intent);
// 已经是代理 Intent 了
return intent;
}
// Activity 是否在插件中 ?
final String packageName = ACTIVITY_INTENT_RESOLVER.resolveIntentTarget(intent);
VLog.v("intent: %s, resolveIntentTarget: %s", intent, packageName);
if (packageName == null) {
// Activity 在宿主或其他应用,忽略掉
VLog.v("skip intent not in plugin: %s", intent);
return intent;
}
// Activity 在插件中, 返回代理 Activity
Intent newIntent = new Intent(intent);
if (null != newIntent.getExtras()) {
//清空extras
newIntent.replaceExtras(new Bundle());
}
final ComponentName oldComponent = intent.getComponent();
final String oldClassName = oldComponent.getClassName();
final ComponentName newComponent = new ComponentName(packageName, oldClassName);
VLog.d("old: %s, new: %s", oldComponent, newComponent);
ActivityInfo ai = PhantomCore.getInstance()
.findActivityInfo(new ComponentName(packageName, oldClassName));
int launchMode = ai.launchMode;
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) {
launchMode = ActivityInfo.LAUNCH_SINGLE_TOP;
}
try {
String proxyClass = LaunchModeManager.getInstance()
.resolveActivity(packageName + "/" + oldClassName, launchMode);
newIntent.setComponent(new ComponentName(PhantomCore.getInstance().getContext(), proxyClass));
newIntent.putExtra(Constants.ORIGIN_INTENT, intent.setComponent(newComponent));
return newIntent;
} catch (LaunchModeManager.ProxyActivityLessException e) {
VLog.w(e, "no available activity for intent: %s, launch mode: %d", intent, launchMode);
// TODO: dump proxy activity pool
return intent;
}
}
private static void initPool() {
if (isPoolInited) {
return;
}
Intent launchModeIntent = new Intent();
launchModeIntent.setAction(ACTION_LAUNCH_MODE);
launchModeIntent.setPackage(PluginLoader.getApplicatoin().getPackageName());
List<ResolveInfo> list = PluginLoader.getApplicatoin().getPackageManager().queryIntentActivities(launchModeIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list != null && list.size() >0) {
for (ResolveInfo resolveInfo:
list) {
if (resolveInfo.activityInfo.name.startsWith(STUB_ACTIVITY_PRE)) {
if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
singleTaskMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
singleTopMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
singleInstanceMapping.put(resolveInfo.activityInfo.name, null);
}
}
}
}
isPoolInited = true;
}
public static String bindLaunchModeStubActivity(String pluginActivityClassName, int launchMode) {
initPool();
String stubActivityName = null;
Iterator<Map.Entry<String, String>> itr = null;
if (launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
itr = singleTaskMapping.entrySet().iterator();
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
itr = singleTopMapping.entrySet().iterator();
} else if (launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
itr = singleInstanceMapping.entrySet().iterator();
}
if (itr != null) {
String idleStubActivityName = null;
while (itr.hasNext()) {
Map.Entry<String, String> entry = itr.next();
if (entry.getValue() == null) {
if (idleStubActivityName == null) {
idleStubActivityName = entry.getKey();
}
} else if (pluginActivityClassName.equals(entry.getValue())) {
return entry.getKey();
}
}
//没有绑定到StubActivity,而且还有空余的stubActivity,进行绑定
if (idleStubActivityName != null) {
singleTaskMapping.put(idleStubActivityName, pluginActivityClassName);
return idleStubActivityName;
}
}
//绑定失败
return PluginStubActivity.class.getName();
}
private static void loadStubActivity() {
Intent launchModeIntent = new Intent();
launchModeIntent.setAction(buildDefaultAction());
launchModeIntent.setPackage(FairyGlobal.getHostApplication().getPackageName());
List<ResolveInfo> list = FairyGlobal.getHostApplication().getPackageManager().queryIntentActivities(launchModeIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list != null && list.size() >0) {
for (ResolveInfo resolveInfo:
list) {
if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
singleTaskActivityMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
singleTopActivityMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
singleInstanceActivityMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
if (resolveInfo.activityInfo.theme == android.R.style.Theme_Translucent) {
standardActivityTranslucentMapping.put(resolveInfo.activityInfo.name, null);
} else if (resolveInfo.activityInfo.screenOrientation == SCREEN_ORIENTATION_LANDSCAPE) {
standardLandspaceActivity = resolveInfo.activityInfo.name;
} else {
standardActivityMapping.put(resolveInfo.activityInfo.name, null);
}
}
}
}
}