普通写Intent的方法和缺陷

  • 普通Activity A要调用起Activity B页面会这么写:

Activity A:

Intent intent = new Intent(A.this, B.class);intent.putExtra("is_index", message);startActivity(intent);

Activity B:

@Overrideprotected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);    ...    String is_index = getIntent().getExtras().getString("is_index");    ...}
  • 上面的写法是大多数Intent写法,在发起方创建intent。但这种写法在代码量大大增加的时候会出现一个问题。当Activity B在各种地方都会被调用起的时候,并且会传入各种各样不同的extra字段时,会发现很混乱,哪些发起方使用了哪些extra字段,每个字段什么意思,哪些是必须的等等问题。最终造成B代码可读性变差,让以后想要调用起B的页面也不清楚需要传入哪些extra。

优化写Intent

  • 同样是Activity A要调用起Activity B页面的例子:

Activity A:

Intent intent = B.newIndexIntent(this, message);startActivity(intent);

Activity B:

private final static String IS_INDEX = "is_index";@Overrideprotected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);    ...    String is_index = getIntent().getExtras().getString(IS_INDEX);    ...}.../** * 创建intent * is_index 是否是首页跳转过来的  */public static Intent newIndexIntent(Context context, String message) {    Intent newIntent = new Intent(context, b.class);    newIntent.putExtra(IS_INDEX, message);    return newIntent;}
  • 用上面的方法可以保证所有extra全部定义在被调用起Activity的内部,对外不可见,并可以对每个extra有详细的注释(是否必须、在什么地方调用等)。

思考

  • 跳转的时候是否可以直接写为 B.newIndexIntent(this,text),因为 发起启动的不是界面,而是上下文对象。是否可以直接做B.class里面封装一个启动方法,里面接受几个参数,然后用传过来的context启动。但有一些特殊情况,如:启动时为startActivityForResult,result的值最好还是放在启动的类里定义等。

附录

  • Intent中的各种FLAG
Intent intent = new Intent(this,xxx.class); //如果activity在task存在,拿到最顶端,不会启动新的Activity  intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); //如果activity在task存在,将Activity之上的所有Activity结束掉  intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //默认的跳转类型,将Activity放到一个新的Task中  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //如果Activity已经运行到了Task,再次跳转不会在运行这个Activity  intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 

网上有关于Intent flag和taskAffinity的实验结果, 我们来看下相关结论:

FLAG_ACTIVITY_NEW_TASK并不像官方文档所说的等同与singleTask.

在没有任何其他flag组合和taskAffinity设置的情况下, 同一应用内FLAG_ACTIVITY_NEW_TASK启动另外一个Activity, 不会在新的Task中创建实例, 也不会有实例复用.

FLAG_ACTIVITY_SINGLE_TOP作用等同与singleTop, 当Task的top Activity是该Activity时, Activity复用.

FLAG_ACTIVITY_CLEAR_TOP会clear top, 也就是说如果Task中有ABCD, 在D中启动B, 会clear掉B以上的CD. CD销毁.

注意, FLAG_ACTIVITY_CLEAR_TOP并不意味着重用, 默认Activity为standard模式的话, 只是会clear其top的其他Activity实例, 该Activity并不会重用, 而是也会销毁, 然后创建一个新的该Activity实例来响应此Intent.

在没有设置taskAffinity的情况下, 同一应用内FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP组合启动另外一个Activity, 作用和单独使用FLAG_ACTIVITY_CLEAR_TOP是一样.(此点类同与第二点)

如taskAffinity解释的一样, 在我们没有引入taskAffinity时(android:affinity=xxx.xxx.xxx), 同一个应用中, 使用各种Intent flag都并不会创建新的Task.

taskAffinity需结合FLAG_ACTIVITY_NEW_TASK使用, 此时会再新的Task中寻找/创建待启动的Activity实例.

强烈建议 FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP结合使用,单独使用FLAG_ACTIVITY_NEW_TASK可能会遇到问题(系统会在android:affinity=xxx.xxx.xxx的Task中找有没有已经存在的A的实例, 发现Task中有. 于是乎, 想重用A. 然而并没有能销毁B, 让A弹出来接收新的Intent.所以说, 这种情况下, Intent.FLAG_ACTIVITY_NEW_TASK必须结合Intent.FLAG_ACTIVITY_CLEAR_TOP来一起用)。

Intent Flag并不能代替launchMode, 至少在想重用Activity的情况下, 你需要做的是考虑launchMode而非Intent Flag.

个人理解, Intent Flag更多是倾向于用来做Task中的Activity组织. 而launchMode兼顾Task组织和Activity实例的重用.

更多相关文章

  1. Android改变ExpandableListView的indicator图标实现方法
  2. Android(安卓)中在有序广播中添加自定义权限的实例
  3. Android通过访问网页查看网页源码实例详解
  4. Android(安卓)webService访问实例
  5. 如何避免打开键盘或横竖屏切换,active重启,处理界面的延迟动画
  6. AndroidManiFast 字段意义
  7. Rokon引擎主要类介绍
  8. Android(安卓)Studio使用---一些奇葩但有用的用法
  9. [Android实例] webview 实现翻页功能

随机推荐

  1. Android获取GPS坐标:
  2. Android 随机生成验证码的bitmap
  3. Android模块化架构设计
  4. Dialog的样式
  5. Android(安卓)menu使用
  6. android视频录制(调用系统视频录制),生成
  7. android 音视频录制
  8. android WebView onJsAlert onJsConfirm
  9. android异步取数据
  10. android之socket_百度文库