意图intent.setFlags方法中的参数值含义

本文详细解析了Android中Intent的四种常用Flags:FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_NO_HISTORY及FLAG_ACTIVITY_SINGLE_TOP的功能与应用场景,帮助开发者更好地管理Activity栈。
一.  intent.setFlags()方法中的参数值含义:

1.FLAG_ACTIVITY_CLEAR_TOP例如现在的栈情况为:A B C D 。D此时通过intent跳转到B,如果这个intent添加FLAG_ACTIVITY_CLEAR_TOP标记,则栈情况变为:A B。如果没有添加这个标记,则栈情况将会变成:A B C D B。也就是说,如果添加了FLAG_ACTIVITY_CLEAR_TOP标记,并且目标Activity在栈中已经存在,则将会把位于该目标activity之上的activity从栈中弹出销毁。这跟上面把B的Launch mode设置成singleTask类似。简而言之,跳转到的activity若已在栈中存在,则将其上的activity都销掉。

2.FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。注意如果试图从非activity的非正常途径启动一个activity(例见下文“intent.setFlags()方法中参数的用例”),比如从一个service中启动一个activity,则intent比如要添加FLAG_ACTIVITY_NEW_TASK标记(编者按:activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈,所以要新起一个栈装入启动的activity)。简而言之,跳转到的activity根据情况,可能压在一个新建的栈中。

3.FLAG_ACTIVITY_NO_HISTORY:例如现在栈情况为:A B C。C通过intent跳转到D,这个intent添加FLAG_ACTIVITY_NO_HISTORY标志,则此时界面显示D的内容,但是它并不会压入栈中。如果按返回键,返回到C,栈的情况还是:A B C。如果此时D中又跳转到E,栈的情况变为:A B C E,此时按返回键会回到C,因为D根本就没有被压入栈中。简而言之,跳转到的activity不压在栈中。

4.FLAG_ACTIVITY_SINGLE_TOP:和Activity的Launch mode的singleTop类似。如果某个intent添加了这个标志,并且这个intent的目标activity就是栈顶的activity,那么将不会新建一个实例压入栈中。简而言之,目标activity已在栈顶则跳转过去,不在栈顶则在栈顶新建activity。

二.intent.setFlags()方法中参数的用例:

很多人使用startActivity时候,会碰到如下的异常:
Caused by: Android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
都知道,Context中有一个startActivity方法,Activity继承自Context,重载了startActivity方法。如果使用Activity的startActivity方法,不会有任何限制,而如果使用Context的startActivity方法的话,就需要开启一个新的task(编者按:参见一.2.的编者按),遇到上面那个异常的,都是因为使用了Context的startActivity方法。解决办法是:Java代码中加一个flag,即intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。这样就可以在新的task里面启动这个Activity了。

public class PageProvider extends ContentProvider { private static final String TAG = "PageProvider"; private static final String KEY_EXIT_ACTIVITY = "exit"; private static final String CALL_METHOD_COMMAND = "command"; private static final String CALL_BUNDLE_KEY_INTENTNAME = "intentName"; private static final String CALL_BUNDLE_KEY_INTENTNAME_OPENPAGE = "openPage"; private static final String CALL_BUNDLE_KEY_INTENTNAME_CLOSEPAGE = "closePage"; private static final String CALL_BUNDLE_KEY_SLOTS = "slots"; private static final String CALL_BUNDLE_KEY_NORMALVALUE = "normalValue"; private static final String CALL_RESULT_BUNDLE_KEY_RETCODE = "retCode"; private static final String RETCODE_SUCCEED = "0"; private static final String RETCODE_FAILED = "1"; private static final String RETCODE_UNSUPPORTED = "3"; private static final String RETCODE_WHEEL_UNSUPPOTED = "9"; private static final int CENTER_DISPLAY_ID = 0; @Override public boolean onCreate() { Log.i(TAG, "onCreate"); return true; } @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { Log.i(TAG, "call query"); return null; } @Nullable @Override public String getType(@NonNull Uri uri) { return ""; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { Log.i(TAG, "call insert"); return uri; } @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { Log.i(TAG, "call delete"); return 0; } @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { Log.i(TAG, "call update"); return 0; } @Override public Bundle call(@NonNull String method, @Nullable String arg, @Nullable Bundle extras) { Log.i(TAG, "run call method: " + method); Bundle bundle = new Bundle(); bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, RETCODE_FAILED); if (TextUtils.isEmpty(method) || extras == null) { Log.i(TAG, "method length is 0 or extras is null"); return bundle; } if (!CALL_METHOD_COMMAND.equals(method)) { Log.i(TAG, "method " + method + " is not supported"); return bundle; } String intentName = extras.getString(CALL_BUNDLE_KEY_INTENTNAME, ""); String slotsJsonString = extras.getString(CALL_BUNDLE_KEY_SLOTS, ""); Log.i(TAG, "intentName:" + intentName + " slotsJsonString:" + slotsJsonString); if (TextUtils.isEmpty(intentName) || TextUtils.isEmpty(slotsJsonString)) { Log.w(TAG, "intent or slots is null, return with failed"); return bundle; } String normalValue = getNormalValue(slotsJsonString); //深蓝定制非P档调节方向盘限制拉页面 if (isDeepalAdjustWheelUnSupported(normalValue)) { Log.w(TAG, " DeepLCar not P_Gear with method " + normalValue + " is unsupported"); bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, RETCODE_WHEEL_UNSUPPOTED); return bundle; } if (!isPageSupported(normalValue)) { Log.w(TAG, intentName + " with method " + normalValue + " is unsupported"); bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, RETCODE_UNSUPPORTED); return bundle; } if (CALL_BUNDLE_KEY_INTENTNAME_OPENPAGE.equals(intentName)) { bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, openOrClosePage(normalValue, false)); } else if (CALL_BUNDLE_KEY_INTENTNAME_CLOSEPAGE.equals(intentName)) { bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, openOrClosePage(normalValue, true)); } else { Log.w(TAG, "intent " + intentName + " is unsupported"); bundle.putString(CALL_RESULT_BUNDLE_KEY_RETCODE, RETCODE_UNSUPPORTED); } return bundle; } private String openOrClosePage(@NonNull String method, boolean isClosePage) { Log.i(TAG, "openOrClosePage method:" + method + " isClosePage:" + isClosePage); Intent intent = new Intent(); intent.setPackage(this.getContext().getPackageName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ActivityOptions activityOptions = ActivityOptions.makeBasic(); activityOptions.setLaunchDisplayId(CENTER_DISPLAY_ID); if (isClosePage) { Log.w(TAG,"closePage"); intent.putExtra(KEY_EXIT_ACTIVITY, true); } Map<String, String> normalValueActionMap = VehicleModelDiffFactory.getDiffManager().getNormalValueActionMap(); if (normalValueActionMap == null || !normalValueActionMap.containsKey(method)) { Log.e(TAG, "normalValueActionMap is null or key not exist."); return RETCODE_UNSUPPORTED; } String actionName = normalValueActionMap.get(method); Log.i(TAG, "actionName: " + actionName); intent.setAction(actionName); // 通过intent进行界面操作 int userId = ActivityManagerEx.getCurrentUser(); ContextEx.startActivityAsUser(this.getContext(), intent, activityOptions.toBundle(), UserHandleEx.getUserHandle(userId)); return RETCODE_SUCCEED; } private String getNormalValue(String slotsJsonString) { String normalValue = ""; try { JSONArray slotsJsonArray = new JSONArray(slotsJsonString); if (slotsJsonArray.length() > 0) { normalValue = slotsJsonArray.getJSONObject(0).getString(CALL_BUNDLE_KEY_NORMALVALUE); } } catch (JSONException e) { Log.e(TAG, "slotsJsonString parse to JSONArray failed"); } return normalValue; } /** * 判断是否支持语音打开界面 * * @param method 目标页面 * * @return true:支持,false 不支持 */ private boolean isPageSupported(String method) { Log.i(TAG, "isPageSupported method:" + method); if (TextUtils.isEmpty(method)) { return false; } // 车型不支持拉起页面 if (!VehicleModelDiffFactory.getDiffManager().isSupportVoiceLaunchPage()) { Log.i(TAG, "Does not support launching the page."); return false; } return VehicleModelDiffFactory.getDiffManager().isSupportVoiceLaunchPage(method); } /** * 深蓝D587定制非P档不可拉起方向盘调节页面 */ private boolean isDeepalAdjustWheelUnSupported(String normalValue) { if (CfgWordUtils.isCarTypeDeepal() && PageConstants.CALL_BUNDLE_NORMALVALUE_WHEEL.equals(normalValue)) { try { int gear = TransmissionManager.getInstance().getTransmissionGear(); Log.i(TAG, " isDeepal getTransmissionGear gear " + gear); if (gear != 1) { return true; } } catch (RemoteException | VehicleServiceException exception) { Log.e(TAG, " isDeepal getTransmissionGear failed " + exception.getMessage()); } } return false; } } 解析这段代码
最新发布
10-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值