對桌面widget的開發(fā)之前接觸的不多,但RemoteViews和PendingIntent在android系統(tǒng)里卻是很有意思的知識點,它們主要是用在開發(fā)桌面widget和通知欄上。本文主要介紹下為什么在android系統(tǒng)里存在RemoteViews和PendingIntent,以及它們工作的原理。
以開發(fā)桌面widget做例, 首先看下兩個類的源碼.
public class RemoteViews implements Parcelable, Filter {}
實現(xiàn)了Parcelable接口,可以想象的到, 這個類的對象要用在跨進程傳輸上.
public final class PendingIntent implements Parcelable {}
PendingIntent, 字面理解就是待處理的intent, 這個intent不會立刻被處理, 直到某個條件滿足時, 才會處理pendingIntent所封裝的普通intent.
RemoteViews:
實際上,桌面widget和本地app不是運行在同一個進程內(nèi),它是運行在SystemServer進程。view的顯示并不是在自己進程內(nèi)完成的, 而自己進程要操作這個view的顯示狀態(tài),所以這個特殊的view叫做RemoteView, 字面翻譯也就是遠程view,顯示在另一個進程中的view.
PendingIntent:
對普通intent進行一個封裝, 由一個進程發(fā)給另一個進程去使用.
以桌面小部件的實現(xiàn)源碼來說明
public class UnionSearchWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
int len = appWidgetIds.length;
for (int i = 0; i < len; i++) {
//提供包名和布局文件讓remoteView加載
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.union_search_widget);
//創(chuàng)建一個普通的intent
Intent searchIntent = new Intent(context,BrowserActivity.class);
searchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
searchIntent.putExtra("from", "from_appwidget_search_input");
//通過PendingIntent.getActivity接口,對普通intent進行封裝,并返回一個pendingIntent
PendingIntent pi = PendingIntent.getActivity(context, 0,
searchIntent, 0);
//給remoteView設(shè)置點擊事件,當(dāng)pendingIntent被觸發(fā)時,就相當(dāng)與調(diào)用
//context.startActivity(intent)
remoteViews.setOnClickPendingIntent(R.id.search_view_title, pi);
//通過AppWidgetManager提交更新app widget顯示的任務(wù)
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
}
}