Activity的启动模式
Activity有四种启动模式:standard、singleTop、singleTask、singleInstance。可以在AndroidManifest.xml中activity标签的属性android:launchMode中设置该activity的加载模式。
- standard模式:默认的模式,以这种模式加载时,每当启动一个新的活动,必定会构造一个新的Activity实例放到返回栈(目标task)的栈顶,不管这个Activity是否已经存在于返回栈中;
- singleTop模式:如果一个以singleTop模式启动的activity的实例已经存在于返回桟的桟顶,那么再启动这个Activity时,不会创建新的实例,而是重用位于栈顶的那个实例,并且会调用该实例的onNewIntent()方法将Intent对象传递到这个实例中;
注:如果以singleTop模式启动的activity的一个实例已经存在于返回桟中,但是不在桟顶,那么它的行为和standard模式相同,也会创建多个实例;
- singleTask模式:这种模式下,每次启动一个activity时,系统首先会在返回栈中检查是否存在该活动的实例,如果存在,则直接使用该实例,并把这个活动之上的所有活动统统清除;如果没有发现就会创建一个新的活动实例;
- singleInstance模式:总是在新的任务中开启,并且这个新的任务中有且只有这一个实例,也就是说被该实例启动的其他activity会自动运行于另一个任务中。当再次启动该activity的实例时,会重新调用已存在的任务和实例。并且会调用这个实例的onNewIntent()方法,将Intent实例传递到该实例中。和singleTask相同,同一时刻在系统中只会存在一个这样的Activity实例。(singleInstance即单实例)
注:前面三种模式中,每个应用程序都有自己的返回栈,同一个活动在不同的返回栈中入栈时,必然是创建了新的实例。而使用singleInstance模式可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪一个应用程序来访问这个活动,都公用同一个返回栈,也就解决了共享活动实例的问题。(此时可以实现任务之间的切换,而不是单独某个栈中的实例切换)
其实我们不在清单文件中设置,只在代码中通过flag来设置也是可以的,如下:
1 Intent intent = new Intent(MainActivity.this,SecondActivity.class); 2 //相当于singleTask 3 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4 startActivity(intent);
1 Intent intent = new Intent(MainActivity.this,SecondActivity.class); 2 //相当于singleTop 3 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 4 startActivity(intent);
三、Intent的常见应用:
1、打开指定网页:(直接复制的上面的代码)
MainActivity.java中,监听器部分的核心代码如下:
1 button1.setOnClickListener(new OnClickListener() {
2 @Override
3 public void onClick(View v) {
4 Intent intent = new Intent();
5 intent.setAction(Intent.ACTION_VIEW);//方法:android.content.Intent.Intent(String action)
6 Uri data = Uri.parse("http://www.baidu.com");
7 intent.setData(data);
8 startActivity(intent);
9 }
10 });
当然,上方代码也可以简写成:
1 button1.setOnClickListener(new OnClickListener() {
2 @Override
3 public void onClick(View v) {
4 Intent intent = new Intent(Intent.ACTION_VIEW);
5 intent.setData(Uri.parse("http://www.baidu.com"));
6 startActivity(intent);
7 }
8 });
第4行代码:指定了Intent的action是 Intent.ACTION_VIEW,表示查看的意思,这是一个Android系统内置的动作;
第5行代码:通过Uri.parse()方法,将一个网址字符串解析成一个Uri对象,再调用intent的setData()方法将这个Uri对象传递进去。
或者可以写成:
1 button1.setOnClickListener(new OnClickListener() {
2 @Override
3 public void onClick(View v) {
4 Uri uri = Uri.parse("http://www.baidu.com");
5 Intent intent = new Intent(Intent.ACTION_VIEW,uri);//方法: android.content.Intent.Intent(String action, Uri uri)
6 startActivity(intent);
7 }
8 });
2、打电话:
【方式一】打开拨打电话的界面:
1 Intent intent = new Intent(Intent.ACTION_DIAL);
2 intent.setData(Uri.parse("tel:10086"));
3 startActivity(intent);
运行程序后,点击按钮,显示如下界面:

【方式二】直接拨打电话:
1 Intent intent = new Intent(Intent.ACTION_CALL);
2 intent.setData(Uri.parse("tel:10086"));
3 startActivity(intent);
要使用这个功能必须在配置文件中加入权限:(加一行代码)
1 <uses-sdk 2 android:minSdkVersion="8" 3 android:targetSdkVersion="16" /> 4 <uses-permission android:name="android.permission.CALL_PHONE"/>
3、发送短信:
【方式一】打开发送短信的界面:action+type
1 Intent intent = new Intent(Intent.ACTION_VIEW);
2 intent.setType("vnd.android-dir/mms-sms");
3 intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
4 startActivity(intent);
【方式二】打开发短信的界面(同时指定电话号码):action+data
1 Intent intent = new Intent(Intent.ACTION_SENDTO);
2 intent.setData(Uri.parse("smsto:18780260012"));
3 intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
4 startActivity(intent);
4、播放指定路径音乐:action+data+type
1 Intent intent = new Intent(Intent.ACTION_VIEW);
2 Uri uri = Uri.parse("file:///storage/sdcard0/平凡之路.mp3"); ////路径也可以写成:"/storage/sdcard0/平凡之路.mp3"
3 intent.setDataAndType(uri, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
4 startActivity(intent);
5、卸载程序:action+data(例如点击按钮,卸载某个应用程序,根据包名来识别)
注:无论是安装还是卸载,应用程序是根据包名package来识别的。
1 Intent intent = new Intent(Intent.ACTION_DELETE);
2 Uri data = Uri.parse("package:com.example.smyh006intent01");
3 intent.setData(data);
4 startActivity(intent);
6、安装程序:action+data+type
1 Intent intent = new Intent(Intent.ACTION_VIEW);
2 Uri data = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk")); //路径不能写成:"file:///storage/sdcard0/···"
3 intent.setDataAndType(data, "application/vnd.android.package-archive"); //Type的字符串为固定内容
4 startActivity(intent);
注:第2行的路径不能写成:"file:///storage/sdcard0/···",不然报错如下:

疑问:通过下面的这种方式安装程序,运行时为什么会出错呢?
1 //通过指定的action来安装程序
2 public void installClickTwo(View view){
3 Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED);
4 Uri data = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk")); //路径不能写成:"file:///storage/sdcard0/···"
5 intent.setData(data);
6 startActivity(intent);
7 }
综上所述,完整版代码如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 android:orientation="vertical" 10 tools:context=".MainActivity" > 11 <Button 12 android:id="@+id/button1_browsePage" 13 android:layout_width="match_parent" 14 android:layout_height="wrap_content" 15 android:onClick="browsePageClick" 16 android:text="打开指定网页"/> 17 <Button 18 android:id="@+id/button2_openDialPage" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:onClick="openDialPageClick" 22 android:text="打开拨号面板"/> 23 <Button 24 android:id="@+id/button3_dialPhone" 25 android:layout_width="match_parent" 26 android:layout_height="wrap_content" 27 android:onClick="dialPhoneClick" 28 android:text="直接拨打指定号码"/> 29 <Button 30 android:id="@+id/button4_openMsgPage" 31 android:layout_width="match_parent" 32 android:layout_height="wrap_content" 33 android:onClick="openMsgPageClick" 34 android:text="打开发短信的界面"/> 35 36 37 <Button 38 android:id="@+id/button5_sendMsg" 39 android:layout_width="match_parent" 40 android:layout_height="wrap_content" 41 android:onClick="sendMsgClick" 42 android:text="给指定的人发短信"/> 43 44 <Button 45 android:id="@+id/button6_playMusic" 46 android:layout_width="match_parent" 47 android:layout_height="wrap_content" 48 android:onClick="playMusicClick" 49 android:text="播放指定路径音乐"/> 50 51 <Button 52 android:id="@+id/button7_uninstall" 53 android:layout_width="match_parent" 54 android:layout_height="wrap_content" 55 android:onClick="uninstallClick" 56 android:text="卸载程序"/> 57 <Button 58 android:id="@+id/button8_install" 59 android:layout_width="match_parent" 60 android:layout_height="wrap_content" 61 android:onClick="installClick" 62 android:text="安装程序"/> 63 64 65 </LinearLayout>
MainActivity.java代码如下:
1 package com.example.m06intent01;
2 import java.io.File;
3 import android.app.Activity;
4 import android.content.Intent;
5 import android.net.Uri;
6 import android.os.Bundle;
7 import android.view.Menu;
8 import android.view.View;
9 public class MainActivity extends Activity {
10 @Override
11 protected void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.activity_main);
14 }
15 //打开指定网页
16 public void browsePageClick(View view){
17 Intent intent = new Intent(Intent.ACTION_VIEW);
18 intent.setData(Uri.parse("http://www.baidu.com/"));
19 startActivity(intent);
20
21 }
22
23 //打开拨号面板
24 public void openDialPageClick(View view){
25 Intent intent = new Intent(Intent.ACTION_DIAL);
26 intent.setData(Uri.parse("tel:10086"));
27 startActivity(intent);
28 }
29
30 //直接拨打指定号码
31 public void dialPhoneClick(View view){
32 Intent intent = new Intent(Intent.ACTION_CALL);
33 intent.setData(Uri.parse("tel:10086"));
34 startActivity(intent);
35 }
36
37 //打开发短信的界面:action+type
38 public void openMsgPageClick(View view){
39 Intent intent = new Intent(Intent.ACTION_VIEW);
40 intent.setType("vnd.android-dir/mms-sms");
41 intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
42 startActivity(intent);
43 }
44
45 //打开发短信的界面(指定电话号码):action+data
46 public void sendMsgClick(View view){
47 Intent intent = new Intent(Intent.ACTION_SENDTO);
48 intent.setData(Uri.parse("smsto:18780260012"));
49 intent.putExtra("sms_body", "具体短信内容"); //"sms_body"为固定内容
50 startActivity(intent);
51 }
52
53 //播放指定路径音乐
54 public void playMusicClick(View view){
55 Intent intent = new Intent(Intent.ACTION_VIEW);
56 Uri uri = Uri.parse("file:///storage/sdcard0/平凡之路.mp3"); //路径也可以写成:"/storage/sdcard0/平凡之路.mp3"
57 intent.setDataAndType(uri, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
58 startActivity(intent);
59 }
60
61 //卸载某个应用程序,根据包名来识别
62 public void uninstallClick(View view){
63 Intent intent = new Intent(Intent.ACTION_DELETE);
64 Uri data = Uri.parse("package:com.example.smyh006intent01");
65 intent.setData(data);
66 startActivity(intent);
67 }
68
69 //安装某个应用程序,根据apk的文件名来识别
70 public void installClick(View view){
71 Intent intent = new Intent(Intent.ACTION_VIEW);
72 Uri data = Uri.fromFile(new File("/storage/sdcard0/AndroidTest/smyh006_Intent01.apk")); //路径不能写成:"file:///storage/sdcard0/···"
73 intent.setDataAndType(data, "application/vnd.android.package-archive"); //Type的字符串为固定内容
74 startActivity(intent);
75 }
76
77
78 @Override
79 public boolean onCreateOptionsMenu(Menu menu) {
80 // Inflate the menu; this adds items to the action bar if it is present.
81 getMenuInflater().inflate(R.menu.main, menu);
82 return true;
83 }
84
85 }
浙公网安备 33010602011771号