Android四大组件-Activity
http://www.jianshu.com/p/7529faae9a37
一、基础知识回顾。
-
定义及功能
一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号、拍照、发送email、看地图。每一个activity被给予一个窗口,在上面可以绘制用户接口。窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上。
-
启动和栈
一个应用程序通常由多个activities组成,他们通常是松耦合关系。通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity。每一个activity然后可以启动另一个activity为了完成不同的动作。每一次一个activity启动,前一个activity就停止了,但是系统保留activity在一个栈上(“back stack”)。当一个新activity启动,它被推送到栈顶,取得用户焦点。Back Stack符合简单“后进先出”原则,所以,当用户完成当前activity然后点击back按钮,它被弹出栈(并且被摧毁),然后之前的activity恢复。
-
基本用法
基本用法:Activity的本质是一个Java类,如:由我们创建工程生成的MainActivity;一般的每个Activity都会存在一个与它匹配的布局文件(xml文件),由它来写入我们需要Activity展示的各种控件和布局。有了布局文件之后,就需要在类里通过OnCreate方法的setContentView方法调用文件资源ID来初始化UI界面和显示。
-
创建和注册
每个需要显示的Activity都需要我们在工程包下的AndroidMainifest.xml文件进行注册!(注意:程序每次打开时显示的Activity我们称为主界面,它的注册和其他Activity注册有区别)
<!--主Activity-->
<activity
Android:name=”.MainActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN”/>
<category android:name=”android.intent.category.LAUNCHER”/>
</intent-filter>
</activity>
主界面显示的Activity加入了<intent-filter>标签和内部的两句声明,这也是必须的。
<action>元素指定这是一个"main"入口点对这个应用程序。<category>元素指定,这个activity应该被列入系统应用程序列表中(为了允许用户启动这个activity)。
此外如果你的应用程序里没有声明任何主活动,它也是可以安装的,只是你无法在启动器中看见或打开,这种程序一般作为第三方服务供其他应用在内部进行调用,如支付宝的快捷支付应用。
二、生命周期。
-
四种状态
运行状态:当Activity位于栈顶时,此时正好处于屏幕最前方。
暂停状态:当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕)。
停止状态:当Activity被其他Activity完全遮挡,此时此Activity对用户不可见。
销毁状态:当Activity由于人为或系统原因(如低内存等)被销毁。 -
七个回调方法
1.onCreate:活动第一次创建被调用。
2.onStart:活动由不可见变为可见的时候调用。
3.onResume:活动处于与用户交互状态时候调用。
4.onPause:活动失去焦点时被调用。
5.onStop:活动完全不可见的时候调用(如果新活动是一个对话框式活着半透明的活动,onPause会执行,而onStop不会执行)。
6.onDestroy:在活动被销毁之前调用。
7.onRestart:由停止状态变为运行状态之前调用。 -
生命周期图
-
详解
在实际应用场景中,假设A Activity位于栈顶,此时用户操作,从A Activity跳转到B Activity。那么对AB来说,具体会回调哪些生命周期中的方法呢?回调方法的具体回调顺序又是怎么样的呢?
开始时,A被实例化,执行的回调有A:onCreate -> A:onStart -> A:onResume。
当用户点击A中按钮来到B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。
此时如果点击Back键,将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。
至此,Activity栈中只有A。在Android中,有两个按键在影响Activity生命周期这块需要格外区分下,即Back键和Home键。我们先直接看下实验结果:
此时如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。
此时如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。由此可见,Back键和Home键主要区别在于是否会执行onDestroy。 -
扩展
不少应用程序都是采取如Home键的效果,当点击了Back键,系统返回到桌面,然后点击应用程序图标,直接回到之前的Activity界面,这种效果是怎么实现的呢?
通过重写按下Back键的回调函数,转成Home键的效果即可。
@Override public void onBackPressed() { Intent home = new Intent(Intent.ACTION_MAIN); home.addCategory(Intent.CATEGORY_HOME); startActivity(home); }
当然,此种方式通过Home键效果强行影响到Back键对Activity生命周期的影响。注意,此方法只是针对按Back键需要退回到桌面时的Activity且达到Home效果才重写。
或者,为达到此类效果,Activity实际上提供了直接的方法。activity.moveTaskToBack(true);
moveTaskToBack()此方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。
三、Activity跳转(Intent)。
-
可以开启另一个Activity通过传递一个Intent并且startActivity()方法启动它。描述了你希望启动的Activity。
Intent的两种用法:显示Intent和隐式Intent。
(1)显示Intent一般使用方法:
Intent intent=newIntent(FirstActivity.this,SecondActivity.class); startActivity(intent); //简单的两行就能实现第一个活动跳转到第二个活动界面。
(2)隐式Intent一般使用方法:
<!--首先需要在注册第二个活动时加入标签--> <!-- 必须指定CATEGORY_DEFAULT,只有这样startActivity(intent)才能找到 --> <!--注意 Intent Filter顾名思义就是Intent的过滤器,组件通过定义Intent Filter可以决定哪些隐式 --> <activity android:name=”.SecondAcivity”> <intent-filter> <action android:name=”包名.ACTION_START”/> <category android:name=”android.intent.category.DEFAULT”/> </intent-filter> </activity>
这样我们就可以用声明的标签来启动隐式Intent
Intent intent=new Intent(“包名.ACTION_START”); startActivity(intent);
-
(3)两者的使用区别
显式意图一般在应用的内部使用,因为在应用内部已经知道了组件的名称,直接调用就可以了。当一个应用要激活另一个应用中的Activity时,只能使用隐式意图,根据Activity配置的意图过滤器建一个意图,让意图中的各项参数的值都跟过滤器匹配,这样就可以激活其他应用中的Activity。所以,隐式意图是在应用与应用之间使用的。 -
Intent可以指定你希望启动或描述完成的动作(操作系统会为你选择合适的Activity,可能来自定不同的应用程序)。
你的应用程序或许希望执行一些动作,例如发送一份邮件、文件消息或者状态更新,使用你的Activity的数据。在这种情况下,你的应用程序或许没有它自己的Activity来完成这个动作,因此你可以促使设备上其它应用程序提供的Activity来完成你的动作。这才是Intent真正有价值的地方--你可以创建一个Intent描述一个你希望执行的动作,然后系统启动一个合适的activity从其它应用程序。如果有多种Activities可以处理这个Intent,那么 用户可以选择哪一个来执行。例如,如果你希望允许用户发送邮件,你可以创建下面的Intent:
Intent intent= new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL,""); startActivity(intent);
-
(常用意图见文章末尾附录。)
-
一个Intent可以传输小量数据被启动的activity使用。
在启动活动时,Intent中提供了一系列putExtra()方法的重载,可以将我们需要传递的数据暂存在Intent中,在打开另一个活动时,从Intent中取出即可。
具体例子:
(1)比如我们想要传递一个String字符串
String data=”Hello world!”; Intent intent=newIntent(FirstActivity.this,SecondActivity.class); Intent.putExtra(“extra_data”,data); //extra_data是一个标签,data是传入的数据。 //相当于Intent对象具有Map键值对功能。 startActivity(intent);
然后在SecondActivity的Oncreate方法里取出Intent存入的数据
Intent intent=getIntent(); String data=intent.getStringExtra(“extra_data”); //用String接收带extra_data标签的数据 Log.d(“SecondActivity”,data);//打印出data
(2)新建一个Bundle对象 ,想该对象中加入键值对,然后将该对象加入Intent中
Intent intent=new Intent(); Bundle bundle = new Bundle(); bundle.putString("first", "zhang"); bundle.putInt("age", 20); intent.putExtras(bundle); intent.setClass(ActivityMain.this, SecondActivity.class); intent.putExtras(bundle); startActivity(intent);
然后在第二个Activity中接收
Bundle bundle = new Bundle(); bundle = this.getIntent().getExtras(); String a = bundle.getString("first"); int b = Integer.parseInt(bundle.getString("age"));
(3)Intent传递Object对象
Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象。要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。Intent中传递这2种对象的方法:
Bundle.putSerializable(Key,Object); //实现Serializable接口的对象 Bundle.putParcelable(Key, Object); //实现Parcelable接口的对象
以下以最常用的Serializable方式为例 :
假设由登录界面(Login)跳转到主界面(MainActivity)传递的对象为登录的用户信息 User类
首先创建一个序列化类:User
import java.io.Serializable; public class User implements Serializable { private int ID; private String UserName; private String PWD; public final void setID(int value) { ID = value; } public final int getID() { return ID; } public final void setUserName(String value) { UserName = value; } public final String getUserName() { return UserName; } public final void setPWD(String value) { PWD = value; } public final String getPWD() { return PWD; } }
MainActivity传递内容
Intent intent = new Intent(); intent.setClass(MainActivity.this, SecondActivity.class); Bundle bundle = new Bundle(); bundle.putSerializable("user", user); intent.putExtras(bundle); this.startActivity(intent);
SecondActivity接收
Intent intent = this.getIntent(); user=(User)intent.getSerializableExtra("user");
以上就可以实现对象的传递。
补充:
如果传递的是List<Object>,可以把list强转成Serializable类型,而且object类型也必须实现了Serializable接口Intent.putExtras(key, (Serializable)list)
接收(List<YourObject>)getIntent().getSerializable(key)
【补充】
parcelable和Serializable的区别又是什么呢?
Serializable的作用是保存对象的属性到本地文件,数据库,网络流等方便数据传输,也可程序之间传递。
parcelable的设计的目的是为了解决Serializable效率不高的问题,内存开销小,所以在内存间传递数据的方式用parcelable,缺点是不能持久化。
Activity退出时返回结果至前一个Activity
// 1.通过startActivityForResult方式启动一个新Activity Intent intent=newIntent(FirstActivity,this,SecondActivity.class); startActivityForResult(intent, 200); //参数为intent对象, requestCode请求码
// 2.新Activity设定setResult方法,通过该方法可以传递responseCode 和 Intent对象 Intent intent=new Intent(); //Intent中也可以传递Bundle Intent.putExtra(“data_return”,”Helloworld!”); setResult(101,intent); //参数为responseCode响应码 和 intent对象 finish();
// 3.在MainActivity中覆写onActivityResult方法,新Activity一旦退出,就会执行该方法 protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //如果请求标识与返回标识一样,则把数据返回到tv上 if (requestCode == 200 & resultCode ==101) { String s = data.getStringExtra("data_return"); tv.setText(s); } }
四、启动模式。
-
standard、singleTop、singleTask、singleInstance
standard(标准模式):每当启动一个新活动,它都会进入返回栈并位于栈顶的位置,这种模式下,系统不会在乎这个活动是否已经存在于返回栈中,每次启动都会创建并都放在栈顶。
singleTop(栈顶复用):在启动活动时如果发现栈中该活动已经位于栈顶,则重用该实例( 会调用实例的onNewIntent() )而不会创建新的实例。若不在栈顶,则会创建新的实例。
singleTask(栈内复用):启动活动时如果发现栈中已经存在该活动,则重用该实例(会调用实例的 onNewIntent() ),并且将位于它之上的活动统统出栈,如果没有发现就会新建一个实例。
singleIntance(单例模式):会有一个单独的返回栈来管理这个活动,而且栈中只有此活动,不管是任何一个程序来访问这个活动,都共用这个返回栈,也就解决了共享活动的问题。
设置方法:在AndroidMainifest.xml文件中activity标签name之下加入声明:Android:launchMode=” standard、singleTop、singleTask、singleInstance(四选一)”这样就可以配置活动的启动模式了。
-
详解standard
standard模式是默认的启动模式,不用为<activity>配置android:launchMode属性即可,当然也可以指定值为standard。
我们将会一个Activity,命名为FirstActivity,来演示一下标准的启动模式。FirstActivity代码如下: -
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first); TextView textView = (TextView) findViewById(R.id.textView); textView.setText(this.toString()); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(FirstActivity.this, FirstActivity.class); startActivity(intent); } }); }
我们FirstActivity界面中的TextView用于显示当前Activity实例的序列号,Button用于跳转到下一个FirstActivity界面。
然后我们连续点击几次按钮,将会出现下面的现象
我们注意到都是FirstActivity的实例,但序列号不同,并且我们需要连续按后退键两次,才能回到第一个FristActivity。standard模式的原理如下图所示
-
如图所示,每次跳转系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的FirstActivity实例。
这就是standard启动模式,不管有没有已存在的实例,都生成新的实例。 -
详解singleTop
我们在上面的基础上为<activity>指定属性android:launchMode="singleTop",系统就会按照singleTop启动模式处理跳转行为。我们重复上面几个动作,将会出现下面的现象:
我们看到这个结果跟standard有所不同,三个序列号是相同的,也就是说使用的都是同一个FirstActivity实例;如果按一下后退键,程序立即退出,说明当前栈结构中只有一个Activity实例。singleTop模式的原理如下图所示:
正如上图所示,跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。也许朋友们会有疑问,我只看到栈内只有一个Activity,如果是多个Activity怎么办,如果不是在栈顶会如何?我们接下来再通过一个示例来证实一下大家的疑问。
我们再新建一个Activity命名为SecondActivity,如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second); TextView textView = (TextView) findViewById(R.id.textView); textView.setText(this.toString()); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SecondActivity.this, FirstActivity.class); startActivity(intent); } }); }
然后将之前的FirstActivity跳转代码改为:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent);
是的,FirstActivity会跳转到SecondActivity,SecondActivity又会跳转到FirstActivity。演示结果如下:
我们看到,两个FirstActivity的序列号是不同的,证明从SecondActivity跳转到FirstActivity时生成了新的FirstActivity实例。原理图如下:
-
我们看到,当从SecondActivity跳转到FirstActivity时,系统发现存在有FirstActivity实例,但不是位于栈顶,于是重新生成一个实例。
这就是singleTop启动模式,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例。 -
详解singleTask
在上面的基础上我们修改FirstActivity的属性android:launchMode="singleTask"。演示的结果如下:
我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:
在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。
这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
详解singleInstance
这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。
我们修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由于涉及到了多个栈结构,我们需要在每个Activity中显示当前栈结构的id,所以我们为每个Activity添加如下代码:
TextView taskIdView = (TextView) findViewById(R.id.taskIdView); taskIdView.setText("current task id: " + this.getTaskId());
然后我们再演示一下这个流程:
我们发现这两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下:
我们看到从FirstActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到FirstActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。
如果我们修改FirstActivity的launchMode值为singleTop、singleTask、singleInstance中的任意一个,流程将会如图所示:
singleInstance启动模式可能是最复杂的一种模式,为了帮助大家理解,我举一个例子,假如我们有一个share应用,其中的ShareActivity是入口Activity,也是可供其他应用调用的Activity,我们把这个Activity的启动模式设置为singleInstance,然后在其他应用中调用。我们编辑ShareActivity的配置:
<activity android:name=".ShareActivity" android:launchMode="singleInstance"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SINGLE_INSTANCE_SHARE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
然后我们在其他应用中这样启动该Activity:
Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE"); startActivity(intent);
当我们打开ShareActivity后再按后退键回到原来界面时,ShareActivity做为一个独立的个体存在,如果这时我们打开share应用,无需创建新的ShareActivity实例即可看到结果,因为系统会自动查找,存在则直接利用。大家可以在ShareActivity中打印一下taskId,看看效果。关于这个过程,原理图如下:
-
启动模式应用场景
singleTop适合接收通知启动的内容显示页面。例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。所以要从外界尽可能多的跳转到一个界面。
singleTask适合作为程序入口点。例如浏览器的主界面、联系人activity。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance适合需要与程序分离开的页面。这种模式的使用情况比较罕见,例如闹铃提醒,将闹铃提醒与闹铃设置分离。呼叫来电界面。
singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,再次启动,首先打开的是B。
-
总结
LauncherMode 分为两组:
第一组standard和SingleTop是一组用的比较多,他们二个唯一的区别就是SingleTop如果在当前Task的顶部,同时在startActivity()这个Activity的时候就不会再创建新的实例,而是执行该实例的onNewIntent()方法,其他情况下的用法是一样的;
第二组SingleTask和SingleIntance这一组用的比较少,要结合特定情况来使用,这一组的使用区别是比较大的,在我们开发APP的过程中要合理的使用Activity的启动模式来使我们的APP更加的快捷,流畅,提高用户体验。如果有写的不好的还忘指点。
五、其他补充
-
Activity中finish() onDestroy() 和System.exit()的区别
Activity.finish()
Call this when your activity is done and should be closed.
在你的activity动作完成的时候,或者Activity需要关闭的时候,调用此方法。当你调用此方法的时候,系统只是将最上面的Activity移出了栈,并没有及时的调用onDestory()方法,其占用的资源也没有被及时释放。因为移出了栈,所以当你点击手机上面的“back”按键的时候,也不会再找到这个Activity。Activity.onDestory()
the system is temporarily destroying this instance of the activity to save space.
系统销毁了这个Activity的实例在内存中占据的空间。
在Activity的生命周期中,onDestory()方法是他生命的最后一步,资源空间等就被回收了。当重新进入此Activity的时候,必须重新创建,执行onCreate()方法。System.exit(0)
这玩意是退出整个应用程序的,是针对整个Application的。将整个进程直接KO掉。finish函数仅仅把当前Activity退出了,但是并没有释放他的资源。安卓系统自己决定何时从内存中释放应用程序。当系统没有可用内存到时候,会按照优先级,释放部分应用。
-
AppCompatActivity、ActionBarActivity、FragmentActivity和Activity的区别
support v4 FragmentActivity 兼容2.x模式下使用Fragment
support v7 AppCompatActivity 兼容2.x模式下使用Fragment和ActionBar,ActionBarActivity是AppCompatActivity过时产品
如果3.0以上直接继承Activity,便可使用Fragment和ActionBar
-
资源内存不足导致低优先级Activity被杀死
Activity优先级
前台Activity——正在和用户交互的Activity,优先级最高
可见但非前台Activity——Activity中弹出的对话框导致Activity可见但无法交互
后台Activity——已经被暂停的Activity,优先级最低
系统内存不足是,会按照以上顺序杀死Activity,并通过onSaveInstanceState和onRestoreInstanceState这两个方法来存储和恢复数据。
-
ActivityManager--获得正在运行的activity、service、进程、最近运行的应用。
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE) ; //获得系统运行的进程 List<ActivityManager.RunningAppProcessInfo> appList1 = mActivityManager .getRunningAppProcesses(); for (RunningAppProcessInfo running : appList1) { System.out.println(running.processName); } System.out.println("================"); //获得当前正在运行的service List<ActivityManager.RunningServiceInfo> appList2 = mActivityManager .getRunningServices(100); for (ActivityManager.RunningServiceInfo running : appList2) { System.out.println(running.service.getClassName()); } System.out.println("================"); //获得当前正在运行的activity List<ActivityManager.RunningTaskInfo> appList3 = mActivityManager .getRunningTasks(1000); for (ActivityManager.RunningTaskInfo running : appList3) { System.out.println(running.baseActivity.getClassName()); } System.out.println("================"); //获得最近运行的应用 List<ActivityManager.RecentTaskInfo> appList4 = mActivityManager .getRecentTasks(100, 1); for (ActivityManager.RecentTaskInfo running : appList4) { System.out.println(running.origActivity.getClassName()); }
【附录】
-
常用Intent意图表
(1).调用拨号程序 Uri uri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_DIAL, uri); startActivity(intent); (2).发送短信或者彩信 //发生短信 Uri uri = Uri.parse("smsto:10086"); Intent intent = new Intent(Intent.ACTION_SENDTO, uri); intent.putExtra("sms_body", "Hello"); startActivity(intent); //发送彩信,相当于发送带附件的短信 Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("sms_body", "Hello"); Uri uri = Uri.parse("content://media/external/images/media/23"); intent.putExtra(Intent.EXTRA_STREAM, uri); intent.setType("image/png"); startActivity(intent); (3).通过浏览器打开网页 Uri uri = Uri.parse("http://www.google.com"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); (4).发送电子邮件 Uri uri = Uri.parse("mailto:someone@domain.com"); Intent intent = new Intent(Intent.ACTION_SENDTO, uri); startActivity(intent); //给someone@domain.com发邮件发送内容为“Hello”的邮件 Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, "someone@domain.com"); intent.putExtra(Intent.EXTRA_SUBJECT, "Subject"); intent.putExtra(Intent.EXTRA_TEXT, "Hello"); intent.setType("text/plain"); startActivity(intent); // 给多人发邮件 Intent intent=new Intent(Intent.ACTION_SEND); String[] tos = {"1@abc.com", "2@abc.com"}; // 收件人 String[] ccs = {"3@abc.com", "4@abc.com"}; // 抄送 String[] bccs = {"5@abc.com", "6@abc.com"}; // 密送 intent.putExtra(Intent.EXTRA_EMAIL, tos); intent.putExtra(Intent.EXTRA_CC, ccs); intent.putExtra(Intent.EXTRA_BCC, bccs); intent.putExtra(Intent.EXTRA_SUBJECT, "Subject"); intent.putExtra(Intent.EXTRA_TEXT, "Hello"); intent.setType("message/rfc822"); startActivity(intent); (5).显示地图与路径规划 // 打开Google地图中国北京位置(北纬39.9,东经116.3) Uri uri = Uri.parse("geo:39.9,116.3"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); // 路径规划:从北京某地(北纬39.9,东经116.3)到上海某地(北纬31.2,东经121.4) Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=39.9 116.3&daddr=31.2 121.4"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); (6).播放多媒体 Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri = Uri.parse("file:///sdcard/foo.mp3"); intent.setDataAndType(uri, "audio/mp3"); startActivity(intent); Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); (7).拍照 // 打开拍照程序 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, 0); // 取出照片数据 Bundle extras = intent.getExtras(); Bitmap bitmap = (Bitmap) extras.get("data"); (8).获取并剪切图片 // 获取并剪切图片 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); intent.putExtra("crop", "true"); // 开启剪切 intent.putExtra("aspectX", 1); // 剪切的宽高比为1:2 intent.putExtra("aspectY", 2); intent.putExtra("outputX", 20); // 保存图片的宽和高 intent.putExtra("outputY", 40); intent.putExtra("output", Uri.fromFile(new File("/mnt/sdcard/temp"))); // 保存路径 intent.putExtra("outputFormat", "JPEG");// 返回格式 startActivityForResult(intent, 0); // 剪切特定图片 Intent intent = new Intent("com.android.camera.action.CROP"); intent.setClassName("com.android.camera", "com.android.camera.CropImage"); intent.setData(Uri.fromFile(new File("/mnt/sdcard/temp"))); intent.putExtra("outputX", 1); // 剪切的宽高比为1:2 intent.putExtra("outputY", 2); intent.putExtra("aspectX", 20); // 保存图片的宽和高 intent.putExtra("aspectY", 40); intent.putExtra("scale", true); intent.putExtra("noFaceDetection", true); intent.putExtra("output", Uri.parse("file:///mnt/sdcard/temp")); startActivityForResult(intent, 0); (9).打开Google Market // 打开Google Market直接进入该程序的详细页面 Uri uri = Uri.parse("market://details?id=" + "com.demo.app"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); (10).安装和卸载程序 Uri uri = Uri.fromParts("package", "com.demo.app", null); Intent intent = new Intent(Intent.ACTION_DELETE, uri); startActivity(intent); (11).进入设置界面 // 进入无线网络设置界面(其它可以举一反三) Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS); startActivityForResult(intent, 0);