对桌面widget的开发之前接触的不多,但RemoteViews和PendingIntent在android系统里却是很有意思的知识点,它们主要是用在开发桌面widget和通知栏上。本文主要介绍下为什么在android系统里存在RemoteViews和PendingIntent,以及它们工作的原理。
以开发桌面widget做例, 首先看下两个类的源码.
public class RemoteViews implements Parcelable, Filter {}
实现了Parcelable接口,可以想象的到, 这个类的对象要用在跨进程传输上.
public final class PendingIntent implements Parcelable {}
PendingIntent, 字面理解就是待处理的intent, 这个intent不会立刻被处理, 直到某个条件满足时, 才会处理pendingIntent所封装的普通intent.
RemoteViews:
实际上,桌面widget和本地app不是运行在同一个进程内,它是运行在SystemServer进程。view的显示并不是在自己进程内完成的, 而自己进程要操作这个view的显示状态,所以这个特殊的view叫做RemoteView, 字面翻译也就是远程view,显示在另一个进程中的view.
PendingIntent:
对普通intent进行一个封装, 由一个进程发给另一个进程去使用.
以桌面小部件的实现源码来说明
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);
//创建一个普通的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设置点击事件,当pendingIntent被触发时,就相当与调用
//context.startActivity(intent)
remoteViews.setOnClickPendingIntent(R.id.search_view_title, pi);
//通过AppWidgetManager提交更新app widget显示的任务
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
}
}