詳解Android中通過(guò)Intent類(lèi)實(shí)現(xiàn)組件間調(diào)用的方法
Intent是Android中用來(lái)調(diào)用其它組件的類(lèi),通過(guò)Intent,我們可以非常方便的調(diào)用Activity,Broadcast Receiver和Service。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
上面這段代碼可以用來(lái)調(diào)用第三方的Activity(啟動(dòng)第三方瀏覽器來(lái)打開(kāi)百度首頁(yè))。
Intent有隱式和顯式之分,上面的
Intent intent = new Intent(Intent.ACTION_VIEW);
所創(chuàng)建的intent被稱(chēng)為隱式Intent。構(gòu)建隱式Intent需要一個(gè)表示action的字符串(例如Intent.ACTION_VIEW,其值為" android.intent.action.VIEW"),Android會(huì)尋找能夠處理該action的Activity(在manifest文件中的該Activity下的intent-filter中聲明),并且調(diào)用他。
有時(shí)候可能多個(gè)Activity都聲明能夠處理某一個(gè)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,因此當(dāng)我們執(zhí)行以下代碼時(shí)
Intent intent = new Intent("com.abc.def");
startActivity(intent);
Activity1和Activity2都符合要求,Android將彈出"Complete Action Using"的對(duì)話框來(lái)讓用戶選擇一個(gè)要執(zhí)行的Activity。
值得注意的是,要想能夠匹配隱式Intent的調(diào)用,必須包含DEFAULT的category(就是<category android:name="android.intent.category.DEFAULT"/>),而若要匹配顯式Intent,則不需要該category。
對(duì)于隱式Intent,除了action之外,還可以提供多種信息來(lái)幫助Android選擇最佳匹配。還可以添加的其他信息包括:host,mimeType,path,pathPattern,pathPrefix,port,scheme。
例如為上面Activity2在manifest中的配置添加一個(gè)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符合
如果在創(chuàng)建Intent的時(shí)候,指明了要調(diào)用的類(lèi)(例如new Intent(xxActivity.this, xx.class),或者通過(guò)setComponent來(lái)指定),那么這樣的Intent被稱(chēng)為顯示Intent。
對(duì)于顯式Intent,因?yàn)樗呀?jīng)指明了要調(diào)用的具體的類(lèi),所以Android會(huì)忽略掉其action,category以及data屬性。(個(gè)人覺(jué)得顯示Intent調(diào)用比隱式的更快些)
Serializable vs Parcelable
Android 主要是通過(guò)Intent來(lái)實(shí)現(xiàn)組件之間的相互調(diào)用,同時(shí)還可以傳遞附加的數(shù)據(jù)。這些數(shù)據(jù)主要是存儲(chǔ)在Bundle之中(當(dāng)調(diào)用Intent.putExtras(Bundle)時(shí),Android會(huì)復(fù)制Bundle中的數(shù)據(jù),而不是引用,因此再修改Bundle中的數(shù)據(jù)并不會(huì)改變Intent中攜帶的數(shù)據(jù))。
Bundle之中可以存放基本數(shù)據(jù)類(lèi)型以及實(shí)現(xiàn)了Serializable或Parcelable接口的類(lèi)。
當(dāng)我們要向Bundle中存放一個(gè)類(lèi)Obj(包含兩個(gè)int成員的簡(jiǎn)單類(lèi)),可以讓它實(shí)現(xiàn)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 + "]";
}
}
我們可以通過(guò)intent.putExtra("obj", new Obj(1, 2));來(lái)將其放入intent中,然后通過(guò) obj = (Obj) intent.getSerializableExtra("obj");來(lái)將其取出。
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());
}
};
}
我們可以通過(guò)intent.putExtra("objpar", new ObjPar(1, 2));來(lái)將其放入intent中,然后通過(guò) objpar = (ObjPar) intent.getParcelableExtra("objpar"); 來(lái)將其取出。
以上是兩種向Bundle中存放Object對(duì)象的方法,明顯可以看出實(shí)現(xiàn)Serializable接口更加簡(jiǎn)單,因?yàn)樗且粋€(gè)標(biāo)記性的接口,并不需要實(shí)現(xiàn)某個(gè)具體方法。相比而言實(shí)現(xiàn)Parcelable接口就顯得相對(duì)復(fù)雜一些,但這樣帶來(lái)的好處是性能的大幅提高。這是因?yàn)楫?dāng)我們實(shí)現(xiàn)Serializable接口后,真正的序列化工作是由JDK來(lái)完成,他需要通過(guò)反射來(lái)獲取成員變量,因?yàn)榉瓷涞男阅懿⒉桓?,因此這種序列化方式速度慢。然而實(shí)現(xiàn)Parcelable接口時(shí),我們提供了該接口中定義方法的實(shí)現(xiàn)(writeToParcel實(shí)現(xiàn)序列化,createFromParcel實(shí)現(xiàn)反序列化),這就避免了反射的使用,因此這種方式速度快。
那么這兩種方式,性能差別有多大呢?下面是國(guó)外網(wǎng)站上的一個(gè)測(cè)試結(jié)果:Serializable耗時(shí)是Parcelable的10倍左右

- Android Jetpack導(dǎo)航組件Navigation創(chuàng)建使用詳解
- Android性能優(yōu)化之RecyclerView分頁(yè)加載組件功能詳解
- Android開(kāi)發(fā)組件化架構(gòu)設(shè)計(jì)原理到實(shí)戰(zhàn)
- Android開(kāi)發(fā)組件flutter的20個(gè)常用技巧示例總結(jié)
- Android開(kāi)發(fā)Jetpack組件DataBinding用例詳解
- Android開(kāi)發(fā)Jetpack組件WorkManager用例詳解
- Android開(kāi)發(fā)Jetpack組件Room用例講解
- Android開(kāi)發(fā)中父組件調(diào)用子組件方法demo
相關(guān)文章
關(guān)于Android Fragment對(duì)回退棧的詳細(xì)理解
這篇文章主要介紹了Android Fragment的回退棧示例詳細(xì)介紹的相關(guān)資料,在Android中Fragment回退棧是由Activity管理的,每個(gè)Activity都有自己的回退棧,其中保存了已經(jīng)停止(處于后臺(tái))的Fragment實(shí)例,需要的朋友可以參考下2016-12-12
Android自動(dòng)化獲取卡頓信息的實(shí)現(xiàn)方法
自動(dòng)化獲取卡頓信息就像給App裝 “行車(chē)記錄儀” —— 實(shí)時(shí)記錄主線程的“駕駛狀態(tài)”,一旦發(fā)現(xiàn)“急剎車(chē)”(卡頓),立刻保存現(xiàn)場(chǎng)(堆棧),事后回看錄像(日志)精準(zhǔn)定位問(wèn)題,本文給大家介紹了Android自動(dòng)化獲取卡頓信息的實(shí)現(xiàn)方法,需要的朋友可以參考下2025-02-02
Android常用三方庫(kù)混淆規(guī)則整理(小結(jié))
這篇文章主要介紹了Android常用三方庫(kù)混淆規(guī)則整理(小結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Android BottomSheet效果的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了Android BottomSheet效果的兩種實(shí)現(xiàn)方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Android賬號(hào)注冊(cè)實(shí)現(xiàn)點(diǎn)擊獲取驗(yàn)證碼倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Android賬號(hào)注冊(cè)過(guò)程中實(shí)現(xiàn)點(diǎn)擊獲取驗(yàn)證碼倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05
Android控件CardView實(shí)現(xiàn)卡片布局
這篇文章主要為大家詳細(xì)介紹了Android控件CardView實(shí)現(xiàn)卡片布局,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
Android通過(guò)json向MySQL中讀寫(xiě)數(shù)據(jù)的方法詳解【讀取篇】
這篇文章主要介紹了Android通過(guò)json向MySQL中讀寫(xiě)數(shù)據(jù)的方法,涉及Android解析json以及與php交互讀取mysql的方法,需要的朋友可以參考下2016-06-06

