Activity的启动模式有四种,具体就不说了,直接上代码实验
先来写个例子:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lyz.demo.start" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
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>
<activity android:name=".OtherActivity"/>
</application>
</manifest>
MainActivity.java
package com.lyz.demo.start;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_one;
private Button btn_two;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("我是01");
Log.e("MainActivity", "新创建01----" + String.valueOf(getTaskId()));
initView();
}
public void initView(){
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_one:
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.btn_two:
startActivity(new Intent(this,OtherActivity.class));
break;
default:
break;
}
}
}
OtherActivity.java
package com.lyz.demo.start;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
/**
* Created by liyanzhen on 16/10/18.
*/
public class OtherActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_one;
private Button btn_two;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
setTitle("我是02");
Log.e("OtherActivity","新创建02----" + String.valueOf(getTaskId()));
initView();
}
public void initView(){
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_one:
startActivity(new Intent(this,MainActivity.class));
break;
case R.id.btn_two:
startActivity(new Intent(this,OtherActivity.class));
break;
default:
break;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_one"
android:text="我是页面一"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_two"
android:text="我是页面二"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
activity_other.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_one"
android:text="我是页面一"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_two"
android:text="我是页面二"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Run
自动打开应用后,点击硬件返回,手动打开应用,再点击硬件返回,查看log信息:
com.lyz.demo.start E/MainActivity: 新创建01----5957
com.lyz.demo.start E/MainActivity: 新创建01----5958
com.lyz.demo.start E/MainActivity: 新创建01----5959
com.lyz.demo.start E/MainActivity: 新创建01----5960
com.lyz.demo.start E/MainActivity: 新创建01----5961
com.lyz.demo.start E/MainActivity: 新创建01----5962
结论:
任务栈:每打开一次应用程序,默认情况下,开启一个任务栈,来维护activity的组件,其中任务栈的Id是自增长的。
====================重点来了===================
脑子里边记着:
MainActivity -----> 始终是standard(默认)模式
OtherActivity -----> 随着讲解修改为对应模式
1、standard ( the default model )
上面的例子中,修改两个activity的声明
设置属性为android:launchMode=”standard”后
Run
点击按钮1,点击按钮2,点击按钮2,点击按钮2,点击按钮1,查看log:
com.lyz.demo.start E/MainActivity: 新创建01----6016
com.lyz.demo.start E/MainActivity: 新创建01----6016
com.lyz.demo.start E/OtherActivity: 新创建02----6016
com.lyz.demo.start E/OtherActivity: 新创建02----6016
com.lyz.demo.start E/OtherActivity: 新创建02----6016
com.lyz.demo.start E/MainActivity: 新创建01----6016
结论:
此时,当我们点击6次返回时,应用才会退出。
standard
特点:在当前任务栈中,当调用startActivity方法开启界面,会实例化多个实例对象在任务栈中,互相不影响。
问题:会在任务栈中实例化多个对象,重复的太多,容易内存溢出。
2、singleTop(单顶部模式)
上面的例子中,修改AndroidManifest.xml中OtherActivity的声明
设置属性为android:launchMode=”singleTop”
并在OtherActivity.java中增加以下方法:
@Override
protected void onNewIntent(Intent intent) {
Log.e("OtherActivity","onNewIntent方法被调用了!");
super.onNewIntent(intent);
}
Run
应用自动启动后,点击按钮2,点击按钮2,点击按钮2,点击按钮1,点击按钮1,点击按钮2,点击按钮2,查看log:
com.lyz.demo.start E/MainActivity: 新创建01----6018
com.lyz.demo.start E/OtherActivity: 新创建02----6018
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
com.lyz.demo.start E/MainActivity: 新创建01----6018
com.lyz.demo.start E/MainActivity: 新创建01----6018
com.lyz.demo.start E/OtherActivity: 新创建02----6018
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
此时,当我们点击5次返回时,应用才会退出。
结论:
如果被开启的activity已经在任务栈的顶部,这时候不会创建一个新的实例,而是调用栈顶activity的onNewIntent方法。
如果当前任务栈中已经有被开启的activity,但是不在顶部,这时候会创建一个新的实例在任务栈中。
3、singleTask(单任务栈模式)
上面的例子中,修改AndroidManifest.xml中OtherActivity的声明
设置属性为android:launchMode=”singleTask”
Run
应用自动启动后,点击按钮2,点击按钮1,点击按钮1,点击按钮1,点击按钮2,点击按钮2,查看log:
com.lyz.demo.start E/MainActivity: 新创建01----6020
com.lyz.demo.start E/OtherActivity: 新创建02----6020
com.lyz.demo.start E/MainActivity: 新创建01----6020
com.lyz.demo.start E/MainActivity: 新创建01----6020
com.lyz.demo.start E/MainActivity: 新创建01----6020
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
此时,当我们只需点击2次返回,应用即可退出。
结论:
如果被开启的activity已经在任务栈中,则调用startActivity方法开启此页面时,不会再创建一个新的实例,而是把当前的activity显示出来,提到栈顶,同时,会把当前任务栈中activity以上的所有activity清除出栈。
如果当前的activity已经在栈顶,直接调用onNewIntent方法。
应用场景:一般用在页面加载非常庞大时,非常消耗资源,只想初始化一次。
4、singleInstance(单一实例)
上面的例子中,修改AndroidManifest.xml中OtherActivity的声明
设置属性为android:launchMode=”singleInstance”
Run
应用自动启动后,点击按钮2,点击按钮1,点击按钮1,点击按钮1,点击按钮2,点击按钮2,查看log:
com.lyz.demo.start E/MainActivity: 新创建01----6022
com.lyz.demo.start E/OtherActivity: 新创建02----6023
com.lyz.demo.start E/MainActivity: 新创建01----6022
com.lyz.demo.start E/MainActivity: 新创建01----6022
com.lyz.demo.start E/MainActivity: 新创建01----6022
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
此时,当我们点击5次返回时,应用退出。
结论:
如果被开启的activity没有实例化过对象时,调用startActivity开启页面时,会创建一个新的任务栈给activity使用,并且当前任务栈只有它自己存在,其他的activity不会在此任务栈中创建新的实例。
如果被开启的activity已经实例化过,那么会调用onNewIntent方法。
singleInstance附加说明:
(1)在上面那个应用中,在AndroidManifest.xml文件中找到OtherActivity的声明,修改为:
<activity
android:name=".OtherActivity"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="com.lyz.demo.start.activity02"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
(2)新增一个应用
MainActivity.java
package com.lyz.demo.singleInstance;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btn_app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("我是新应用");
Log.e("我是新应用", "----" + getTaskId());
initView();
}
public void initView(){
btn_app = (Button) findViewById(R.id.btn_app);
btn_app.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.lyz.demo.start.activity02");
intent.addCategory(Intent.CATEGORY_DEFAULT);//可加可不加,默认就是default
startActivity(intent);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_app"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="跳转至02" />
</RelativeLayout>
Run
(1)先Run应用一,自动启动后,点击按钮2,点击按钮1,点击按钮1
(2)Run应用二,自动启动后,点击按钮,查看应用一的log:
com.lyz.demo.start E/MainActivity: 新创建01----6038
com.lyz.demo.start E/OtherActivity: 新创建02----6039
com.lyz.demo.start E/MainActivity: 新创建01----6038
com.lyz.demo.start E/MainActivity: 新创建01----6038
com.lyz.demo.start E/OtherActivity: onNewIntent方法被调用了!
结论:
在整个系统中,无论哪一个应用程序开启当前采用singleInstance的activity,如果已经实例化过,那么始终都是调用的同一个activity,而且是在同一个任务栈中。
应用场景:需要常驻在系统中的页面采用singleInstance模式。