1. 程式人生 > >Android實戰技巧:元件間通訊---Intent和IntentFilter

Android實戰技巧:元件間通訊---Intent和IntentFilter

Understanding Intent and IntentFilter--理解Intent和IntentFilter

Intent(意圖)在Android中是一個十分重要的元件,它是連線不同應用的橋樑和紐帶,也是讓元件級複用(Activity和 Service)成為可能的一個重要原因。Intent的使用分為二個方面一個是發出Intent,另一個則是接收Intent用官方的說法就是Intent Resolving。本主將對Intent和IntentFilter進行一些介紹。
Intent和IntentFilter是Android和一種訊息通訊機制,可以讓系統的元件之間進行通訊。資訊的載體就是Intent,它可以是一個要完成的動作請求,也可以一般性的訊息廣播,它可以由任意一個元件發出。訊息,也就是Intent,最終也是要被元件來進行處理和消化。訊息由元件發出,通常在訊息的裡面也會有會標記有目標元件的相關資訊,另外目標元件也需要告訴系統,哪些訊息是它所感興趣的,它需要設定一些過濾器,以過濾掉無關的訊息。
其實這裡就好比學校裡的廣播,廣播有時會播放通知,但有時也會播放要執行的動作,比如打掃衛生。訊息中通常都會說明訊息的目標物件,可能是計算機學院,可能是老師,也可能是英語系的人才需要關注。而每個人,或是學院組織,也只關心與他們有關的訊息,當然這裡就要他們自己去判斷哪些是與他們有關的訊息了。在Android當中訊息就是Intent,過濾器就是IntentFilter。發出訊息的元件可以在訊息中設定目標元件的相關資訊,目標元件也可以設定過濾器,然後系統會進行過濾,只把元件所感興趣的訊息,傳遞給元件。這裡假設讀者已經瞭解Intent和IntentFilter的基本使用方法,且並不會進行全面的介紹,如果不瞭解,可以先讀讀
官方文件
,這裡重點講講IntentFilter在使用時的一些注意事項。
Intent訊息機制通常有二種,一個是顯式Intent(Explicit Intent),另一個是隱式Intent(Implicit Intent)。
  • 顯式Intent--需要在Intent中明確指定目標元件,也就是在Intent中明確寫明目標元件的名稱(Component name),需要指定完整的包名和類名。因為對於本程式以外的其他應用程式,你很難知道它的元件名字,所以顯式的Intent通常用於應用程式內部通訊,更確切的說,顯示Intent是用於應用程式內部啟動元件,通常又是Activity或Service。還沒有見用顯式Intent來給BroadcastReceiver傳送廣播的。
  • 隱式Intent--也就是不在Intent中指定目標元件,在Intent中不能含有目標的名字。系統是根據其他的資訊,比如Data,Type和Category去尋找目標元件。
隱式Intent通常用於與應用程式外部的元件進行通訊。應用程式級別的元件複用也主要是靠隱式Intent來完成的。而IntentFilter也是隻有隱式Intent才用的著,顯式Intent都是直接把Intent傳遞給目標元件,根本不會理會元件的IntentFilter。

顯式Intent(Explicit Intent)

顯示Intent使用起來比較簡單,只需要在Intent中指定目標元件的名字即可,也就是通過Intent的方法設定Component屬性。如前所述,顯式Intent通常用於應用程式內部啟動Activity或Service。事實上,並不完全侷限在應用程式內部,對於外部應用的Activity和Service,也可以用顯式Intent來啟動,但你必須知道它們的名字。
設定元件的名字的方法有:
public Intent setComponent(ComponentName component); public Intent setClass(Context packageContext, Class<?> cls); public Intent setClassName (Context packageContext, String className); public Intent setClassName (String packageName, String className);事實上雖然設定的方法有這麼多,但Intent內部標識目標元件的屬性只有一個Component,所以這麼設定方法的目的也只是設定目標元件的Component,事實上有這麼多的方法原因在於ComponentName的構造是多過載了的。在解析Intent時,系統也是取得這個Component屬性,然後去啟動它。
ComponentName Intent.getComponent();
對於應用程式內部啟動Activity通常是這樣子設定Intent:
Intent i = new Intent(); // Select one of them i.setComponent(new ComponentName(getApplication(), ViewStubDemoActivity.class)); i.setComponent(new ComponentName(getApplication(), ViewStubDemoActivity.class.getName())); i.setComponent(new ComponentName(getApplication().getPackageName(), ViewStubDemoActivity.class.getName())); i.setClass(getApplication(), ViewStubDemoActivity.class); i.setClassName(getApplication(), ViewStubDemoActivity.class.getName()); i.setClassName(getApplication().getPackageName(), ViewStubDemoActivity.class.getName()); startActivity(i);因為應用程式內部的元件類,都是可以訪問到的,所以要儘可能少寫字串常量,以減少拼寫錯誤,如果一定要使用包名和類名,也要注意,類名必須是全稱,也就是從包名開始,如“com.hilton.networks.WifiManagerActivity"。
但是對於外部應用程式的Activity,通常只能通過以下方法:
Intent i = new Intent(); // select one of them i.setComponent(new ComponentName("com.hilton.networks", "com.hilton.networks.WifiManagerActivity")); i.setClassName("com.hilton.networks", "com.hilton.networks.WifiManagerActivity"); startActivity(i);首先,帶有Context為引數的是不能夠用的,因為通常你無法拿到其他應用程式的Context,你只能拿到你所在應用程式的Context,所以用你所在的應用程式的Context去啟動外部的Activity肯定會報錯的。其次,不參再像上面那樣通過Class.getName()去指定類名,你為你無法匯入外部的類,會有編譯錯誤的。另外,千萬要注意不要拼錯,否則會有RuntimeException丟擲的。
對於Service元件,也是一樣,Intent的寫法與Activity元件一致,但是對於BroadcastReceiver元件通常都用顯式Intent。

隱式Intent的訊息過濾器--IntentFilter

IntentFilter是用來解析隱式Intent(Implicit Intent)的,也就是說告訴系統你的元件(Activity, Service, BroadcastReceiver)能夠處理哪些隱式的Intent。在使用的時候我們通常是這樣子的:
<manifest ...> <receiver ...> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_ENABLED" /> <action android:name="android.appwidget.action.APPWIDGET_DISABLED" /> <action android:name="android.appwidget.action.APPWIDGET_DELETED" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_UNMOUNTED"/> <action android:name="android.intent.action.MEDIA_SHARED"/> <action android:name="android.intent.action.MEDIA_REMOVED"/> <action android:name="android.intent.action.MEDIA_EJECT"/> <data android:scheme="file" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/> <data android:scheme="package" /> </intent-filter> </receiver> </manifest>在Manifest中使用IntentFilter時要注意以下三點:
1. 千萬注意拼寫錯誤
這裡有一個需要十分小心和注意的地方那就是對於IntentFilter裡面的Action和Data字串常量不要寫錯,因為這個在編譯時是不會被檢查,在執行時又不會丟擲異常,如果你拼寫錯了,比如大小寫拼錯了,在編譯時和執行時都不會有錯誤,但是你的程式卻不能正常工作,你的程式無法收到相應的Intent。曾有一個同事在IntentFilter中寫了一些Action,但把其中一個的大小寫拼錯了,結果花了他一個下午的時間來除錯,最後還是另外一個同事到他那聊天才發現了是大小寫的拼寫錯誤。
這裡也可以發現Android在Manifest檔案中的IntentFilter這塊的封裝性很差。如果,僅僅是如果,這些Action常量也可以通過引用的方式來寫,就可以在編譯時做些檢查和匹配,可以大大的減少出錯的機率,同時也加強了封裝和資訊隱藏。比如,對於上面的可以寫成這樣:
<manifest ...> <receiver ...> <intent-filter> <action android:name="@android:action/AppWidgetManager.APPWIDGET_UPDATE" /> <action android:name="@android:action/AppWidgetManager.APPWIDGET_ENABLED" /> <action android:name="@android:action/AppWidgetManager.APPWIDGET_DISABLED" /> <action android:name="@android:action/AppWidgetManager.APPWIDGET_DELETED" /> </intent-filter> </receiver> </manifest>雖然這種拼寫錯誤很低階,但是因為它低階所以當程式不能正常工作時沒有人會想到是因為拼寫錯誤,所以這種拼寫錯誤通常會耗費不少的除錯時間。另外一種避免此種錯誤的方法就是在程式碼中通過Context.registerReceiver(BroadcastReceiver,IntentFilter)來註冊BroadcastReceiver,就可以直接寫入常量,而非具體字串。但這隻能是接收Broadcast的時候,對於那些想作為公開介面的元件,還是需要在Manifest裡面宣告,比如Email,它要能處理Intent.ACTION_SEND_TO,就需要在Manifest中宣告。2. 要注意Data欄位除了上面討論的之外,對於IntentFilter還有另外的一點需要注意,就是對於某些Action是需要加上Data欄位資訊,否則有可能接收不到。比如:
<manifest ...> <receiver ...> <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_UNMOUNTED"/> <action android:name="android.intent.action.MEDIA_SHARED"/> <action android:name="android.intent.action.MEDIA_REMOVED"/> <action android:name="android.intent.action.MEDIA_EJECT"/> <data android:scheme="file" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/> <data android:scheme="package" /> </intent-filter> </receiver> </manifest>對於手機外部儲存卡的狀態變化的Broadcast,在註冊監聽器的時候就需要加上DataScheme,否則就會接收不到。這個也花費了我幾個小時的除錯時間,改在程式碼中用Context.registerReceiver(BroadcastReceiver,IntentFilter)註冊也不行,最後參考了Music中的做法,加上了DataScheme才能在onReceive()中接收到Intent。同樣對於後面的Package相關的Broadcast,也是要加上DataScheme否則也是接收不到Broadcast。可悲的是對於像這樣的系統公共的Broadcast
Intent,在Intent的文件中並沒有說明如何使用,如果沒有參考事例,相信需要一定的時間才能夠找出為什麼接收不到Intent。
除了DataScheme還有一個是MimeType,這個對於系統公共介面是必須加上的,比如Email要處理Intent.ACTION_SENTTO,就需要這樣宣告:
<manifest ...> <activity android:name="EmailComposer"> <intent-filter> <action android:name="android.intent.action.SEND"/> <data android:mimeType="image/*" /> </intent-filter> </activity> </manifest>3. 同時也要注意Category欄位
如果沒有對IntentFilter寫正確的Category欄位,也是收不到Intent。比如:
<manifest ...> <receiver ...> <intent-filter> <action android:name="com.hilton.controlpanel.action.BUTTON_ACTION" /> <category android:name="com.hilton.controlpanel.category.SELF_MAINTAIN" /> </intent-filter> </receiver> </manifest>如果把Category去掉,死活也接收不到Intent,當然這要取決於Intent是如何發出的,如果Intent發出時沒有加Category,那就沒有必須在IntentFilter加上Category。
總之,對於Intent,要保證發出和接收完全一致,否則系統就無法找到相應的匹配,程式也就無法接收Intent。
有關於 DEFAULT category,也要注意,如果是針對Activity的Implicit Intent隱式Intent,如果在沒有其他Category的情況下,一定要加上DEFAULT Category。因為系統會在Context.startActivity(Intent)和Context.startActivityForResult(
Intent)時給Intent加上DEFAULT category。而對於Context.sendBroadcast(Intent),Context.sendOrderedBroadcast(Intent),Contxt.sendStickyBroadcast(Intent)和Context.bindService(Intent)Context.startService(Intent)就不會加DEFAULT Category。
另外要注意,儘量把Action進行合併寫進一個IntentFilter中。因為對於每個IntentFilter標籤都會建立一個IntentFilter物件,所以如果寫幾個就會有幾個物件在那,不但耗費資源而且在匹配的時候也會耗費更多的時間,因為在查詢匹配的時候是要一個IntentFilter物件接著一個IntentFilter物件進行檢查的。直到找到最佳匹配或是到所有的IntentFilter都檢查完為止。

IntentFilter的匹配規則

1. 通過Action欄位來匹配這個是Intent中比較基本的一個欄位,也比較簡單,就是一個字串,如果相等就匹配成功,否則證明還沒找到目標。但要注意,如果IntentFilter沒有指定Action,那麼它不會匹配到任何的隱式Intent,它只能被顯式的Intent匹配上。反過來,如果Intent自己沒有指定Action,那麼它能匹配上含有任何Action的IntentFilter,但不能匹配上沒有指定Action的IntentFilter。對於Action,平時要注意拼寫錯誤,因為在AndroidManifest檔案中宣告Action都是字串,並且在編譯時不會做檢查,執行時,如果Action拼錯了導致匹配不上,要麼是程式不能正常工作,要麼會有異常丟擲。

2. 通過Category欄位來匹配對於Activity來講,如果想處理隱式Intent,並且除了Intent.ACTION_MAIN以外,必須指定Category為DEFAULT,否則不會被匹配到。因為Context.startActivity()和Context.startActivityForResult()會自動加上DEFAULT Category。其他情況,Service和BroadcastReceiver則不會,對於Service和BroadcastReceiver,如果Intent中沒有指定Category,那麼在其IntentFilter中也不必指定。

3. 通過Data欄位來匹配這個相對來講比較複雜,通常Data包含uri, scheme(content, file, http)和type(mimeType)對於Intent來講有二個方法:

Intent.setData(Uri); //一個Uri,Scheme包含在其中 Intent.setType(String); //指定MimeType,比如'image/jpeg', 'audio/mpeg'等 Intent.setDataAndType(Uri, String); //上面二個方法的簡便呼叫方式,一起搞進去對於IntentFilter來講,需要設定的是Scheme和Type,Scheme是對Uri的限制,目標需要限制Scheme是因為Scheme能告訴目錄能從哪裡拿到Uri所指向的檔案,Type是MimeType對型別的限制。
<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="content" android:mimeType="image/*" /> </intent-filter>Data匹配時的規則一共有四條:
a.如果Intent沒有指定Data相關的欄位,只能匹配上沒有指定Data的IntentFilter。也就是說如果一個Intent沒有指定任何的Data(Uri和Type),它只能匹配到沒有指定任何Data(Scheme和Type)的IntentFilter。
b.如果一個Intent只指定了Uri但是沒有Type(並且Type也不能夠從Uri中分析出)只能匹配到僅指定了相應Scheme且沒有指定Type的IntentFilter。實際的例子有如果一個Intent是想要發郵件,或是打電話,它們的Intent是類似這樣的:"mailto:[email protected]"和"tel:1234567"。換句話說,這些Uri本身就是資料,而不再是一個指向資料的地址。比如:Phone中的Dialer就有如下的IntentFilter:

<intent-filter> <action android:name="android.intent.action.CALL" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="tel" /> </intent-filter>
再如,要處理SD狀態變化的IntentFilter:

<intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_UNMOUNTED"/> <action android:name="android.intent.action.MEDIA_SHARED"/> <action android:name="android.intent.action.MEDIA_REMOVED"/> <action android:name="android.intent.action.MEDIA_EJECT"/> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" /> </intent-filter>
再如,要處理Package狀態變化的IntentFilter:

<intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="package" /> <intent-filter>
但是注意,對於想對資料進行操作的Intent,最好不要只指定Uri,而不指定型別。因為如果這樣做通常會匹配到一大堆
c. 如果一個Intent只指定了Type,但是沒有指定Uri,它只能匹配到只指定了相應Type且沒有指定Scheme的IntentFitler
d. 如果一個Intent即有Uri又有Type,那麼它會匹配上:1).Uri和Type都匹配的IntentFilter;2).首先Type要匹配,另外如果Intent的Uri是content:或file:,且IntentFilter沒有指定Scheme的IntentFilter。因為對於Android來講content和file這二種Scheme是系統最常見也是用的最多的,所以就當成預設值來對待。
另外需要注意,Type,因為是MimeType,所以是允許使用萬用字元的,比如'image/*',能匹配上所有以'image'為開頭的型別,也說是說能匹配上所有的影象。

根據Data匹配的例子

假如系統中有四個Activity,A的IntentFilter是這樣子的:
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="content" android:mimeType="image/*" /> </intent-filter> </activity>這表明A可以傳送一切圖片型別,並且內容必須是由ContentProvider提供的,也就是Uri必須是以"content://"開頭的
而另外一個Activity B是這樣子宣告的:
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="file" android:mimeType="image/*" /> </intent-filter> </activity>這表明B可以傳送一切圖片,但內容必須是單獨的一個檔案,也就是Uri必須是由"file://"開頭的
還有一個C是這樣子宣告的:
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>這表明C只能接收那些沒有指定任何Uri和Type的Action是SEND的Intent。
而D是這樣子宣告的:
<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> </activity>這表明D可以傳送一切圖片,無論是資料庫內的(content),還是單獨的檔案(file)。
如果一個Intent是這樣寫的:
Intent share = new Intent(Intent.ACTION_SEND); startActivity(share);那麼它只能匹配C,因為C沒有指定資料和型別,Action是SEND,根據規則a,它只能匹配Activity A。但如果給Intent加上額外的條件
share.setDataAndType(uri,"image/jpeg");那麼如果uri是資料庫內容,它會匹配到A,如果它是一個檔案,會匹配到B。但無論是content還是file都會匹配到D,因為它能處理以任何形式儲存的圖片。但始終不會匹配到C,因為C沒有宣告Data欄位,所以不會匹配上。
所以,通常想把元件作為系統公用介面時都是這樣子來寫:
<activity ...> <intent-filter> <!-- implement public actions such as View, Edit, Pick or Send --> <action android:name="android.intent.action.SEND" /> <!-- never forget default category, otherwise your activity never receives intents --> <category android:name="android.intent.category.DEFAULT" /> <!-- specify mimeType to constrain data type, receive data from both content provider and file --> <data android:mimeType="image/*" /> <!-- specify scheme to constrain data source, if necessary --> <data android:shceme="http" /> </intent-filter> </activity>Intent和IntentFilter對於元件Activity來講注意事項比較多,但是對於Service和BroadcastReceiver來說就沒有那麼多的注意事項了,因為對於Service和BroadcastReceiver通常都不用設定Category和Data。但也有例外,比如前面所講到的SD相關廣播和應用程式安裝相關廣播。
另外要注意,如果使用Context.startActivity()或Context.startActivityForResult(),Context.bindService()和Context.startService(),如果系統沒有為Intent匹配到目標Activity和Service那麼會有RuntimeException(ActivityNotFoundException)丟擲;如果有多個目標同時匹配,會以列表的方式來讓使用者選擇使用哪個。

使用IntentFilter匹配來進行查詢可用的元件

Intent和IntentFilter不但可以用來進行元件複用,還可以用於查詢系統內都有哪裡元件能做哪些事情。比如Launcher上面會列出很多的應用,其實這種說法不準確,應該是上面列出了所有的能啟動一個應用的元件(比如,Dialer和Contacts同屬於一個應用程式Contacts中,但是在Launcher裡面卻有二個,一個是Dialer一個是Contacts。那麼Launcher是如何做到的呢?它不可能是去檢查系統檔案,看看哪些應用程式檔案存在,然後再列出來。它是通過查詢Intent的方式,把所有含有"android.intent.action.MAIN"和"android.intent.category. LAUNCHER"的Activity的相關資訊都取出來,然後列出它們的名稱和Icon。同樣,我們也可這樣來獲得具體相應特徵的元件,具體的請參考SDK中的一篇文章(Resources->Articles->Can I Use this Intent?),講的很詳細,且有Sample Code。

相關推薦

Android實戰技巧元件通訊---IntentIntentFilter

Understanding Intent and IntentFilter--理解Intent和IntentFilter Intent(意圖)在Android中是一個十分重要的元件,它是連線不同應用的橋樑和紐帶,也是讓元件級複用(Activity和 Service)成為可能的

Android實戰技巧ViewStub的應用

       在開發應用程式的時候,經常會遇到這樣的情況,會在執行時動態根據條件來決定顯示哪個View或某個佈局。那麼最通常的想法就是把可能用到的View都寫在上面,先把它們的可見性都設為View.GONE,然後在程式碼中動態的更改它的可見性。這樣的做法的優點是邏輯簡單而且

Android實戰技巧用TextView實現Rich Text---在同一個TextView中設定不同的字型風格

背景介紹 在開發應用過程中經常會遇到顯示一些不同的字型風格的資訊猶如預設的LockScreen上面的時間和充電資訊。對於類似的情況,可能第一反應就是用不同的多個TextView來實現,對於每個TextView設定不同的字型風格以滿足需求。 這裡推薦的做法是使用android

Android實戰技巧為從右向左語言定義複雜字串,程式碼xml設定

程式碼方式,一般是放在一個Utils.java作為公共方法 /// add by xxx.zhou for ArabicRTL support 20141024 begin public static boolean isContainEG_I

Android實戰技巧之四十九Usb通訊之USB Host

零 USB背景知識 USB是一種資料通訊方式,也是一種資料匯流排,而且是最複雜的匯流排之一。 硬體上,它是用插頭連線。一邊是公頭(plug),一邊是母頭(receptacle)。例如,PC上的插座就是母頭,USB裝置使用公頭與PC連線。 目前USB硬體介面

Android元件通訊--深入理解IntentIntentFilter

Understanding Intent and IntentFilter--理解Intent和IntentFilterIntent(意圖)在Android中是一個十分重要的元件,它是連線不同應用的橋樑和紐帶,也是讓元件級複用(Activity和 Service)成為可能的一個重要原因。Intent的使用分為

Android實戰技巧之三十八Handler使用中可能引發的內存泄漏

sha 指向 ons har 引用 destroy 對象 from weak 問題描寫敘述 曾幾何時,我們用原來的辦法使用Handler時會有以下一段溫馨的提示: This Handler class should be static or le

Android Service、IntentService,Service元件通訊

Service元件 Service 和Activity 一樣同為Android 的四大元件之一,並且他們都有各自的生命週期,要想掌握Service 的用法,那就要了解Service 的生命週期有哪些方法,並且生命週期中各個方法回撥的時機和作用 什麼是service?service的基本概念 Servic

Android實戰技巧之四十Android5.1.1原始碼編譯與燒寫

購買Nexus手機的朋友大多是為了自己修改系統玩,再加上其較高的價效比,在開發者中還是廣受歡迎的。我的5太子被我升級到了6.0預覽版,玩的正嗨,捨不得換回到5.1時代了。不過鑑於距6.0原始碼釋出還有段日子,5.1的原始碼編譯與燒寫仍是主流,下面就記錄了整個過程

Android實戰技巧之九最新Android開發環境(Eclipse+ADT+Android 5.0)

一、一切由執行時錯誤引起dalvikvm Could not find class '引用包.類', referenced from method... 其實在編譯時也會見到如下錯誤:       [dx]        [dx] trouble processing:   

Android實戰技巧之三十五瞭解native activity

1.native activity的意義 很多人覺得Android的Fwk提供的支援足夠好了,既然Google不推薦用Ndk開發為什麼又放寬Ndk的限制而推出可以無Java開發Android App呢?我的理解是不同的技術實現會有其適合的場景。 Ndk的適用

使用Event Bus模式解耦Android App元件通訊

當一個Android應用功能越來越多的時候,保證應用的各個部分之間高效的通訊將變得越來越困難。 在應用中的多個地方,控制元件經常需要根據某個狀態來更新他們顯示的內容。這種場景常見的解決方式就是定義一個介面,需要關注該事件的控制元件來實現這個介面。然後事件觸發的地方來註冊/取消註冊這些對該事件感興趣的控制

Android元件通訊——EventBus

    在Android開發中,元件間通訊一直是一個不可忽視的部分。當然,元件之間的通訊有很多種方式可以選擇,本文就利用EventBus通訊的方式進行論述。 EventBus是一個第三方框架,它的簡單使用分為如下幾步:     1. 下載框架原始碼,並匯入工程中。   

android元件信使--Intent之Action屬性

Action是指Intent要完成的動作,是一個字串常量。在Intent類裡面定義了大量的Action常量屬性,例如:ACTION_CALL(打電話)、ACTION_EDIT(編輯資料)、ACTION_BATTERY_LOW(低電量廣播action)等。我們也可以自定義Ac

Android實戰技巧之二十一Android原型設計工具探索

移動開發者、移動產品經理和互動設計師在有了產品的想法後會做出一系列的草圖,然後反覆推敲改進,直到自己滿意。這個草圖就是原型設計,是產品設計初期很重要的工作,它是產品的雛形,之後會以此為原型進行開發。 當移動網際網路熱度增加後,一些主打移動原型設計的工具如雨後春

Android實戰技巧之三十七圖片的Base64編解碼

通常用Base64這種編解碼方式將二進位制資料轉換成可見的字串格式,就是我們常說的大串,10塊錢一串的那種,^_^。 Android的android.util包下直接提供了一個功能十分完備的Base64類供我們使用,下面就演示一下如何將一張圖片進行Base64

Android實戰技巧之一文字與佈局(字串變數在資源裡替換)

//別看這個標題挺大,其實這次要說的只是3個小技巧。 //2014.11.7 update 1、字串資源裡變數替換 工作中是拒絕硬編碼的,Android裡會把一些字串等放在xml中當做資源使用,如專案中values下的strings.xml列出了app_name.

Android 架構分層中的模組、元件、外掛,元件通訊(路由等)

模組化、元件化、外掛化。 計算機界有一句名言:“電腦科學領域的任何問題都可以通過增加一箇中間層來解決。-- 頁面元件化的設計思路是:  1.將頁面拆分為粒度更小的元件,元件內部除了包含UI實現,還包含資料層和邏輯層;  2.元件提供個性化配置滿足兩端差異需求,如果無法滿足再

Android 框架煉成 教你如何寫元件通訊框架EventBus

轉載請標明出處:1、概述首先我們回顧一下,這玩意就是在register時,掃描類中複合命名規範的方法,存到一個map,然後post的時候,查詢到匹配的方法,反射呼叫;好,那麼根據這一句話,我們就開始編寫框架之旅~~~2、依然是原來的配方1、ItemListFragmentpa

Android程序通訊互動

Intent 的 ComponentName Intent作為我們最常用的資料傳輸渠道,特別是通過Intent開啟一個Activity,想必每個人都不會陌生。通常我們用到的都是通過Intent開啟同一個程序(App)內部的Activity,如果想實現