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 }