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 //相当于singleTask3 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);4 startActivity(intent);
1 Intent intent = new Intent(MainActivity.this,SecondActivity.class);2 //相当于singleTop3 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 @Override3 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 @Override3 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);
要使用这个功能必须在配置文件中加入权限:(加一行代码)
14
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 }
综上所述,完整版代码如下:
111 17 23 29 35 36 37 43 44 50 51 57 63 64 65
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 @Override11 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+type38 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+data46 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 @Override79 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 }