首页 > 系统 > Android > 正文

详解Android中通过Intent类实现组件间调用的方法

2019-12-12 06:22:54
字体:
来源:转载
供稿:网友

Intent是Android中用来调用其它组件的类,通过Intent,我们可以非常方便的调用Activity,Broadcast Receiver和Service。

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);

上面这段代码可以用来调用第三方的Activity(启动第三方浏览器来打开百度首页)。
Intent有隐式和显式之分,上面的

Intent intent = new Intent(Intent.ACTION_VIEW);

所创建的intent被称为隐式Intent。构建隐式Intent需要一个表示action的字符串(例如Intent.ACTION_VIEW,其值为" android.intent.action.VIEW"),Android会寻找能够处理该action的Activity(在manifest文件中的该Activity下的intent-filter中声明),并且调用他。
有时候可能多个Activity都声明能够处理某一个action,例如:

<activity  android:name=".Activity1">  <intent-filter>    <action android:name="com.abc.def" />    <category android:name="android.intent.category.DEFAULT" />  </intent-filter></activity><activity  android:name=".Activity2">  <intent-filter>    <action android:name="com.abc.def" />    <category android:name="android.intent.category.DEFAULT" />  </intent-filter></activity>

上面Activity1和Activity2都声明能够处理“com.abc.def”的action,因此当我们执行以下代码时

Intent intent = new Intent("com.abc.def");startActivity(intent);

Activity1和Activity2都符合要求,Android将弹出"Complete Action Using"的对话框来让用户选择一个要执行的Activity。

值得注意的是,要想能够匹配隐式Intent的调用,必须包含DEFAULT的category(就是<category android:name="android.intent.category.DEFAULT"/>),而若要匹配显式Intent,则不需要该category。

对于隐式Intent,除了action之外,还可以提供多种信息来帮助Android选择最佳匹配。还可以添加的其他信息包括:host,mimeType,path,pathPattern,pathPrefix,port,scheme。

例如为上面Activity2在manifest中的配置添加一个mimeType的属性:

<activity  android:name=".Activity2">  <intent-filter>    <action android:name="com.abc.def" />    <category android:name="android.intent.category.DEFAULT" />    <data android:mimeType="abc/def"/>  </intent-filter></activity>

那么:

Intent intent = new Intent("com.abc.def");startActivity(intent);//只有Activity1符合/********************************************/Intent intent = new Intent("com.abc.def");intent.setType("abc/def");startActivity(intent);//只有Activity2符合

如果在创建Intent的时候,指明了要调用的类(例如new Intent(xxActivity.this, xx.class),或者通过setComponent来指定),那么这样的Intent被称为显示Intent。

对于显式Intent,因为他已经指明了要调用的具体的类,所以Android会忽略掉其action,category以及data属性。(个人觉得显示Intent调用比隐式的更快些)

Serializable vs Parcelable
Android 主要是通过Intent来实现组件之间的相互调用,同时还可以传递附加的数据。这些数据主要是存储在Bundle之中(当调用Intent.putExtras(Bundle)时,Android会复制Bundle中的数据,而不是引用,因此再修改Bundle中的数据并不会改变Intent中携带的数据)。

Bundle之中可以存放基本数据类型以及实现了Serializable或Parcelable接口的类。

当我们要向Bundle中存放一个类Obj(包含两个int成员的简单类),可以让它实现Serializable或Parcelable接口,如下所示:

1.Serializable


public class Obj implements Serializable {  private int a;  private int b;  public Obj(int a, int b) {    this.a = a;    this.b = b;  }    @Override  public String toString() {    return "Obj: [" + a + ", " + b + "]";  }}

我们可以通过intent.putExtra("obj", new Obj(1, 2));来将其放入intent中,然后通过 obj = (Obj) intent.getSerializableExtra("obj");来将其取出。
2.Parcelable


public class ObjPar implements Parcelable {  private int a;  private int b;  public ObjPar(int a, int b) {    this.a = a;    this.b = b;  }    @Override  public String toString() {    return "Obj: [" + a + ", " + b + "]";  }  @Override  public int describeContents() {    return 0;  }  @Override  public void writeToParcel(Parcel dest, int flags) {    dest.writeInt(a);    dest.writeInt(b);  }    public static final Parcelable.Creator<ObjPar> CREATOR = new Creator<ObjPar>() {        @Override    public ObjPar[] newArray(int size) {      return new ObjPar[size];    }        @Override    public ObjPar createFromParcel(Parcel source) {            return new ObjPar(source.readInt(), source.readInt());    }  };}

我们可以通过intent.putExtra("objpar", new ObjPar(1, 2));来将其放入intent中,然后通过 objpar =  (ObjPar) intent.getParcelableExtra("objpar"); 来将其取出。
以上是两种向Bundle中存放Object对象的方法,明显可以看出实现Serializable接口更加简单,因为他是一个标记性的接口,并不需要实现某个具体方法。相比而言实现Parcelable接口就显得相对复杂一些,但这样带来的好处是性能的大幅提高。这是因为当我们实现Serializable接口后,真正的序列化工作是由JDK来完成,他需要通过反射来获取成员变量,因为反射的性能并不高,因此这种序列化方式速度慢。然而实现Parcelable接口时,我们提供了该接口中定义方法的实现(writeToParcel实现序列化,createFromParcel实现反序列化),这就避免了反射的使用,因此这种方式速度快。

那么这两种方式,性能差别有多大呢?下面是国外网站上的一个测试结果:Serializable耗时是Parcelable的10倍左右

 2016520152123213.png (761×1002)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表