date: 2017-05-04 14:52:45
基本用例
启动Activity
Activity表示应用的一个屏幕,通过将Intent传递给startActivity(),可以启动新的Activity实例,同时将Intent携带的数据传给新的Activity。如果希望在新的Activity关闭后,返回给原先的Activity数据,需要使用startActivityForResult(),同时在原先的Activity中的onActivityResult()中回调
文档如下说:
Launch an activity for which you would like a result when it finished. When this activity exits, your onActivityResult() method will be called with the given requestCode. Using a negative requestCode is the same as calling startActivity(Intent) (the activity is not launched as a sub-activity).
Note that this method should only be used with Intent protocols that are defined to return a result. In other protocols (such as ACTION_MAIN or ACTION_VIEW), you may not get the result when you expect. For example, if the activity you are launching uses FLAG_ACTIVITY_NEW_TASK, it will not run in your task and thus you will immediately receive a cancel result.
As a special case, if you call startActivityForResult() with a requestCode >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your activity, then your window will not be displayed until a result is returned back from the started activity. This is to avoid visible flickering when redirecting to another activity.
摘抄[4]的一段代码,以更好的理解startActivityForResult()
public class MainActivity extends Activity {
private final static String TAG="MainActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnOpen=(Button)this.findViewById(R.id.btnOpen);
btnOpen.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//得到新打开Activity关闭后返回的数据
//第二个参数为请求码,可以根据业务需求自己编号
startActivityForResult(new Intent(MainActivity.this, OtherActivity.class), 1);
}
});
}
/**
* 为了得到传回的数据,必须在前面的Activity中(指MainActivity类)重写onActivityResult方法
*
* requestCode 请求码,即调用startActivityForResult()传递过去的值
* resultCode 结果码,结果码用于标识返回数据来自哪个新Activity
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String result = data.getExtras().getString("result");//得到新Activity 关闭后返回的数据
Log.i(TAG, result);
}
}
public class OtherActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
Button btnClose=(Button)findViewById(R.id.btnClose);
btnClose.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
//数据是使用Intent返回
Intent intent = new Intent();
//把返回数据存入Intent
intent.putExtra("result", "My name is linjiqin");
//设置返回数据
OtherActivity.this.setResult(RESULT_OK, intent);
//关闭Activity
OtherActivity.this.finish();
}
});
}
}
关于请求码和结果码,在[4]中也配有代码解释:请求码用于区分原Activity中那个控件触发了Intent,结果码用于区分是哪个新的Activity返回了结果
启动服务
Service是一个不使用用户界面而在后台执行操作的组件,通过将Intent传递给startService(),可以启动服务执行一次性操作。这里先放一边…
传递广播
广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将 Intent 传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),您可以将广播传递给其他应用。
Intent的分类
Intent分为显示和隐式
显示Intent
一般会显示的调用,因为知道要启动的Activity或服务的类名
例:
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
除了使用上述的构造函数设置组件名称外,还可以使用intent.setComponent()
或者是intent.setClass()/intent.setClassName()
隐式Intent
不明确启动哪个Activity或服务,而是设置Action,Data,Category 来让系统筛选出合适的Activity。通过<intent-filter>
筛选
在隐式的Intent中,如果找到单个匹配的Intent过滤器,则将启动该组件;如果多个Intent过滤器被匹配,则系统会显示一个对话框,以支持用户选取要使用的应用
[注]对于启动service,一般用显示Intent,因为使用隐式Intent启动,用户无法看到哪些服务已经启动。
例:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
关于隐式调用中使用resolveActivity(),[2]中有这么一段解释:
类似打开相机,发送图片等隐式Intent,是并不一定能够在所有的Android设备上都正常运行。例如打开相机的隐式Intent,如果系统相机应用被关闭或者不存在相机应用,又或者是相机应用的某些权限被关闭等等情况都可能导致这个隐式的Intent无法正常工作。一旦发生隐式Intent找不到合适的调用组件的情况,系统就会抛出ActivityNotFoundException的异常,如果我们的应用没有对这个异常做任何处理,那应用就会发生Crash。
预防这个问题的最佳解决方案是在发出这个隐式Intent之前调用resolveActivity做检查
Intent 构建
Action
[5]中讲的很好,截取Android的分享和接收分享一部分来说明一下
比如有一个应用,为其中的一个Activity设置分享,如下
public static void shareText(Context context, String title, String text) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, title); //设置发给接收共享的应用的标题
intent.putExtra(Intent.EXTRA_TEXT, text);//设置发给接收共享的应用的文本
context.startActivity(Intent.createChooser(intent, title)); //title为显示框的标题
}
关于intent.createChooser的说明参照[6],也就是将符合intent的应用显示在一个框中,框的标题是title
既然有了发送分享的应用,那么就会有接收分享的应用,在接收分享的应用的Manifest中添加如下:
<activity android:name=".SharePage" android:label="分享到微博">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
具体一点的实例就是,比如我们在某个应用上看到一篇很好的文章,该应用设置了发送分享,我们点击分享,就会跳出一个选择框,其中有微信,微博,QQ等,而这些应用就是在Manifest中添加了接收分享的应用
关于其他的类别筛选,[7][8]都比较好的说明了
参考:
[1]https://developer.android.com/guide/components/intents-filters.html?hl=zh-cn#Building
[2]http://blog.csdn.net/daiqiquan/article/details/49308719
[3]http://blog.csdn.net/xiao__gui/article/details/11392987
[4]http://www.cnblogs.com/zgqys1980/p/5286208.html
[5]http://blog.csdn.net/h3c4lenovo/article/details/7722259
[6]http://blog.csdn.net/heng615975867/article/details/18983317
[7]http://blog.csdn.net/andie_guo/article/details/9271973
[8]http://blog.csdn.net/weihan1314/article/details/7973511