Intent的用法
一、简介:
1. Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件
想要执行的动作,还可以在不同的组件之间传递数据。
2. Intent一般可以被用于启动活动、传递数据、启动或停止服务、以及发送广播等场景。
二、Intent的基本使用:
1. 启动活动:
1). 启动活动有2种方式:显示Intent与隐式Intent;俩者的区别:
简单的说:
①.对于明确指出了目标组件名称的Intent,我们称之为“显式Intent”。
②.对于没有明确指出目标组件名称的Intent,则称之为“隐式Intent”。
作用范围:
①.显式Intent直接用组件的名称定义目标组件,这种方式很直接,
但是你必须很明确的知道你所调用的目标组件的名称与功能,
因此,显式Intent更多用于在应用程序内部传递消息(自己的程序你知道哪部分在做什么)
比如在某应用程序内,一个Activity启动一个Activity或Service。
②. 但如果想调用别的程序的组件时,且开发人员往往并不清楚别的应用程序的组件名称,这时我们只能用隐式Intent,隐式Intent恰恰相反,它不会用组件名称定义需要激活的目标组件,
而是Android系统帮助应用程序寻找与Intent请求意图最匹配的组件。
Android系统具体怎么找:主要是通过Intent Filter来寻找与隐式Intent相关的对象。
(更详细的另一篇《隐式Intent的使用》中细说)
因此,隐式Intent更广泛地用于在不同应用程序之间传递消息。
2). 使用显示的Intent:
/*
*FirstActivity 来启动 SecondActivity
* FirstActivity.this作为上下文传入;(随时获取上下文的方法在《Toast》中提过)
* SecondActivity.class作为目标活动(目标组件)传入->明确指出,所以为显示Intent
* startActivity()用于启动活动
*/
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.startActivity(intent);
3).使用隐式的Intent:
①.在AndroidManifest.xml中定义<intent-filter>(位于<activity>内部):
<!--1.这里定义了目标活动(目标组件) -> .SecondActivity-->
<!--2.指明这个活动的【动作标识action为】:com.example.activity.ACTION_START-->
<!--3.指明这个活动的【类别标识category为】:android.intent.category.DEFAULT 与-->
<!--com.example.activity.CPJ_category-->
<activity android:name="com.example.activity.SecondActivity">
<intent-filter>
<action android:name="com.example.activity.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.example.activity.CPJ_category"/>
</intent-filter>
</activity>
<!--指定当前活动可以响应com.example.activity.ACTION_START这个action-->
<!--1.<category>标签包含一些附加信息,更精确指明当前的活动能够响应的Intent中,还可能带有的category-->
<!--2.只有action和category同时匹配才能响应Intnet-->
<!--3.android.intent.category.DEFAULT是一种默认的category,在调用-->
<!--startActivity()时会自动把这个category添加到intent中-->
<!--4.一个intent只能由一个action,但是可以有多个category-->
②.定义跳转的上下文FirstActivity.java,并在其中加入如下代码:
/*
*FirstActivity 来启动 SecondActivity
* new Intent("com.example.activity.ACTION_START")定义了动作标识action
* addCategory("com.example.activity.CPJ_category")定义了类别标识category
* startActivity()用于启动活动
*此时安卓系统会寻找将action与category都匹配上的目标组件,正好会匹配上
*我们前面定义的.SecondActivity,所以会启动SecondActivity活动。
* 以下代码,并没有明确指出目标组件,而是去匹配,所以称为隐式Intent
*/
Intent intent = new Intent("com.example.activity.ACTION_START");
intent.addCategory("com.example.activity.CPJ_category");
intent.startActivity(intent);
2.传递数据:
Intent还可以在启动一个活动的同时传递一些数据给它(FirstActivity传值给SecondActivity):
1). FirstActivity中加入如下代码:
/*
* 向下一个活动传递参数,利用Intent的putExtra()把信息暂时存储在缓冲中
* putExtra()参数为键值形式:第一个参数是键,第二个参数是值,
*/
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data1","Hello SecondActivity");//传一个String型
intent.putExtra("extra_data2",100);//再传一个int型
startActivity(intent);
</pre><span style="white-space:pre"></span><h3> <span style="font-weight:normal; background-color:rgb(255,255,255)"><span style="font-size:14px; color:#cc33cc">2). SecondActivity中加入如下代码:</span></span></h3><span style="white-space:pre"></span> <pre name="code" class="java">/*
* SecondActivity来接收传来的参数:
* getStringExtra()接收传来的String型参数
* getIntExtra()接收传来的Int型参数,如果没值时返回0
*/
Intent intent = getIntent();
String string_data = intent.getStringExtra("extra_data1");
String int_data = intent.getIntExtra("extra_data2", 0);
我们会发现putExtra()所支持的类型是有限的,虽然常用的一些类型都能传递,但是如果想
传递一个自定义的对象时,就做不到了。使用Intent传递对象的方法在下下篇
《使用Intent传递对象》中详细介绍。
利用Intent返回数据给上一个活动(SecondActivity在销毁时传值给FirstActivity):
1). FirstActivity中写入如下代码(利用startActivityForResult()启动活动):
/*
* startActivityForResult用于启动活动,但这个方法期望在活动销毁的时候能够返回一个结果给
* 上一个活动。有2个参数:
* 第一个参数:Intent
* 第二个参数:请求码,用于在之后的判断中判断数据的来源
* */
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);
2). SecondActivity中写入如下代码(执行销毁操作,并传数据给Intent缓冲):
/*
* setResult()方法接收俩个参数,
* 第一个参数:用于向上一个活动返回处理数据,一般是RESULT_OK与RESULT_CANCELED这俩个值
* 第二个参数:则是把带着数据的intent传递回去
* */
Intent intent = new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK, intent);
finish();//销毁SecondActivity
3).FirstActivity中写入如下代码(重写onActivityResult()方法):
/**
* 接收上一个销毁的活动的值(由startActivityResult()启动的活动,会在销毁时,回调上一个活动的onActivityResult())
* @param {int} requestCode 启动活动时传入的请求码(1)
* @param {int} resultCode 返回数据时传入的处理结果集
* @param {Intent} data 带着数据的intent
* */
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode){
case 1:
if(resultCode == RESULT_OK){
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
3.启动或停止服务:
利用主活动MainActivity去启动或停止一个自定义服务MyService
1).MainActivity中写入如下代码:
/*
*启动一个服务:
* MainActivity.this为上下文
* MyService.class为目标服务(目标组件) -> 显示Intent调用
* startService()启动服务
*/
Intent startIntent = new Intent(MainActivity.this, MyService.class);
startService(startIntent);
/*
*停止一个服务:
* MainActivity.this为上下文
* MyService.class为目标服务(目标组件) -> 显示Intent调用
* stopService()停止服务
*/
Intent stopIntent = new Intent(MainActivity.this, MyService.class);
stopService(stopIntent);
2).那么能隐式的调用Service吗?
如果你像前面一样这样写到:
Intent startIntent = new Intent("com.example.cpj.Service.action_MyService");
startIntent.addCategory("com.example.cpj.Service.service_category");
startService(startIntent);//启动服务
就汇报:Service Intent must be explicit 的错误!
Android 5.0一出来后,其中有个特性就是Service Intent must be explitict,
也就是说从Lollipop开始,service服务必须采用显示方式启动。
那如何隐式调用服务呢:
方法:设置Action和packageName:
①. 在AndroidManifest.xml中定义<intent-filter>(位于<service>内部):
<!--服务注册-->
<service android:name="com.example.cpj.Service.MyService">
<intent-filter>
<action android:name="action_MyService"/>
<category android:name="category_MyService"/>
</intent-filter>
</service>
②. 在MainActivity中写入如下代码:
Intent startIntent = new Intent();
startIntent.setPackage(getPackageName());//这里你需要设置你应用的包名
startIntent.setAction("action_MyService");//action
startIntent.addCategory("service_category");//category
startService(startIntent);//启动服务
4.发送广播:
①.在AndroidManifest.xml中定义<intent-filter>(位于<receiver>内部):
<!--服务注册-->
<receiver android:name="com.example.cpj.MyBroadcastReceiver">
<intent-filter>
<action android:name="MY_BROADCAST"/>
</intent-filter>
</receiver>
②.在MainActivity中写入如下代码:
Intent intent = new Intent("MY_BROADCAST");
sendBroadcast(intent);
三、Intent的隐式用法
Intent的隐式用法也很丰富,比如调用打电话、发短信、开网页等功能;
这些内容都在下一篇《隐式Intent的使用》中具体说明;