一.RemoteViews的應(yīng)用
RemoteViews的概念:RemoteViews就是一種在其他進(jìn)程中顯示的View丢间,在實際開發(fā)中它主要是用在通知欄和桌面小部件的開發(fā)過程中临扮。
1.RemoteViews在通知欄上的應(yīng)用
當(dāng)我們需要正在通知欄中自定義通知時获枝,我們可以先提供一個布局文件冒黑,然后通過RemoteViews來加載這個布局文件即可改變通知的樣式:
Notification notification = new Notification();
notification.icon = R.drawable.ic_launcher;
notifaication.tickerText = "hello world";
notification.when = System.currentTimeMillis();
notification.flags = Notification.FLAG_AUTO_CANCLE;
Intent intent = new Intent(this,Activity1.class);
PendingIntent pendingIntent = PentdingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews remoteViews = new RemoteViews(getPackgeName(),R.layout.Layout_notification);
remoteViews.setTextiewText(R.id.msg,"chapter_5"); //設(shè)置文字
remoteViews.setImageViewResource(R.id.icon,R.drawable.icon1); //設(shè)置圖標(biāo)
PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this,0,new Intent(this,Activity2.class),PendingIntent.FLAG_UPDATE_CURRENT)
remoteViews.setOnClickPendingIntent(R.id.open_activity2,openActivity2PendingIntent);
notification.contentView = remoteViews;
notification.contentIntent = pendingIntent;
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(2,notification);
從上述代碼中可以看出惫企,我們只用傳入包名以及布局文件的資源id即可創(chuàng)建出一個RemoteViews對象疙咸。關(guān)于更新,我們則是使用RemoteViews提供的一系列set方法來完成操作媳友。如果要給一個控件增加點擊事件斯议,則需要setOnClickPendingIntent()方法來實現(xiàn)。
2.RemoteViews在桌面小部件上的應(yīng)用
開發(fā)桌面小部件主要分為以下幾步:
1)定義小部件的界面(布局信息)
2)定義小部件的配置信息
3)定義小部件的實現(xiàn)類
4)在AndroidManifest.xml中聲明小部件
具體的操作過程可以點擊這里醇锚。
3.PendingIntent概述
概念:PendingIntent表示一種pending狀態(tài)的意圖哼御,就是說接下來有一個Intent會在將來某一個特定的時刻發(fā)生。PendingIntent典型的使用場景是給RemoteViews添加單擊事件焊唬。PendingIntent通過send()和cancel()方法來發(fā)送和取消特定的待定Intent恋昼。
PendingIntent的三種意圖:PendingIntent支持三種意圖,啟動Activity赶促、啟動Service和發(fā)送廣播液肌,它們分別對應(yīng)著它的三個接口和方法:
可以看到這三個方法的參數(shù)都是相同的,這里來著重介紹一下requestCode和flags鸥滨。
requestCode
表示PendingIntent發(fā)送方的請求碼嗦哆,多數(shù)情況下取0即可谤祖。同時它也和PendingIntent的匹配規(guī)則有關(guān),即當(dāng)兩個PendingIntent的requestCode和內(nèi)部的Intent都相同時老速,這兩個PendingIntent就是匹配的粥喜。flag
flag主要有以下4個標(biāo)記位:
1)FLAG_ONE_SHOT:當(dāng)前描述的PendingIntent只能被使用一次,然后它會被自動cancel橘券,后續(xù)如果有相同的PendingIntent則它們的send()方法會調(diào)用失敗额湘。
2)FLAG_NO_CANCEL:當(dāng)前描述的PendingIntent不會主動創(chuàng)建,如果當(dāng)前的PendingIntent之前不存在约郁,那么那三個方法會直接返回null缩挑。
3)FLAG_CANCEL_CURRENT:當(dāng)前描述的PendingIntent如果已經(jīng)存在,那么它們都會被cancel鬓梅,系統(tǒng)在后續(xù)會創(chuàng)建一個新的PendingIntent供置。
4)FLAG_UODATE_CRUUENT:當(dāng)前描述的PendingIntent如果以及存在,那么它們都會被更新绽快。
二.RemoteViews的內(nèi)部機制
1.RemoteViews的構(gòu)造方法
RemoteViews有許多的構(gòu)造方法芥丧,這里只是舉出來最常用的一種:public RemoteViews(String packgeNmae,int layout)
,從參數(shù)的名字中就可以看出該方法所需要的兩個參數(shù)就是當(dāng)前應(yīng)用所在的包名和將要加載的布局文件坊罢。
2.RemoteViews所支持的View類型
layout
LinearLayout续担、FrameLayout、RelativeLayout活孩、GridLayout物遇。View
AnaloClock、Button憾儒、TextView询兴、ImageView、ListView起趾、GridView诗舰、Chronometer、ImageButton训裆、StackView眶根、ViewStub、ProgressBar边琉。
3.RemoteViews訪問View的方法
由于RemoteViews主要是用來操作其他進(jìn)程的View属百,所以它無法直接訪問里面的View元素,而是需要通過RemoteViews提供的一些列set方法來完成变姨,具體的方法如下:
4.RemoteViews的內(nèi)部運行過程
首先由于RemoteViews實現(xiàn)了Parcelable接口诸老,所以它會先通過Binder傳遞到SystemServer進(jìn)程中。接著系統(tǒng)會根據(jù)RemoteViews中傳入的包名钳恕、布局等信息别伏,通過LayoutInflater去加載這些布局文件。接著系統(tǒng)會對View執(zhí)行一系列界面更新任務(wù)忧额,而這些更新任務(wù)就是通過之前的set方法來完成的厘肮,當(dāng)RemoteViews被加載完成以后,這些更新操作就會被執(zhí)行睦番。
Action的概念:在Android系統(tǒng)中由于效率的原因并沒有通過Binder去直接支持View的跨進(jìn)程訪問类茂,而是通過Action來進(jìn)行。Action實現(xiàn)了Parcelable接口托嚣。當(dāng)我們在應(yīng)用中每調(diào)用一次set方法時巩检,RemoteViews中就會添加一個Action的對象,當(dāng)我們提交更新時示启,這些Action對象就會被在遠(yuǎn)程進(jìn)程中依次執(zhí)行兢哭。
執(zhí)行方法:當(dāng)RemoteViews到達(dá)遠(yuǎn)程進(jìn)程之后,RemoteViews就會調(diào)用apply()方法去遍歷所有的Action對象并且調(diào)用它們的apply()方法夫嗓,而具體的View更新操作都是由Action中得apply()方法去執(zhí)行的迟螺。