Activity启动模式的理解

1、理解 Tasks and Back Stack(任务和后台堆栈)

一个 App 对应一个 Task,该app 内的全部 activity 被安排在一个后台堆栈里。
多窗口模式下:一个windows下可能由多个 Task,系统为每一个窗口单独管理 Taskandroid

当启动一个app时,系统为其启动一个Task。其它App进入后台(每一个堆栈内的 acitivity处于中止状态)。注意:若是后台任务过多,系统会销毁后台活动以释放内存,活动的状态也会丢失。windows

2、管理任务

Android管理任务和后台堆栈的方式,如上所述,经过将全部的活动连续地放在同一任务和“后进先出”的堆栈中,对于大多数应用程序来讲是很是好的,而且没必要担忧您的活动与任务或它们如何退出有关。浏览器

可是,您可能会决定要中断这种正常行为:app

  • 也许您但愿应用程序中的一个活动在启动时 启动一个新任务(而不是放在当前任务中);
  • 当启动一个活动时,你想提出它的一个现有实例,而不是在堆栈的顶部建立一个新实例;
  • 当用户离开任务时,除了根活动,,但愿清除堆栈。

您能够在<activity>清单元素中使用属性,并在传递给startActivity()意图中使用标志。ide

在这方面,您可使用的主体 <activity> 属性以下:性能

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

您可使用的主要意图标志是:this

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_SINGLE_TOP

3、定义启动模式

Android中每一个界面都是一个Activity,切换界面操做实际上是多个不一样Activity之间的实例化操做。在AndroidActivity的启动模式决定了Activity的启动运行方式。code

启动模式容许您定义活动的新实例如何与当前任务关联。你能够用两种方式定义不一样的启动模式:对象

  • 使用清单文件
    当在清单文件中声明一个活动时,能够指定活动在启动时应如何与任务相关联。
  • 使用 Intent flags
    当调用 startActivity() 时,能够在乎图中包含一个标志,声明新的活动如何(或是否)与当前任务相关联。

所以,若是活动A启动活动B,活动B能够在其清单中定义它应该如何与当前任务相关联(若是有的话),并且活动A也能够请求活动B应该如何与当前任务相关联。若是两个活动都定义了活动B应该如何与任务相关联,那么活动A的请求(如意图中定义的)将被授予活动B的请求(如清单中定义的)。事件

注意:一些启动模式 在清单文件中可用 ,但不可用做为意图的标志;一样地,一些启动模式做为 flags 可用,但在清单中不能定义。

使用清单文件

Activity启动模式设置:

<activity android:name=".MainActivity" android:launchMode="standard" />

Activity的四种启动模式:

  1. standard(默认模式)
    系统在启动的任务中建立活动的新实例并将意图路由到该任务。
    该活动能够被实例化屡次,每一个实例能够属于不一样的任务,而且一个任务能够具备多个实例。

  2. singleTop 若是活动的实例已经存在于当前任务的顶部,则系统经过调用其 onNewIntent()方法将意图路由到该实例,而不是建立活动的新实例。

该活动能够屡次实例化,每一个实例能够属于不一样的任务,而且一个任务能够有多个实例(但仅当在后台堆栈顶部的活动不是活动的现有实例)。

  1. singleTask
    系统建立一个新任务并实例化新任务的根的活动。可是,若是活动的实例已经存在于单独的任务中,则系统经过调用其 onNewIntent()方法将意图路由到现有实例,而不是建立新实例。一次只能存在一个活动实例。

注意:虽然活动在一个新任务中启动,但后退按钮仍然将用户返回到先前的活动。

  1. singleInstance
    singleTask 相同,只是系统没有将任何其余活动放入实例中。该活动始终是其任务的惟一成员,该活动启动的任何活动在单独的任务中打开。

在一个新栈中建立该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例,其效果至关于多个应用程序共享一个应用,无论谁激活该Activity都会进入同一个应用中。

举例

1.standard

public class MainActivity extends AppCompatActivity {

    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = findViewById(R.id.textView);
        tv.setText(this.toString());

    }
   
    // 按钮点击事件
    public void launchStandard(View view) {
        startActivity(new Intent(this, MainActivity.class));
        tv.setText(this.toString());
    }
}

输入图片说明

由此可知,这种 Standard 模式是 每次都会建立新的Activity对象,当点击返回按钮时,他会将栈顶(当前Activity)消灭,而后跳到下一层。这种模式可能大多数状况下不是咱们须要的,由于对系统性能的消耗过大。

2.singleTop
从上面的解释中便可知道,在每次使用新的Activity时会自动检测栈顶的当前Activity是不是须要引用的Activity,若是是则直接引用此Activity,而不会建立新的Activity。

<activity
            android:name=".SingleTopActivity"
            android:launchMode="singleTop"
            android:screenOrientation="portrait" />
public class MainActivity extends AppCompatActivity {

    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = findViewById(R.id.textView);
        tv.setText(this.toString());

    }

    public void launchStandard(View view) {
        startActivity(new Intent(this, SingleTopActivity.class));
        tv.setText(this.toString());

    }
}
public class SingleTopActivity extends AppCompatActivity {

    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_top);
        tv = findViewById(R.id.textView);
        tv.setText(this.toString());
    }

   @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Toast.makeText(this,this.getClass().getSimpleName(),Toast.LENGTH_LONG).show();
    }

    public void launchSingleTop(View view) {
        startActivity(new Intent(this, SingleTopActivity.class));
        tv.setText(this.toString());
    }
}

输入图片说明

当在SingleTopActivity点击 "启动当前页面按钮" 时,不会建立新的对象,由于该Activity 处在栈顶,不会建立新的对象,可是会回调 onNewIntent() 方法。   

3.singleTask

此启动模式和singleTop在名字上便可看出区别,即singleTop每次只检测当前栈顶的Activity是不是咱们须要请求建立的,而singleTask则会检测栈中所有的Activity对象,从上向下,若是检测到是咱们所请求的则会消灭此Activity对象上面的对象,直接把检测到的咱们须要的Activity置为栈顶。

4.SingleInstance

此启动模式和咱们使用的浏览器工做原理相似,咱们都知道在多个程序中访问浏览器时,若是当前浏览器没有打开,则打开浏览器,不然会在当前打开的浏览器中访问。此模式会节省大量的系统资源,由于他能保证要请求的Activity对象在当前的栈中只存在一个。

上面即为Android中的四种启动模式,咱们在开发Android项目时会常用到,巧妙设置Activity的启动模式会节省系统开销和程序运行效率。

相关文章
相关标签/搜索