1、Activity的启动模式有四种:standard、singleTop、singleTask、singleInstance。默认是standard。这个配置是AndroidManifest.xml里面对某一个Activity进行设置。
我们利用下面的代码,把当前的任务栈和实验的Activity的地址都显示出来,方便说明。
public class MainActivity extends AppCompatActivity {
private TextView tv_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_main = (TextView) findViewById(R.id.tv_main);
tv_main.setText(String.format("TaskId:%s Current activity id:%s",getTaskId(),toString()));
findViewById(R.id.btnStartAnotherAty).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this,AnotherAty.class);
startActivity(i);
}
});
}
}
我们启动Activity的时候,一般会创建一个实例,并把这个实例压到任务栈里。四种模式的核心在于,我们启动一个Activity的时候,这个实例是从哪里来?
- standard。是默认模式,在这个模式里,只要我们启动Aty,那么就创建新的实例,甭管这个实例存不存在以及是不是在任务栈的栈顶。
- singleTop。和标准模式不同的地方在于,如果Aty的实例在栈顶的话,那么启动的时候直接从栈顶取不用重新创建,如果不在栈顶那没话说直接创建。
- singleTask。比singleTop更会重复利用。也就是说只要任务栈里有这个Aty,如果它在栈顶,直接使用,如果它不在栈顶,那么它上面的Aty统统出栈,它自己直接到了栈顶,然后被调用显示。
- singleInstance。理解更简单,一个Aty配一个任务栈。从一个Aty切换到另一个Aty的过程,也是从一个任务栈切换到另一个任务栈的过程,从任务栈的id可以看出来,它们是在不同的任务栈里面的。
2、显式使用Intent,之前一直在用,就是启动的时候直接都告诉了要启动的类:
startActivity(new Intent(MainActivity.this,AnotherAty.class));
那为什么还要出现隐式使用Intent呢?因为如果我们从A应用想启动B应用的一个Activity,是不知道且无法直接用Aty类来启动的,所以我们需要利用指名道姓指出这个Aty的name然后启动它,这就是隐式使用Intent的方法。
- 在AndroidManifest.xml文件里给我们要启动的Aty配置action和category这个:
<activity android:name=".AnotherAty">
<intent-filter>
<action android:name="club.finnovate.androidactivity.intent.action.MYACTION"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
- 使用的时候,直接指明上面action的名字即可启动:
startActivity(new Intent("club.finnovate.androidactivity.intent.action.MYACTION"));
这一点在跨应用时十分方便。所以这个名字不能乱起,最好是package名+intent+action+这个action名字。此外,尽管我们的action名字不小心泄露了,如果我们不想其他应用来启动我们的话,我们是可以设置Aty的exported为false,默认是true:
<activity android:name=".AnotherAty" android:exported="false">
<intent-filter>
<action android:name="club.finnovate.androidactivity.intent.action.MYACTION"></action>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
3、上面我们看到intent-filter里面有好几个配置。
- 关于action:如果出现多个action相同的页面,系统会弹出显示框让用户自己选择到底启动哪一个?这在浏览器打开网页或者相册预览图片的时候经常遇到。显示框里出现的就是我们应用的icon和Aty的label名称。
- 关于data:在遇到同名action的时候(不遇到不同action也能用)这个data可以用来进一步区分是哪个Aty。比如如下要遵守app协议:
<data android:scheme="app"></data>
其他选项有很多:
使用的话,当然要指明我启动哪个action外,还要指明遵守什么规则等。
startActivity(new Intent("club.finnovate.androidactivity.intent.action.MYACTION", Uri.parse("app://hello")));
通过scheme协议,另外一个案例就是通过浏览器的链接打开手机某个app的Aty页面。这里遇到我们常用的action是VIEW,还要BROWSABLE指明这个是可被浏览器调用的。
<activity android:name=".AnotherAty" android:exported="false" android:label="222222">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.BROWSABLE"></category>
<category android:name="android.intent.category.DEFAULT"></category>
<data android:scheme="app"></data>
</intent-filter>
</activity>
超链接的地址只要是”app://”开头即可。但是,需要我们在手机模拟器上打开网址,点击超链接。一般在手机上10.0.2.2可以访问我们本地的localhost,加上端口号以及路径就可以访问页面,然后点击超链接,就可以打开我们的app的Aty。