解锁最舒适的startActivity姿势

  Android开发日常,单个界面UI,单个界面业务,在需要的地方调用startActivity(),App就可以蹦起来啦。多数时候,为了更好的用户体验,或者产品“合理”的想法,界面逻辑并不是乖巧的从A->B->C,再由C->B->A,而是,怎么说呢,只有你想不到,对!。在开发过程中,遇到这类问题,因此,稍加总结,希望能给阅读到此文的小伙伴一些帮助。
  你可能遇到:
  1. 界面由A->B->C->D->A,即D完成某一逻辑后,直接返回A。
  2. 界面由A->B->C->D->(A->Z),这里返回A后立即启动Z。
  3. Application类启动Activity。
  文中可能出现错误,望阅读到的小伙伴及时指出,在核对后我会第一时间修改有误之处。
  咋还没到正文呢,下面就是,从Activity的启动模式讲起。

Activity的四种启动模式

  1. standard(默认)
  2. singleTop(栈顶复用)
  3. singleTask(栈内复用)
  4. singleInstance (全局唯一)

  standard是Activity的默认模式。如果你没有设置启动模式,系统会以该模式启动Activity。在该模式下,Activity每次启动,都会在当前任务栈生成一个新的实例。
  singleTop模式,在该模式下,若要启动的Activity位于当前任务栈栈顶时,则不会再创建新的实例,直接就复用栈顶这个Activity,其回调方法onNewIntent()会被执行。若需要启动的Activity不在栈顶或任务栈中并没有这个Activity存在,则会在栈顶创建一个新实例。
  singleTask,在该模式下,若要启动的Activity在当前任务栈中不存在,则会在栈顶创建一个新实例。若存在,就会复用这个Activity,会将它上面的Activity全部出栈,其回调方法onNewIntent()会被执行。
  singleInstance,在该模式下,要启动的Activity会在一个新的任务栈中创建实例,这个新的任务栈只允许有这一个Activity存在,并且这个实例全局唯一,若再启动这个Activity,则会直接复用存在的实例,其回调方法onNewIntent()会被执行。
  我们可以在AndroidManifest.xml文件中设置Activity的启动模式。
  这样:
  <activity android:name=".testActivity" android:launchMode="singleTop" />

intent标记

  启动模式可以帮助开发者更轻松的实现界面之间逻辑,但项目中,总是有力不从心的地方。怎么办呢,我们可以利用setFlags()方法,为Intent的设置标记,一行代码,轻松跳转。
  举个栗子:

Intent nextActivityIntent = new Intent(this,NextActivity.class);
nextActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(nextActivityIntent);

Intent常用标记(我常用)

  1. Intent.FLAG_ACTIVITY_SINGLE_TOP
  2. Intent.FLAG_ACTIVITY_CLEAR_TOP
  3 .Intent.FLAG_ACTIVITY_NEW_TASK
  4. Intent.FLAG_ACTIVITY_CLEAR_TASK

  FLAG_ACTIVITY_SINGLE_TOP,若要启动的Activity位于当前任务栈栈顶时,则不会再创建新的实例。
  FLAG_ACTIVITY_CLEAR_TOP ,若当前栈中存在要启动的Activity实例,会将它上面的Activity全部出栈。
  FLAG_ACTIVITY_NEW_TASK,要启动的Activity会在一个新的任务栈中创建实例。
  FLAG_ACTIVITY_CLEAR_TASK,这个标记必须和FLAG_ACTIVITY_NEW_TASK一起使用,要启动的Activity会在一个新任务栈创建实例,所有旧的Acitivity都会被干掉。
  以上仅为我常用的标记,联合使用,功能强大。

startActivity方法

  若仅是启动单个界面,可以调用startActivity()方法,若要启动多个界面,就要用到startActivities()方法,后者须传入Intent[]参数,这里注意插入Intent[]中Intent顺序,先启动的Activiity会先压入任务栈中。

上码

1. 界面由A->B->C->D->A,即D完成某一逻辑后,直接返回A

  D中返回A方法如下:

private void backA() {
        Intent backAIntent = new Intent(this, AActivity.class);
        backAIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(backAIntent);
}

  其中FLAG_ACTIVITY_SINGLE_TOP 和FLAG_ACTIVITY_CLEAR_TOP一起使用,A上面BCD会全部出栈,A来到栈顶,A的回调方法onNewIntent()会被执行,这里仅Toast—“Welcome back to A”。
  A中代码如下:

 @Override
 protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Toast.makeText(this, "Welcome back to A", Toast.LENGTH_SHORT).show();
}

运行效果:
这里写图片描述

2. 界面由A->B->C->D->(A->Z),这里返回A后立即启动Z

  可以修改AonNewIntent()方法中代码。
  这样:

@Override
protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Intent ZIntent = new Intent(this, ZActivity.class);
        startActivity(ZIntent);
}

  可以修改DbackA()方法中代码。
  这样:

private void backA() {
        Intent[] intents = new Intent[2];
        intents[0] = new Intent(this, AActivity.class);
        intents[0].setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intents[1] = new Intent(this, ZActivity.class);
        startActivities(intents);
}

两种方法略有区别,这里不做详细讨论。
运行效果:
这里写图片描述

3. 非 Activity Context启动Activity

先上效果:
这里写图片描述

  可以看到,界面由A->B,B界面返回退出App,没有回到A,这里给Intent设置了FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK两个标记,这样,B界面会在新的任务栈创建实例,旧的Activity全部被干掉,因此B返回,直接退出App。若只设置FLAG_ACTIVITY_NEW_TASK标记,B界面返回到A。
   非 Activity Context启动Activity,必须为Intent设置FLAG_ACTIVITY_NEW_TASK标记,否则会报错。
   这样(脑补颜色全红!!!):

android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

最后

  开发是一个团队相互协作,队友会调用你开发的模块,你也会调用队友的模块。我们可以在Activity中添加静态启动方法。
  举个例子:

public static void start(Context context, int  paramOne, String paramTwo) {
         Intent intent = new Intent(context, AActivity.class);
         intent.putExtra("paramOne", paramOne);
         intent.putExtra("paramTwo", paramTwo);
         context.startActivity(intent);    
}

  这样调用者根据方法传入相应参数即可,减少团队不必要沟通,这样开发者若修改此方法(增加或删除参数),可以迅速定位,统一修改。着实是一个非常实用的小技巧。

第一篇博客,就这样吧。
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值