RemoteViews的應(yīng)用
RemoteViews表示的是一個(gè)View結(jié)構(gòu),它可以在其他進(jìn)程中顯示。
RemoteViews在通知欄的應(yīng)用
通過RemoteViews加載布局文件可以實(shí)現(xiàn)自定義通知效果。更新RemoteViews時(shí),無法直接訪問里面的View,必須通過RemoteViews所提供的一系列方法來更新View。
//設(shè)置TextView的文本
remoteViews.setTextViewText(R.id.text, "this is content.");
//設(shè)置ImageView的圖片
remoteViews.setImageViewResource(R.id.icon, R.drawable.icon);
//設(shè)置點(diǎn)擊事件
remoteViews.setOnClickPendingIntent(int viewId, PendingIntent pendingIntent);
emoteViews在桌面小部件上的應(yīng)用
AppWidgetProvider是Android中提供的用于實(shí)現(xiàn)桌面小部件的類,繼承BroadcastReceiver,其本質(zhì)是一個(gè)BroadcastReceiver。
桌面小部件的開發(fā)分為如下幾個(gè)步驟:
- 定義小部件界面
在res/layout目錄下新建一個(gè)布局文件
- 定義小部件的配置信息
在res/xml目錄下新建一個(gè)xml文件,內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget"
android:minWidth="60dp"
android:minHeight="60dp"
android:updatePeriodMillis="3600000"
/>
定義小部件的實(shí)現(xiàn)類
在AndroidMainifest.xml中聲明小部件
PendingIntent概述
PendingIntent表示在將來的某個(gè)時(shí)刻發(fā)生,Intent是立即發(fā)生。
PendingIntent的匹配規(guī)則:如果兩個(gè)PendingIntent它們內(nèi)部的Intent相同并且requestCode也相同,那么這兩個(gè)PendingIntent就是相同的(如果兩個(gè)Intent的ComponentName和intent-filter都相同,那么這兩個(gè)Intent就是相同的,Extras不參與Intent匹配)。
flags的類型:
- FLAG_NO_CREAT
PendingIntent不會(huì)主動(dòng)創(chuàng)建,如果當(dāng)前PendingIntent之前不存在,那么getActivity、getService、getBroadcast方法返回null。這個(gè)標(biāo)記位實(shí)際開發(fā)中很少見,它無法單獨(dú)使用。 - FLAG_ONE_SHOT
PendingIntent只能使用一次,然后它會(huì)自動(dòng)cancel,如果后續(xù)還有相同的PendingIntent,那么它們的send方法會(huì)調(diào)用失敗。 - FLAG_CANCEL_CURRENT
PendingIntent如果已經(jīng)存在,那么它們會(huì)被cancel,然后創(chuàng)建一個(gè)新的PendingIntent。 - FLAG_UPDATE_CURRENT
PendingIntent如果已經(jīng)存在,那么它們會(huì)被更新,即它們的Intent中的Extras會(huì)被替換成最新的。
下面結(jié)合通知欄消息來闡述這幾個(gè)標(biāo)志位的用途。
NotificationManager.notify(int id, Notification notification)
如果notify方法的參數(shù)id相同,那么多次調(diào)用notify方法只能彈出一條通知,后續(xù)的通知會(huì)替換前面的通知;如果參數(shù)id不同,那么多次調(diào)用notify方法會(huì)彈出多條通知,這種情況下,如果PendingIntent匹配,分以下幾種情況:
- FLAG_ONE_SHOT
后續(xù)通知中的PendingIntent會(huì)和第一條通知保持完全一致(包括Extras),單擊任何一條通知后。剩余的通知均無法打開 - FLAG_CANCEL_CURRENT
只有最新的通知才可以打開,之前彈出的通知均無法打開 - FLAG_UPDATE_CURRENT
之前彈出的通知中的PendingIntent被更新(包括Extras),這些通知都是可以打開的
RemoteViews的內(nèi)部機(jī)制
1、RemoteViews會(huì)通過Binder傳遞到SystemServer進(jìn)程,系統(tǒng)通過LayoutInflater加載RemoteViews布局。
2、SystemServer更新View。set方法對(duì)View的更新不會(huì)立即執(zhí)行,RemoteViews內(nèi)部記錄所有的更新View的操作,RemoteViews加載后才會(huì)執(zhí)行這些更新操作。
Android系統(tǒng)并沒有通過Binder去直接支持View的跨進(jìn)程訪問,而是通過將View的操作封裝到Action對(duì)象中,并把Action對(duì)象被傳遞到遠(yuǎn)程進(jìn)程來執(zhí)行具體的操作。這樣做的好處就是:
1、不需要定義大量Binder接口
2、通過在遠(yuǎn)程進(jìn)程批量執(zhí)行RemoteViews的更新操作,避免了大量的IPC操作,提高了應(yīng)用的性能。