詳解Android中通過Intent類實現(xiàn)組件間調(diào)用的方法
Intent是Android中用來調(diào)用其它組件的類,通過Intent,我們可以非常方便的調(diào)用Activity,Broadcast Receiver和Service。
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com")); startActivity(intent);
上面這段代碼可以用來調(diào)用第三方的Activity(啟動第三方瀏覽器來打開百度首頁)。
Intent有隱式和顯式之分,上面的
Intent intent = new Intent(Intent.ACTION_VIEW);
所創(chuàng)建的intent被稱為隱式Intent。構(gòu)建隱式Intent需要一個表示action的字符串(例如Intent.ACTION_VIEW,其值為" android.intent.action.VIEW"),Android會尋找能夠處理該action的Activity(在manifest文件中的該Activity下的intent-filter中聲明),并且調(diào)用他。
有時候可能多個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,因此當(dāng)我們執(zhí)行以下代碼時
Intent intent = new Intent("com.abc.def"); startActivity(intent);
Activity1和Activity2都符合要求,Android將彈出"Complete Action Using"的對話框來讓用戶選擇一個要執(zhí)行的Activity。
值得注意的是,要想能夠匹配隱式Intent的調(diào)用,必須包含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符合
如果在創(chuàng)建Intent的時候,指明了要調(diào)用的類(例如new Intent(xxActivity.this, xx.class),或者通過setComponent來指定),那么這樣的Intent被稱為顯示Intent。
對于顯式Intent,因為他已經(jīng)指明了要調(diào)用的具體的類,所以Android會忽略掉其action,category以及data屬性。(個人覺得顯示Intent調(diào)用比隱式的更快些)
Serializable vs Parcelable
Android 主要是通過Intent來實現(xiàn)組件之間的相互調(diào)用,同時還可以傳遞附加的數(shù)據(jù)。這些數(shù)據(jù)主要是存儲在Bundle之中(當(dāng)調(diào)用Intent.putExtras(Bundle)時,Android會復(fù)制Bundle中的數(shù)據(jù),而不是引用,因此再修改Bundle中的數(shù)據(jù)并不會改變Intent中攜帶的數(shù)據(jù))。
Bundle之中可以存放基本數(shù)據(jù)類型以及實現(xiàn)了Serializable或Parcelable接口的類。
當(dāng)我們要向Bundle中存放一個類Obj(包含兩個int成員的簡單類),可以讓它實現(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 + "]"; } }
我們可以通過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對象的方法,明顯可以看出實現(xiàn)Serializable接口更加簡單,因為他是一個標記性的接口,并不需要實現(xiàn)某個具體方法。相比而言實現(xiàn)Parcelable接口就顯得相對復(fù)雜一些,但這樣帶來的好處是性能的大幅提高。這是因為當(dāng)我們實現(xiàn)Serializable接口后,真正的序列化工作是由JDK來完成,他需要通過反射來獲取成員變量,因為反射的性能并不高,因此這種序列化方式速度慢。然而實現(xiàn)Parcelable接口時,我們提供了該接口中定義方法的實現(xiàn)(writeToParcel實現(xiàn)序列化,createFromParcel實現(xiàn)反序列化),這就避免了反射的使用,因此這種方式速度快。
那么這兩種方式,性能差別有多大呢?下面是國外網(wǎng)站上的一個測試結(jié)果:Serializable耗時是Parcelable的10倍左右
- Android Jetpack導(dǎo)航組件Navigation創(chuàng)建使用詳解
- Android性能優(yōu)化之RecyclerView分頁加載組件功能詳解
- Android開發(fā)組件化架構(gòu)設(shè)計原理到實戰(zhàn)
- Android開發(fā)組件flutter的20個常用技巧示例總結(jié)
- Android開發(fā)Jetpack組件DataBinding用例詳解
- Android開發(fā)Jetpack組件WorkManager用例詳解
- Android開發(fā)Jetpack組件Room用例講解
- Android開發(fā)中父組件調(diào)用子組件方法demo
相關(guān)文章
Android中隱藏狀態(tài)欄和標題欄的方法匯總(隱藏狀態(tài)欄、標題欄的五種方法)
這篇文章主要介紹了Android中隱藏狀態(tài)欄和標題欄的方法匯總(隱藏狀態(tài)欄、標題欄的五種方法),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02android 獲取手機內(nèi)存及 內(nèi)存可用空間的方法
下面小編就為大家?guī)硪黄猘ndroid 獲取手機內(nèi)存及SD卡內(nèi)存可用空間的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03在android開發(fā)中進行數(shù)據(jù)存儲與訪問的多種方式介紹
很多時候我們的軟件需要對處理后的數(shù)據(jù)進行存儲或再次訪問,Android為數(shù)據(jù)存儲提供了多種方式,首先給大家介紹使用文件如何對數(shù)據(jù)進行存儲,感興趣的朋友可以了解下哈2013-06-06Android的Fragment的生命周期各狀態(tài)和回調(diào)函數(shù)使用
這篇文章主要介紹了Android的Fragments的生命周期各狀態(tài)和回調(diào)函數(shù)使用,Fragments的生命周期與Activity息息相關(guān),需要的朋友可以參考下2016-02-02Android旋轉(zhuǎn)、平移、縮放和透明度漸變的補間動畫
這篇文章主要實現(xiàn)Android旋轉(zhuǎn)、平移、縮放和透明度漸變的補間動畫,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2018-04-04Android實現(xiàn)長按back鍵退出應(yīng)用程序的方法
這篇文章主要介紹了Android實現(xiàn)長按back鍵退出應(yīng)用程序的方法,實例分析了Android按鈕事件的操作技巧,需要的朋友可以參考下2015-05-05