Android基础------Intent的使用

时间:2021-02-10 15:33:26

Intenet的使用


1.Intent的介绍和作用

(1) 什么是Intent

Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动 作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用

可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。

(2) Intent的作用

Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯。比如说调用 startActivity()来启动一个activity,或者由broadcaseIntent()来传递给所有感兴趣的 BroadcaseReceiver, 再或者由startService()/bindservice()来启动一个后台的service.所以可以看出来,intent主要是用来启动其他的 activity 或者service,所以可以将intent理解成activity之间的粘合剂。

activity、service和broadcast receiver之间是通过Intent进行通信的,而另外一个组件Content Provider本身就是一种通信机制,不需要通过Intent。我们来看下面这个图就知道了:

Android基础------Intent的使用


2.Intent的分类

Intent大致可以分为两种类型:显式Intent和隐式Intent。

显式Intent:

如果在我们定义的Intent中明确包含了要启动的组件的完整类名(包名及类名),即Intent的“意图”非常明显,那么这个Intent就是显式的。使用显式Intent最典型的情形是在你自己的程序中启动一个组件,因为你自己肯定知道自己的要启动的组件的类名。比如,为了响应用户操作通过显式的Intent在你的程序中启动一个Activity或启动一个Service下载文件。

隐式Intent:

没有明确指定组件名要启动哪一个活动,而是系统根据动作(action)、类别(category)、数据(Uri)和数据类型来找到最合适的组件。一般来说我们需要在里设置category、action和data等信息。需要注意的是,为了确保App的安全性,我们应该总是使用显式Intent去启动Service并且不要为该Service设置任何的Intent Filter。通过隐式的Intent启动Service是有风险的,因为你不确定最终哪个App中的哪个Service会启动起来以响应你的隐式Intent,更悲催的是,由于Service没有UI的在后台运行,所以用户也不知道哪个Service运行了

Intent Filter,即Intent过滤器,一个组件可以包含0个或多个Intent Filter。Intent Filter是写在App的manifest文件中的,其通过设置action或uri数据类型等指明了组件能够处理接收的Intent的类型。对于Android的主活动都有下面几行代码来表明启动活动:


<intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Android基础------Intent的使用


3.Intent的相关属性

component(组件):目的组件
action(动作):用来表现意图的行动
category(类别):用来表现动作的类别
data(数据):表示与动作要操纵的数据
type(数据类型):对于data范例的描写
extras(扩展信息):扩展信息
Flags(标志位):期望这个意图的运行模式

(1)component

Component属性明确指定Intent的目标组件的类名称。(属于直接Intent)
如果 component这个属性有指定的话,将直接使用它指定的组件。指定了这个属性以后,Intent的其它所有属性都是可选的。

例如,启动第二个Activity时,我们可以这样来写:


 button1.setOnClickListener(new OnClickListener() {            
              @Override
              public void onClick(View v) {
                  //创建一个意图对象
                  Intent intent = new Intent();
                  //创建组件,通过组件来响应
                  ComponentName component = new ComponentName(MainActivity.this, SecondActivity.class);
                  intent.setComponent(component);                
                  startActivity(intent);                
             }
         });


======================================================================
// 写简单一点
                 Intent intent = new Intent();
                 //setClass函数的第一个参数是一个Context对象
                 //Context是一个类,Activity是Context类的子类,也就是说,所有的Activity对象,都可以向上转型为Context对象
                 //setClass函数的第二个参数是一个Class对象,在当前场景下,应该传入需要被启动的Activity类的class对象
                 intent.setClass(MainActivity.this, SecondActivity.class);
                 startActivity(intent);   
======================================================================
// 再写简单一点 
                 Intent intent = new Intent(MainActivity.this,SecondActivity.class);
                 startActivity(intent);
(2)action

当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想“做”三个俯卧撑;我要“写” 一封情书,等等。在Intent中,Action就是描述做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK等, 基本涵盖了常用动作。加的动作越多,越精确。

Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 节点指定一个 Action列表用于标识 Activity 所能接受的“动作”。

<activity android:name=".TargetActivity">  
    <intent-filter>            
         <action android:name="com.scott.intent.action.TARGET"/>  
         <category android:name="android.intent.category.DEFAULT"/>  
    </intent-filter>  
 </activity>  

TargetActivity在其中声明了,即目标action,如果我们需要做一个跳转的动作,就需要在Intent中指定目标的action,如下:

public void gotoTargetActivity(View view) {  
     Intent intent = new Intent("com.scott.intent.action.TARGET");  
     startActivity(intent);  
 }  
(3)category

其中标签指明了当前活动可以响应的action。标签则附加了一些信息,更精确地指明了当前活动能响应的Intent还可能带有的category。只有和同时匹配上Intent中指定的action和category时,活动才能响应该Intent

<category android:name="android.intent.category.LAUNCHER" />  

Android基础------Intent的使用

下面我们来一段代码进行调试以下

  • 1.打开清单文件AndroidManifest.xml
 <activity> 
             android:name=".SecondActivity">
             <intent-filter>
                  <action android:name="com.example.smyh006intent01.MY_ACTION"/>
5                  <category android:name="android.intent.category.DEFAULT" />
6             </intent-filter>            
7         </activity>
  • 2.修改MainActivity.java
 button1.setOnClickListener(new OnClickListener() {            
              @Override
              public void onClick(View v) {
                  //启动另一个Activity,(通过action属性进行查找)
                  Intent intent = new Intent();
                  //设置动作(实际action属性就是一个字符串标记而已)
                  intent.setAction("com.example.smyh006intent01.MY_ACTION"); //方法:Intent android.content.Intent.setAction(String action)
                  startActivity(intent);        
              }
         });
(4)data(数据):表示与动作要操纵的数据

Data属性是Android要访问的数据,和action和Category声明方式相同,也是在中。
多个组件匹配成功显示优先级高的; 相同显示列表。
Data是用一个uri对象来表示的,uri代表数据的地址,属于一种标识符。通常情况下,我们使用action+data属性的组合来描述一个意图:做什么

  • 使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。比如应用程序中需要展示一个网页,没有必要自己去实现一个浏览器(事实上也不太可能),而是只需要条用系统的浏览器来打开这个网页就行了。
    案例:实现打开指定网页
button1.setOnClickListener(new OnClickListener() {            
              @Override
              public void onClick(View v) {
                  Intent intent = new Intent();
                  intent.setAction(Intent.ACTION_VIEW);
                  Uri data = Uri.parse("http://www.baidu.com");
                  intent.setData(data);                
                  startActivity(intent);        
              }
         });
(5)type:对于data范例的描写

如果Intent对象中既包含Uri又包含Type,那么,在<intent-filter>中也必须二者都包含才能通过测试。
Type属性用于明确指定Data属性的数据类型或MIME类型,但是通常来说,当Intent不指定Data属性时,Type属性才会起作用,否则Android系统将会根据Data属性值来分析数据的类型,所以无需指定Type属性。
data和type属性一般只需要一个,通过setData方法会把type属性设置为null,相反设置setType方法会把data设置为null,如果想要两个属性同时设置,要使用Intent.setDataAndType()方法

  • data+type属性的使用 【实例】:播放指定路径的mp3文件。
button.setOnClickListener(new OnClickListener(){
              @Override
              public void onClick(View v) {
                  Intent intent = new Intent();
                  intent.setAction(Intent.ACTION_VIEW);
                  Uri data = Uri.parse("file:///storage/sdcard0/平凡之路.mp3");
                  //设置data+type属性
                  intent.setDataAndType(data, "audio/mp3"); //方法:Intent android.content.Intent.setDataAndType(Uri data, String type)
                  startActivity(intent);                
             }            
         });

(6)extras(扩展信息):扩展信息

是其它所有附加信息的集合。使用extras可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

  • 存入
public void gotoTargetActivity(View view) {  
     Intent intent = new Intent("com.scott.intent.action.TARGET");  
     Bundle bundle = new Bundle();  
     bundle.putInt("id", 0);  
     bundle.putString("name", "scott");  
     intent.putExtras(bundle);  
     startActivity(intent);  
     }  
  • 取出
Bundle bundle = intent.getExtras(); 
     int id = bundle.getInt("id"); 
     String name = bundle.getString("name"); 
(7)Flags(标志位):期望这个意图的运行模式

一个程序启动后系统会为这个程序分配一个task供其使用,另外同一个task里面可以拥有不同应用程序的activity。那么,同一个程序能不能拥有多个task?这就涉及到加载activity的启动模式,这个需要单独讲一下。

注:android中一组逻辑上在一起的activity被叫做task,自己认为可以理解成一个activity堆栈。