本文转载:
<!-- <div class="Blog_con3_1">管理员在2009年8月13日编辑了该文章文章。</div> -->
Android应用程序的基本组件,这些基本组建除了Content Provider之外,几乎全部都是依靠Intent对象来激活和通信的。
下面介绍Intent类,并通过例子来说明Intent一般用法
1.1 Intent类简介
Intent类的对象是组件间通信的载体,组件之间进行通信就是一个个Intent对象在不断地传递。Intent对象主要作用于运行在相同或不同应用程序的Activity,Service和Broadcast Receiver组件之间,对于这3种组件,其作用机制也不相同
一,对于Activity组件,Intent主要通过调用 Context.startActivity,Context.startActivityForResult等方法实现传递,其结果是启动一个新的 Activity或者使当前的Activity开始新的任务。
二,对于Service组件,Intent主要通过Context.startService和Context.bindService方法实现传递,其作用结果是初始化并启动一个服务或者绑定服务到Context对象。
三,对于Broadcast Receiver组件,Intent主要通过sendBroadcast等一系列发送广播的方法实现传递,其作用结果是将Intent组件以广播的形式发出以便合适的组件接收
一个Intent对象就是一组信息,其包含接收Intent组件所关心的信息(如Action 和 Data)和Android系统关系的信息(如Category),一般来讲,一个Intent对象包含如下内容
1.1.1 Component Name部分
组件名称指明了未来要处理Intent的组件,组件名称封装在一个ComponentName对象中,该对象用于唯一标识一个应用程序组件,如 Activity,Service,Content Provider等。ComponontName类包含两个String成员,分别代表组件的全程类名和包名,包名必须和 AndroidMainfest.xml中<application>标记中的对应信息一致。
对于Intent对象来说,组件名称不是必须的,如果添加了组件名称则该Intent为“显示Intent”,这样Intent在传递的时候会直接根据 ComponentName对象的信息去寻找目标组件。如果不设置组件名称,则为“隐式Intent”,Android会根据Intent中的其他信息来确定应该响应Intent的组件是哪个。
1.1.2 Action部分
Action为一个字符串对象,其描述了该Intent会触发的动作。Android系统中已经预先设定好了一些表征Action的常量,如 ACTION_CALL,ACTION_MAIN等,同时,开发人员也可以自己定义Intent的动作描述,一般来讲,自己定义Action字符串应该以应用程序的包名为前缀,如可以定义一个Action为“karat.zhan.StartService”.
因为Action很大程度上觉得了一个Intent的内容(主要是Data和Extras部分),所以定义自己的Action时应该坐到见名知义,同时如果应用程序比较复杂,应该为其定一个整体的Action协议,使所有的Action集中管理
1.1.3 Data部分
Data描述Intent的动作所操作到的数据的URI及类型,不同的Action对应不同的操作数据,比如Action为ACTION_VIEW的 Intent的Data应该是“http:”格式的URI.当前组件进行Intent的匹配检查时,正确设置Data的URI资源和数据类型很重要。
1.1.4 Category部分
Category为字符串对象,其包含了可以处理Intent的组件的类别信息,Intent中可以包含任意个Category。同Action一样,Android一样,Android系统预先定义了一些Category常量,但是不可以自定义Category.
调用方法addCategory用来为Intent添加一个Category,方法removeCategory用来移除一个Category;getCategories方法返回已定义的Category
1.1.5 Extras部分
Extras是一组键值对,其包含需要传递给目标组件并由其处理的一些额外信息。
1.1.6 Flags部分
一些有关系统如何启动组件的标志位,所有的标志位都已在Android系统中预先定义
2 IntentFilter类简介
当Intent在组件之间进行传递时,组件如果需要告知Android系统自己能够响应和处理哪些Intent,就需要使用IntentFilter对象。顾名思义,IntentFilter对象负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理。
IntentFilter实行“白名单”管理,即只用列出组件乐于接收的Intent,IntentFilter只会过滤掉隐式Intent,显示的 Intent会被直接传递到目标组件,一个隐式的Intent只有通过了组件的某一个IntentFilter的过滤,才可以被组建接收并处理。
像Activity,Service,Broadcast Receiver这些组件可以有一个或者多个IntentFilter,每个IntentFilter相互独立,只需要通过一个即可。每个 IntentFilter都是android.content包下的IntentFilter类的对象,除了用于过滤广播的IntentFilter可以在代码中创建外,其他组件的IntentFilter必须在AndroidMainfest.xml文件中进行声明
IntentFilter中具有与Intent对应的用于过滤Action,Data和Category的字段,一个Intent对象要想被一个组件处理,必须通过这三层的检查
2.1 检查Action
尽管一个Intent只可以设置一种Action,一个IntentFilter却可以持有一个或多个Action用于过滤,到达的Intent对象只需要匹配期中一个Action即可。但是IntentFilter的Action部分不可以为空,如果Action部分为空则会过滤掉所有Intent,相反,将通过所有的IntentFilter的Action检查
2.2 检查Data
同Action一样,IntentFilter中的Data部分也可以是一个或者多个,也可以没有。每个Data包含的内容为URI和数据类型,进行Data检查时主要也是对这两点进行比较,比较规则如下:
一,如果Intent对象没有设置Data,只有IntentFilter也未作设置时才可以通过检查;
二,如果Intent对象只设置了URI而没有指定数据类型,只有当其匹配IntentFilter的URI,并且IntentFIlter也米有设置数据类型时该Intent对象才可以通过检查。
三,如果Intent对象只指定了数据类型而没有设置URI,只有当其匹配IntentFIlter的数据类型,并且也没有设置URI时该Intent对象才可以通过检查。
四,如果Intent对象既包含了URI又包含了数据类型,只有当其数据类型匹配IntentFilter中的数据类型并且通过了URI检查时该Intent对象才可以通过检查。
2.3 检查Category
IntentFilter中可以设置多个Category,检查Category时,只有当Intent对象中所有的Category都匹配 IntentFilter中的Category时该Intent对象才可以通过检查,并且IntentFilter中的Category可以比 Intent中的Category多,但是必须都包含Intent对象中所有的Category.如果一个Intent没有设置Category,则将通过所有IntentFilter的Category检查。
IntentFilter既可以在AndroidMainfest.xml中声明,也可以在代码中动态创建。如果实在 AndroidMainfest.xml中声明IntentFilter,需要使用<intent-filter>标记。该标记包含<action>,<data><category>子标签,每个子标签中包含的属性以及对应的方法如下:
子标签 属性 说明 对应方法
<action> name 字符串,系统预定义或者自己定义 addAction(string)
<category> name 字符串 addCategory(String)
mimeType 数据类型,可以使用通配符 addDataType(String)
scheme 这四个部分共同组成了 addDataScheme(String)
<data> host RUI,其格式为: addDataAuthority(String)
port scheme://host:port/path, addDataPath(String)
path 例如content://karant.zhan:200/files
如果一个到来的Intent对象通过乐意不止一个组件(如Activity,Service等)的IntentFilter的检查,那么系统将会弹出提示,让用户选择激活哪个组件。
下面用三个例子来对Intent进行介绍:
实例1.与Android系统组件通信
本例使用Intent和IntentFilter与Android系统预定义组拨号程序进行通信
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="拨号"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="karant.zhan"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".IntentToSystem"
android:label="@string/app_name">
<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.CALL_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
Activity类代码:
package karant.zhan;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class IntentToSystem extends Activity {
Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener(){ //监听按钮
@Override
public void onClick(View v) {
Intent myIntent = new Intent(Intent.ACTION_DIAL); //创建Intent对象
IntentToSystem.this.startActivity(myIntent); //启动Android内置的拨号程序
}
});
}
}
运行效果:
实例2:下面将会是一个应用程序内部组件之间通过Intent和Broadcast Receiver组件通信的例子
在Activity组件中通过单机按钮启动一个Service,Service将会启动一个线程,该线程的工作是定时产生一个随机数,将其封装到 Intent对象中传递给Activity,Activity接收到Intent后提取期中的信息将其显示到TextView控件中。单击停止来停止服务
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/buttonStart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="开始"
/>
<Button
android:id="@+id/buttonStop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="停止"
/>
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="未连接"
/>
</LinearLayout>
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="karant.zhan"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".IntentToBR"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" android:process=":remote" >
<intent-filter>
<action android:name="karant.zhan.Myservice"/>
</intent-filter>
</service>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
Activity类代码:
package karant.zhan;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class IntentToBR extends Activity {
public static final int CMD_STOP_SERVICE = 0;
Button buttonStart; //开始服务Button对象引用
Button buttonStop; //停止服务Button对象引用
TextView textView; //TextView对象引用
DataReceiver dataReceiver; //BroadcastReceiver对象
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonStart = (Button)findViewById(R.id.buttonStart);
buttonStop = (Button)findViewById(R.id.buttonStop);
textView = (TextView)findViewById(R.id.textView);
buttonStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent myIntent = new Intent(IntentToBR.this, karant.zhan.MyService.class);
IntentToBR.this.startService(myIntent); //发送Intent启动Service
}
});
buttonStop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent myIntent = new Intent(); //创建Intent对象
myIntent.setAction("karant.zhan.IntentToBR");
myIntent.putExtra("cmd", CMD_STOP_SERVICE);
sendBroadcast(myIntent); //发送广播
}
});
}
@Override
protected void onStart() {
dataReceiver = new DataReceiver();
IntentFilter filter = new IntentFilter(); //创建IntentFilter对象
filter.addAction("karant.zhan.IntentToBR");
registerReceiver(dataReceiver, filter); //注册Broadcast Rceiver
super.onStart();
}
@Override
protected void onStop() {
unregisterReceiver(dataReceiver); //取消注册Broadcast Receiver
super.onStop();
}
private class DataReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) { //重写onReceive方法
//下面两行代码从接收到的Intent对象中取出Extra部分的信息并将其作为TextView的显示内容
double data = intent.getDoubleExtra("data", 0);
textView.setText("Service的数据为:"+ data);
} //继承自BroadcastReceiver的子类
}
}
MyService类代码:
package karant.zhan;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
public class MyService extends Service{
CommandReceiver cmdReceiver; //继承自BroadcastReceiver的子类
boolean flag; //线程执行的标志位
@Override
public void onCreate() {
flag = true;
cmdReceiver = new CommandReceiver();
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
//重写onBind
return null;
}
//重写onStartCommand
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter(); //创建IntentFilter对象
filter.addAction("karant.zhan.MyService");
registerReceiver(cmdReceiver, filter); //注册Broadcast Receiver
doJob(); //调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
this.unregisterReceiver(cmdReceiver); //重写onDestroy方法
super.onDestroy();
}
public void doJob(){ //新建线程
new Thread(){
public void run() {
while(flag){
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent();
intent.setAction("karant.zhan.IntentToBR");
intent.putExtra("data", Math.random()); //以data为键以随机数为值
sendBroadcast(intent);
}
}
}.start();
}
private class CommandReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int cmd = intent.getIntExtra("cmd", -1); //获取Extra信息
if(cmd == IntentToBR.CMD_STOP_SERVICE){ //如果需要停止服务
flag = false; //停止线程
stopSelf(); //停止服务
}
}
}
}
运行效果:
相关推荐
实验二 Activity组件通信 一、实验目的及要求 (1) 掌握显示启动和隐式启动的方式 (2) 掌握Activity间的数据通信 二、实验内容及步骤 任务:根据下述要求实现对应程序 1、 完成启动界面的设计,要求采用合理布局...
本篇文章将深入探讨Vue2和Vue3在使用上的主要区别以及组件通信的方法。 ### Vue2与Vue3的区别 #### 1. Composition API Vue2 使用的是 Options API,所有组件选项如 data、methods、computed 等都直接在组件选项...
"组件通信与广播消息"这个主题主要聚焦于Android中的Intent机制以及BroadcastReceiver的使用。Intent作为Android系统中的一种消息传递机制,用于启动Activity、Service或触发BroadcastReceiver。在...
在本文中,我们将深入探讨如何在Ionic 3框架中实现组件通信,特别是在处理多重应用需求时的方法。首先,让我们理解组件通信在软件开发中的重要性,尤其是在构建复杂且交互丰富的移动应用时。Angular,作为Ionic的...
了解使用Intent进行组件通信的原理 掌握使用Intent启动Activity的方法 掌握获取Activity返回值的方法 了解Intent过滤器的原理与匹配机制 掌握发送和接收广播消息的方法
Angular2 父子组件通信方式的示例 Angular2 中父子组件通信方式是指在 Angular2 应用程序中,父组件和子组件之间的数据交换和事件传递机制。Angular2 官方文档对组件交互这块有详细的介绍,总共有四种方式:通过...
除了常见的父子组件通信,兄弟组件之间的通信同样频繁且重要。兄弟组件由于处于同一层级,无法直接通过父子组件通信的方式(props 和 $emit)进行数据交互,因此需要借助一些特定的技术和模式来实现有效的信息传递。...
1. React(react18)中组件通信01——props. 2. React(react18)中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅. 3. React(react18)中组件通信03——简单使用 Context 深层传递参数. 4. React...
组件通信机制允许我们在不同的组件之间传递数据和事件,从而使得组件能够相互协作和交互。本文将详细介绍Vue.js中实现组件间通信的几种方法,并对相关的知识点进行解释。 首先,Vue.js组件通信的方式主要有以下几种...
Vue3 组件通信方式概述 在 Vue3 中,组件通信是指组件之间的数据交换和事件传递。组件通信是 Vue 应用程序中非常重要的一部分,它使得不同的组件能够协同工作,实现复杂的业务逻辑。本文将总结 Vue3 中的七种组件...
Vue.js 是一款流行的前端JavaScript框架,它以组件化开发为核心,极大地提高了开发效率和代码复用性。...而理解并熟练运用组件通信,能够帮助开发者更好地处理组件间的交互,提高代码的可读性和可复用性。
3. **非父子组件通信 (Non-Parent-Child Communication)**:对于非父子关系的组件通信,可以使用以下方法: - **Vuex**:当应用规模较大时,可以使用Vuex作为中央状态管理器,统一管理和共享状态。 - **Event Bus*...
在这个"vue记事本案例"中,我们重点探讨的是Vue.js中的父子组件通信,以及如何实现新增待办、删除待办(一键清空)、待办数量统计和持久化存储功能。 首先,让我们关注父子组件通信。在Vue.js中,父子组件之间的...
1. **组件通信**:通过定义特定的协议,不同模块之间可以声明并实现服务接口,实现服务的注册和查找。这样,一个模块无需了解其他模块的具体实现,只需通过接口调用即可获取服务,降低了模块间的耦合度。 2. **动态...
组件通信是Android应用程序设计的核心部分,Intent作为Android系统中组件间通信的重要工具,扮演着连接各个组件的关键角色。本章将深入探讨Intent的原理、使用方法以及如何通过Intent实现组件间的交互,特别是启动...
项目中,我们经常会遇到兄弟组件通信的情况。在大型项目中我们可以通过引入vuex轻松管理各组件之间通信问题,但在一些小型的项目中,我们就没有必要去引入vuex。下面简单介绍一下使用传统方法,实现父子组件通信的...
Android 组件通信和后台服务实验报告 一、Intent 进行组件通信的原理 Intent 是 Android 中一种重要的组件通信机制,它允许不同的应用程序组件之间进行交互和通信。Intent 可以用来启动 Activity、服务或broadcast...
此外,文章还探讨了 Vue3 的多种组件通信方式及其具体实现。 适合人群:已经对 Vue2 有一定了解,希望深入学习 Vue3 的开发者。 使用场景及目标:帮助读者理解和掌握 Vue3 中的新特性和最佳实践,提高开发效率,解决...
安卓组件通信与广播消息 安卓组件通信是指在安卓系统中,各个组件之间可以通过Intent进行通信的机制。Intent是一种消息传递机制,可以激活Activity、Service和Broadcast Receiver。在运行时绑定在同一应用或不同...
组件通信与广播消息 组件通信是指在 Android 系统中,应用程序之间或内部的组件之间的交互和数据传递。Intent 是 Android 系统中的一种机制,用于实现组件之间的通信和数据传递。Intent 是一个动作的完整描述,包含...