RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notication);
remoteViews.setTextViewText(R.id.text, "text");
remoteViews.setImageViewResource(R.id.image, R.drawable.icon);
remoteViews.setOnClickPendingIntent(R.id.button,
PendingIntent.getActivities(this, 0,
new Intent(this, TargetActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT));
getActivity(Context context, int requestCode, Intent intent, @Flags int flags)
getBroadcast(Context context, int requestCode, Intent intent, @Flags int flags)
getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)
* PendingIntent用于描述Intent和target action,提供给其他application以执行相应的动作。
* 所以为了安全,要使用显示Intent,直接指定目标组件。
* PendingIntent标识了一组将要操作的数据,如果创建它的process被kill了,不影响其他process继续使用他;之后如果重新创建了一个相同类型的PendingIntent,之前同类型的如果可用将继续被使用。
* 相同的Intent将得到相同的PendingIntent,而Intent中extra的部分不会影响判断Intent是否相同。所以如果想得到不同PendingIntent,要保证Intent的不同(单独区分extra无效),或者在PendingIntent的get方法中指定不同的requestCode;如果同一时刻只想使用同一个PendingIntent,通过设置FLAG_CANCEL_CURRENT或FLAG_UPDATE_CURRENT来取消或更新指定的Intent。
* flags:
* FLAG_ONE_SHOT
该PendingIntent只能被使用一次。Intent被send之后会直接被cancel,之后send将失败。
* FLAG_CANCEL_CURRENT
如果当前描述的PendingIntent已经存在,则cancel,然后创建一个新的PendingIntent。
* FLAG_UPDATE_CURRENT
如果当前描述的PendingIntent已经存在,则替换其中Intent的extra。
Remoteviews仅支持部分layout和view,不支持其子类和其他自定义View。
RemoteViews会通过Binder传递到SystemServer进程,在SystemServer中加载布局,更新View。具体流程:
public void setTextViewText(int viewId, CharSequence text) {
setCharSequence(viewId, "setText", text);
}
public void setCharSequence(int viewId, String methodName, CharSequence value) {
addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value));
}
private void addAction(Action a) {
if (hasLandscapeAndPortraitLayouts()) {
throw new RuntimeException("RemoteViews specifying separate landscape and portrait" +
" layouts cannot be modified. Instead, fully configure the landscape and" +
" portrait layouts individually before constructing the combined layout.");
}
if (mActions == null) {
mActions = new ArrayList<>();
}
mActions.add(a);
}
/** @hide */
public View apply(Context context, ViewGroup parent, OnClickHandler handler) {
RemoteViews rvToApply = getRemoteViewsToApply(context);
View result = inflateView(context, rvToApply, parent);
loadTransitionOverride(context, handler);
rvToApply.performApply(result, parent, handler);
return result;
}
private void performApply(View v, ViewGroup parent, OnClickHandler handler) {
if (mActions != null) {
handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler;
final int count = mActions.size();
for (int i = 0; i < count; i++) {
Action a = mActions.get(i);
a.apply(v, parent, handler);
}
}
}