Android面试——Activity的四种启动模式
前言
今天开始,会逐步总结Android面试可能遇到的各种问题及其知识点总结。为的就是今天4月份的晋升面试或者更好机会的面试能够拿出100%的状态。
有兴趣的同学,也可以关注我的Android面试文件夹。
Activity四种启动模式
Activity一共有四种启动模式,分别是:
- standard
- singleTop
- singleTask
- singleInstance
在具体介绍这四种启动模式之前,我们先来简单介绍一下Android任务栈。
Android任务栈
一个Android应用程序功能通常会被拆分成多个Activity,各个Activity之间通过Intent进行连接。在Android系统中,是通过栈结构(FILO的线性表)来保存整个App的Activity,栈底元素是整个任务栈的发起者。 
当一个App启动时,首先会检测当前环境中是否存在该App的任务栈,果然不存在,那么系统就会创建一个任务栈给这个App。这个App所启动的Activity都将在这个栈中进行管理,这个栈也被成为是一个Task.(ps:这里是针对standard模式来进行简单阐述)。
 
需要特别注意的是:由于Activity有四种不同的启动模式,因此导致一个Task中的Activity可能来自不同的App,同一个App的Activity也可能不在一个Task中。
查看Activity任务栈的命令
下面介绍几条常用命令用来查看Activity的任务栈:
- adb shell dumpsys activity : 查看ActivityManagerService的所有信息。
- adb shell dumpsys activity activities : 查看Activity的组件信息。
- adb shell dumpsys activity services : 查看Service的组件信息。
- adb shell dumpsys activity providers: 查看ContentProvider信息。
- adb shell dumpsys activity broadcasts: 查看BroadCastReceiver信息。
- adb shell dumpsys activity intents: 查看intent信息。
- adb shell dumpsys activity processes:查看进程信息。
示例代码
首先,定义两个Activity,分别为MainActivity和SecondActivity。且其布局中均只有一个Button按钮。 
其中,MainActivity中的按钮点击事件为启动SecondActivity,而SecondActivity中的按钮事件用来启动自己。
MainActivity.java
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        Button mButton1 = (Button) findViewById(R.id.button1);
        mButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startSecondActivity();
            }
        });
    }
    private void startSecondActivity() {
        Intent intent = new Intent("com.imooc.wzy.secondactivity");
        startActivity(intent);
    }
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
SecondActivity.java
public class SecondActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        initView();
    }
    private void initView() {
        Button button = (Button) findViewById(R.id.id_send);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startSelf();
            }
        });
    }
    private void startSelf() {
        Intent intent = new Intent("com.imooc.wzy.secondactivity");
        startActivity(intent);
    }
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
并且,为了模拟跨进程启动Activity,我们讲SecondActivity的android:process设置为“:remote”。从而,SecondActivity和MainActivity是位于两个进程中。
standard
默认的启动模式,如果不指定Activity的启动模式,则使用这种方式启动Activity。 
这种启动模式每次都会创建新的实例,就在之前start这个Activity所在Activity的任务栈创建新的实例。
示例代码:
<activity
    android:name="com.lczh.gaint.ui.MainActivity"
    android:launchMode="standard">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity
    android:name="com.lczh.gaint.ui.SecondActivity"
    android:launchMode="standard"
    android:process=":remote">
    <intent-filter>
        <action android:name="com.imooc.wzy.secondactivity" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
图示: 
singleTop
如果指定启动Activity是singleTop模式,那么在启动时,系统会判断当前栈顶Activity是不是要启动的Activity,如果是则不创建新的Activity而直接引用这个Activity,如果不是,则创建这个Activity。。 
 这种启动模式虽然不会创建新的实例,但是系统仍然会在Activity启动时调用onNewIntent方法。
示例代码:
<activity
    android:name="com.lczh.gaint.ui.SecondActivity"
    android:launchMode="singleTop"
    android:process=":remote">
    <intent-filter>
        <action android:name="com.imooc.wzy.secondactivity" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
图示: 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号