下面列出了android.content.pm.ActivityInfo#LAUNCH_SINGLE_TASK 实例代码,或者点击链接到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();
}
}
}
@TargetApi(Build.VERSION_CODES.N)
public static void applyOpenInNewWindow(Context context, Intent intent) {
if(!isFreeformModeEnabled(context)) return;
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
ActivityInfo activityInfo = intent.resolveActivityInfo(context.getPackageManager(), 0);
if(activityInfo != null) {
switch(activityInfo.launchMode) {
case ActivityInfo.LAUNCH_SINGLE_TASK:
case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
break;
}
}
}
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);
}
}
}
}
public static boolean isUrlSchemeDeclaredInAndroidManifest(Context context, String urlScheme, Class klass) {
Intent intent = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(urlScheme + "://"))
.addCategory(Intent.CATEGORY_DEFAULT)
.addCategory(Intent.CATEGORY_BROWSABLE);
ActivityInfo activityInfo = getActivityInfo(context, klass);
return (activityInfo != null && activityInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK &&
AppHelper.isIntentAvailable(context, intent));
}
/**
* 为插件中的Activity分配代理
*
* @param mLoadedApk 插件的实例
* @param actInfo 插件Activity对应的ActivityInfo
* @return 返回代理Activity的类名
*/
public static String findActivityProxy(PluginLoadedApk mLoadedApk, ActivityInfo actInfo) {
boolean isTranslucent = false;
boolean isHandleConfigChange = false;
boolean isLandscape = false;
boolean hasTaskAffinity = false;
boolean supportPip = false;
//通过主题判断是否是透明的
Resources.Theme mTheme = mLoadedApk.getPluginTheme();
isTranslucent = ActivityInfoUtils.isTranslucentTheme(mTheme, actInfo);
if (!isTranslucent) {
//兼容遗留逻辑
if (actInfo.metaData != null) {
String special_cfg = actInfo.metaData.getString(IntentConstant.META_KEY_ACTIVITY_SPECIAL);
if (!TextUtils.isEmpty(special_cfg)) {
if (special_cfg.contains(IntentConstant.PLUGIN_ACTIVITY_TRANSLUCENT)) {
PluginDebugLog.runtimeLog(TAG,
"findActivityProxy meta data contains translucent flag");
isTranslucent = true;
}
if (special_cfg.contains(IntentConstant.PLUGIN_ACTIVTIY_HANDLE_CONFIG_CHAGNE)) {
PluginDebugLog.runtimeLog(TAG,
"findActivityProxy meta data contains handleConfigChange flag");
isHandleConfigChange = true;
}
}
}
}
if (supportPictureInPicture(actInfo)) {
PluginDebugLog.runtimeLog(TAG, "findActivityProxy activity taskAffinity: "
+ actInfo.taskAffinity + " hasTaskAffinity = true" + ", supportPictureInPicture = true");
supportPip = true;
}
if (actInfo.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
String pkgName = mLoadedApk.getPluginPackageName();
if (TextUtils.equals(actInfo.taskAffinity, pkgName + IntentConstant.TASK_AFFINITY_CONTAINER1)) {
PluginDebugLog.runtimeLog(TAG, "findActivityProxy activity taskAffinity: "
+ actInfo.taskAffinity + " hasTaskAffinity = true");
hasTaskAffinity = true;
}
}
if (actInfo.screenOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
PluginDebugLog.runtimeLog(TAG, "findActivityProxy activity screenOrientation: "
+ actInfo.screenOrientation + " isHandleConfigChange = false");
isHandleConfigChange = false;
}
if (actInfo.screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
PluginDebugLog.runtimeLog(TAG, "findActivityProxy isLandscape = true");
isLandscape = true;
}
return matchActivityProxyByFeature(supportPip, hasTaskAffinity, isTranslucent, isLandscape,
isHandleConfigChange, mLoadedApk.getProcessName());
}
/**
* 获取一个占位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;
}
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);
}
}
}
}
}