启动模式

一、概念

顾名思义,就是activity的启动方式方法,共有4种模式standard,singleTop,singleTask,singleInstance。
为什么要学习启动模式呢?因为有些时候我们是需要控制activity的实例数量的,比如通话界面,整个手机中应该只有一个通话activity的实例。再比如浏览器,我们可以打开多个页面,各个页面间相互独立。这类的需求我们就需要使用启动模式来实现,所以理解每一种启动模式的特点就很必要了。
这里插一句,配置activity启动模式有2种方式,在AndroidManifinest.xml中配置和代码配置
接下来就以一个demo为例说明下几种方式的特点

二、demo相关

2.1 xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.example.hjw.launchmode.MainActivity"><Buttonandroid:id="@+id/bt_singleInstance"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="bt_singleInstance"/><Buttonandroid:id="@+id/bt_singleTop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="bt_singleTop"/><Buttonandroid:id="@+id/bt_singleTask"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="bt_singleTask"/><Buttonandroid:id="@+id/bt_self"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="bt_self"/></LinearLayout>

2.2 AndroidManifinest.xml

4个Activity,分别配置4种启动模式

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.hjw.launchmode"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter></activity><activityandroid:name=".TopActivity"android:launchMode="singleTop"android:taskAffinity="com.example.hjw.launchmode.top"><!--android:taskAffinity="com.example.hjw.launchmode.top"--></activity><activityandroid:name=".TaskActivity"android:launchMode="singleTask"android:taskAffinity="com.example.hjw.launchmode.task"></activity><!----><activityandroid:name=".InstanceActivity"android:launchMode="singleInstance"android:taskAffinity="com.example.hjw.launchmode.task"></activity></application></manifest>

2.3 Activity,共有4个Activity,做的事情都是一样的,这里就只贴出一个,其他的类似

package com.example.hjw.launchmode;import android.content.Intent;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;public class MainActivity extends AppCompatActivity {public static String TAG = "hjw";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG,"onCreate: "+getClass().getSimpleName() + " TaskId: " + getTaskId() + " hasCode:" + this.hashCode());findViewById(R.id.bt_singleInstance).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, InstanceActivity.class);startActivity(intent);}});findViewById(R.id.bt_singleTop).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, TopActivity.class);startActivity(intent);}});findViewById(R.id.bt_singleTask).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, TaskActivity.class);startActivity(intent);}});findViewById(R.id.bt_self).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, MainActivity.class);startActivity(intent);}});}@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);Log.d(TAG,"onCreate: "+getClass().getSimpleName() + " TaskId: " + getTaskId() + " hasCode:" + this.hashCode());}
}
好了,准备工作做完了,接下来就进入高潮了

三、4种启动模式

1,standard

如果没有指定启动模式,默认就是这种方式,例子中就是点击self按钮,启动自己,看下log
   Line 10264: 01-17 19:28:27.290 D/hjw     ( 5419): onCreate: MainActivity TaskId: 426 hasCode:148911758Line 10321: 01-17 19:28:32.445 D/hjw     ( 5419): onCreate: MainActivity TaskId: 426 hasCode:91877479Line 10344: 01-17 19:28:33.651 D/hjw     ( 5419): onCreate: MainActivity TaskId: 426 hasCode:81065124Line 10366: 01-17 19:28:34.566 D/hjw     ( 5419): onCreate: MainActivity TaskId: 426 hasCode:138172765

结论:每次开启activity都会创建一个新的实例,点击back的时候是一个一个的销毁实例。

2,singleTop

(1)这次的顺序是先启动MainActivity,然后一直启动singleTopActivity,看下log
   Line 9896: 01-17 19:32:46.760 D/hjw     ( 5419): onCreate: MainActivity TaskId: 427 hasCode:56325801Line 12280: 01-17 19:32:49.569 D/hjw     ( 5419): onCreate: TopActivity TaskId: 427 hasCode:90947310Line 12772: 01-17 19:32:51.491 D/hjw     ( 5419): onNewIntent: TopActivity TaskId: 427 hasCode:90947310Line 12780: 01-17 19:32:54.239 D/hjw     ( 5419): onNewIntent: TopActivity TaskId: 427 hasCode:90947310Line 12784: 01-17 19:32:54.381 D/hjw     ( 5419): onNewIntent: TopActivity TaskId: 427 hasCode:90947310

可以看到,第一次创建了topActivity,后面都是回调onNewIntent,复用

(2)这次的顺序是,从MainActivity,启动singleTopActivity,再启动Main,再启动几次Top
   Line 9912: 01-17 19:37:32.003 D/hjw     ( 5817): onCreate: MainActivity TaskId: 429 hasCode:148911758Line 10043: 01-17 19:38:06.624 D/hjw     ( 5817): onCreate: TopActivity TaskId: 429 hasCode:47509012Line 10086: 01-17 19:38:08.290 D/hjw     ( 5817): onCreate: MainActivity TaskId: 429 hasCode:59946807Line 10114: 01-17 19:38:11.327 D/hjw     ( 5817): onCreate: TopActivity TaskId: 429 hasCode:209995572Line 10128: 01-17 19:38:12.309 D/hjw     ( 5817): onNewIntent: TopActivity TaskId: 429 hasCode:209995572Line 10135: 01-17 19:38:13.131 D/hjw     ( 5817): onNewIntent: TopActivity TaskId: 429 hasCode:209995572Line 10151: 01-17 19:38:13.863 D/hjw     ( 5817): onNewIntent: TopActivity TaskId: 429 hasCode:209995572

结论:栈顶复用,只有位于栈顶时,才可以复用

3,singleTask

测试顺序采用与singleTop同样的方式
(1)
   Line 10253: 01-17 19:41:25.604 D/hjw     ( 5817): onCreate: MainActivity TaskId: 430 hasCode:202738547Line 13098: 01-17 19:41:28.461 D/hjw     ( 5817): onCreate: TaskActivity TaskId: 431 hasCode:19651321Line 13132: 01-17 19:41:30.322 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 431 hasCode:19651321Line 13140: 01-17 19:41:30.900 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 431 hasCode:19651321Line 13148: 01-17 19:41:31.368 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 431 hasCode:19651321Line 13156: 01-17 19:41:31.835 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 431 hasCode:19651321Line 13164: 01-17 19:41:32.305 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 431 hasCode:19651321

这个方式下,与singleTop表现一致(细心的同学可能已经发行,TaskId这时候发生了变化,而前边两种方式,TaskId没有发生变化,TaskId这个点留到最后一起说)

(2)

   Line 10253: 01-17 19:43:59.360 D/hjw     ( 5817): onCreate: MainActivity TaskId: 432 hasCode:57364092Line 10286: 01-17 19:44:03.450 D/hjw     ( 5817): onCreate: TaskActivity TaskId: 433 hasCode:131192636Line 10333: 01-17 19:44:06.559 D/hjw     ( 5817): onCreate: MainActivity TaskId: 433 hasCode:157377881Line 10358: 01-17 19:44:07.885 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 433 hasCode:131192636Line 10385: 01-17 19:44:08.989 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 433 hasCode:131192636Line 10393: 01-17 19:44:09.759 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 433 hasCode:131192636Line 10401: 01-17 19:44:10.296 D/hjw     ( 5817): onNewIntent: TaskActivity TaskId: 433 hasCode:131192636

这里就体现出区别了,当再次启动TaskActivity时,只是调用了onNewIntent,说明复用了该activity。

结论:栈内复用,并且会把它之上的activity实例销毁。从现象看就是back两次,栈就空了。当然了还有其他证明方式
adb shell dumpsys activity activities

4,singleInstance


(1)
   Line 10590: 01-17 19:49:49.377 D/hjw     ( 5817): onCreate: MainActivity TaskId: 434 hasCode:23450184Line 10616: 01-17 19:49:51.074 D/hjw     ( 5817): onCreate: InstanceActivity TaskId: 435 hasCode:177643169Line 10633: 01-17 19:49:52.268 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 435 hasCode:177643169Line 10641: 01-17 19:49:52.489 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 435 hasCode:177643169Line 10649: 01-17 19:49:52.759 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 435 hasCode:177643169

这个表现与singleTask一样

(2)
   Line 10170: 01-17 19:52:58.799 D/hjw     ( 5817): onCreate: MainActivity TaskId: 436 hasCode:119769668Line 10213: 01-17 19:53:01.271 D/hjw     ( 5817): onCreate: InstanceActivity TaskId: 437 hasCode:94725757Line 10238: 01-17 19:53:03.052 D/hjw     ( 5817): onCreate: MainActivity TaskId: 436 hasCode:91870454Line 10293: 01-17 19:53:05.881 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 437 hasCode:94725757Line 10307: 01-17 19:53:08.611 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 437 hasCode:94725757Line 10325: 01-17 19:53:09.233 D/hjw     ( 5817): onNewIntent: InstanceActivity TaskId: 437 hasCode:94725757

结论:创建一个新的task,task只放这一个实例,复用
至此,4种启动模式的特点就介绍完了。

还有一个遗留的问题,TaskId,就是指任务栈的编号可以通过在AndroidManifinest.xml中给Activity设置taskAffinity属性。
activity在启动的时候会优先寻找自己指定的TaskId,对于前2种启动方式,这个属性并不生效,后两种,是有效的。至于为啥,没研究过,请大神指点。另外我自己还有一个问题
   Line 10443: 01-17 19:58:51.761 D/hjw     ( 5817): onCreate: MainActivity TaskId: 438 hasCode:6413022Line 10467: 01-17 19:58:54.475 D/hjw     ( 5817): onCreate: TopActivity TaskId: 438 hasCode:6067614Line 10495: 01-17 19:58:56.345 D/hjw     ( 5817): onCreate: InstanceActivity TaskId: 439 hasCode:222214387Line 10530: 01-17 19:58:57.975 D/hjw     ( 5817): onCreate: TopActivity TaskId: 440 hasCode:180213716Line 10548: 01-17 19:58:59.457 D/hjw     ( 5817): onNewIntent: TopActivity TaskId: 440 hasCode:180213716

应该从log中也能看出顺序,先Main,再Top,再Instance,再Top,这个时候可以看到,Top被放到440中了,而不是之前的438中。 求大神指点

(二)Activity启动模式相关推荐

  1. 【安卓开发 】Android初级开发(二)Activity启动模式

    Activity页面跳转在业务逻辑页面添加以下代码 //跳转到下一个activityIntent intent = new Intent(this,MainActivity2.class);start ...

  2. activity 启动模式_腾讯大牛:你根本不懂Activity!

    码个蛋(codeegg)第 583 次推文 作者:厘米姑娘 原文:https://www.jianshu.com/p/602b1ec4ca7a 在之前的Activity篇主要学习Activity的生命 ...

  3. activity 启动模式_Android世界:Activity的启动模式及其适用范围

    一.Activity启动模式简介 activity启动模式,可以理解为activity在任务栈(也叫"回退栈")的回退规则,即点击"back"键时,activi ...

  4. Android Activity 启动模式详解

    最近有群里的朋友问我 Activity的四种启动模式分别是什么意思? 当初因为项目比较忙,草草的解释了下, Api文档中说的也只是一般,在这里就小记一下吧,以便有更多的朋友对Activity启动模式了 ...

  5. Android初级开发笔记-- activity启动模式的学习(1)

    第一次学习Android中一个很重要的概念,启动模式.文章记录的也只是一些入门知识,随着学习的深入还会有activity启动模式的学习(2)和(3). 下面分三个小点说一下对启动模式的理解区别以及如何 ...

  6. Android开发面试题之Activity启动模式讲解总结

    activity启动模式分为: Standard :默认的启动模式每次启动activity都会新建一个activity,不管是否此activity是否存在 SingleTop :栈顶复用模式,每次启动 ...

  7. Android activity启动模式

    如何正确理解和使用 Activity的4种启动模式 关于Activity启动模式的文章已经很多,但有的文章写得过于简单,有的则过于注重细节,本文想取一个折中,只关注最重要和最常用的概念,原理和使用方法 ...

  8. Android中Activity启动模式详解

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...

  9. Android中Activity启动模式

    Android中Activity启动模式一共是四种,这里我写一下我对其的理解: 1.standard(默认) 2.singleTop,如果某个Activity设置了该属性,且当前Activity就是这 ...

最新文章

  1. 相似度矩阵遍历 python
  2. 装好了ubuntu,w2k却无法启动了,:(
  3. Linux下locale: Cannot set LC_CTYPE to default locale: No such file or directory警告
  4. java 数组用字符做下表_JAVA字符串json数组使用Formatter格式化成表格形式
  5. java基础(1)-几种获取类的扩展方式
  6. Nocatalog 下的RMAN 增量备份 shell脚本
  7. SQL Server -- SQL NULL值,ISNull(),Oracal NVL(),MYSQL IFNULL(),COALESCE()
  8. redis 高可用
  9. Android IPC 结篇
  10. Android常见概念
  11. GB28181协议--GB28181协议简介
  12. 恩智浦智能车大赛----笔记
  13. 外文文献检索下载网站哪些比较好用
  14. Mary_Morton [XCTF-PWN][高手进阶区]CTF writeup攻防世界题解系列17
  15. Python_day04
  16. 调试python程序---pdb
  17. AD19——实验室焊接QFP、PQFP、LQFP、TQFP封装芯片方法(更新)
  18. powerdesigner16.5破解补丁
  19. 金属复合金属纳米簇/双金属纳米簇/贵金属纳米簇的制备步骤
  20. 中小企业网络构架环境搭建

热门文章

  1. 行内块元素加了文字会被挤下来的原因及解决方法。
  2. 用fill给二维数组赋值
  3. 职教计算机应用基础,中等职业学校计算机应用基础教学大纲
  4. crmeb 短信配置相关说明教程
  5. LInux初学者 必学 三种配置网卡IP地址的方式(非常详细)
  6. java毕业设计C语言程序设计》在线自学习系统Mybatis+系统+数据库+调试部署
  7. 微软Surface发布会看什么
  8. 02、django model 模型的使用 基本引擎配置[ 增 删 改]
  9. pythoniter雪峰_python学习(廖雪峰的官方网站)
  10. 自荐.net快速开发平台,新时代的选择