当前位置:网站首页>Function and principle of remoteviews
Function and principle of remoteviews
2022-06-28 12:15:00 【A cup of bitter mustard】
One 、RemoteViews What is it? ?
RemoteViews Indicates remote View, For cross process updates UI, It is mainly used in the system notice bar (Notification) And desktop widgets (App Widget) in .RemoteViews No inheritance View, But it did parcelable This interface .

The notification is displayed on the notification bar through NotificationManager Of notify() Method , If the notification bar needs custom layout , You need to use it RemoteViews.
/**
* Post a notification to be shown in the status bar. If a notification with
* the same id has already been posted by your application and has not yet been canceled, it
* will be replaced by the updated information.
*
* @param id An identifier for this notification unique within your
* application.
* @param notification A {@link Notification} object describing what to show the user. Must not
* be null.
*/
public void notify(int id, Notification notification)
{
notify(null, id, notification);
}
/**
* Post a notification to be shown in the status bar. If a notification with
* the same tag and id has already been posted by your application and has not yet been
* canceled, it will be replaced by the updated information.
*
* All {@link android.service.notification.NotificationListenerService listener services} will
* be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
* provided on this notification or the
* {@link NotificationChannel} this notification is posted to using
* {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
* notification is canceled, or you can revoke permissions with
* {@link Context#revokeUriPermission(Uri, int)}.
*
* @param tag A string identifier for this notification. May be {@code null}.
* @param id An identifier for this notification. The pair (tag, id) must be unique
* within your application.
* @param notification A {@link Notification} object describing what to
* show the user. Must not be null.
*/
public void notify(String tag, int id, Notification notification)
{
notifyAsUser(tag, id, notification, mContext.getUser());
}Desktop widgets are via AppWidgetProvider Realized ,AppWidgetProvider It's essentially a broadcast , However, the interface of the widget needs to use RemoteViews Realization .
public class AppWidgetProvider extends BroadcastReceiver {
/**
* Constructor to initialize AppWidgetProvider.
*/
public AppWidgetProvider() {
}
/**
* Implements {@link BroadcastReceiver#onReceive} to dispatch calls to the various
* other methods on AppWidgetProvider.
*
* @param context The Context in which the receiver is running.
* @param intent The Intent being received.
*/
// BEGIN_INCLUDE(onReceive)
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
} else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
} else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (oldIds != null && oldIds.length > 0) {
this.onRestored(context, oldIds, newIds);
this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
}
}
}
}
// END_INCLUDE(onReceive)
// Other code is omitted here
}The reason for using... In notification bars and widgets RemoteViews Display interface , Because their interfaces run in other processes , That is, systematic SystemServer process .
Two 、 How to use RemoteViews?
RemoteViews For usage in the notification bar and widget, refer to : Official documents
And my other blog :RemoteViews Layout and type constraints source code analysis
3、 ... and 、RemoteViews Principle
RemoteViews Is used to display and update in other processes UI, However, it only supports some commonly used Layout and View. because RemoteViews It's cross process , Not provided findViewById() Method , So you can't access it directly View Elements . however RemoteViews Provides a range of set Method to access its View Elements , For example, setting resources 、 Add click events, etc .

RemoteViews Mainly used in notification bar and widget , The notification bar and widget are created by NotificationManager and AppWidgetManager management , and NotificationManager and AppWidgetManager It's through Binder Respectively and SystemServer In process NotificationManagerService as well as AppWidgetService Communicating . therefore , The interface in the notification bar and widget is actually made up of NotificationManagerService as well as AppWidgetService Loaded , They run on the system SystemServer In progress ,APP Process to update RemoteViews, You need to use Binder Cross process communication .
RemoteViews Medium IPC The process :
1. RemoteViews adopt Binder Pass on to SystemServer process , The system will RemoteViews Get the relevant resources from the package name and other information ;
2. adopt LayoutInflater load RemoteViews Layout file for , stay SystemServer In progress , This layout file is actually an ordinary View, But compared with APP process , It's a RemoteViews;
3. System pair View Execute the interface initialization task , These operations are carried out through RemoteViews A series of set Method submitted , But these set Method pair View The operation of is not performed immediately , stay RemoteViews These operations are recorded internally , The specific implementation will wait until RemoteViews Execute after being loaded ;
4. When APP The process needs to be updated RemoteViews when , You need to call the relevant set Method , adopt NotificationManager and AppWidgetManager To submit an update task to SystemServer process , The specific update operation needs to be performed in SystemServer In progress .
RemoteViews in set Method implementation :
1. The system did not pass Binder To support View Cross process access .RemoteViews Provides a Action The concept of ,Action Realized Parcelable Interface .
2. The system will RemoteViews A series of operations are encapsulated into Action In the object , And will Action Cross process transfer to SystemServer process , Finally, execute in the remote process Action Object . Every call set Method ,RemoteViews The corresponding Action object , Eventually it will be transferred to the remote process .
3. The remote process passes through RemoteViews Of apply methods View Update operation for ( Traverse all of Action object , And call it apply Method ).
4. This eliminates the need to define a large number of Binder Interface , Through batch operation in remote process , Avoid a lot of IPC operation , Improved performance .
/**
* Base class for all actions that can be performed on an
* inflated view.
*
* SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
*/
private abstract static class Action implements Parcelable {
public abstract void apply(View root, ViewGroup rootParent,
OnClickHandler handler) throws ActionException;
public static final int MERGE_REPLACE = 0;
public static final int MERGE_APPEND = 1;
public static final int MERGE_IGNORE = 2;
public int describeContents() {
return 0;
}
public void setBitmapCache(BitmapCache bitmapCache) {
// Do nothing
}
public int mergeBehavior() {
return MERGE_REPLACE;
}
public abstract int getActionTag();
public String getUniqueKey() {
return (getActionTag() + "_" + viewId);
}
/**
* This is called on the background thread. It should perform any non-ui computations
* and return the final action which will run on the UI thread.
* Override this if some of the tasks can be performed async.
*/
public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
return this;
}
public boolean prefersAsyncApply() {
return false;
}
/**
* Overridden by subclasses which have (or inherit) an ApplicationInfo instance
* as member variable
*/
public boolean hasSameAppInfo(ApplicationInfo parentInfo) {
return true;
}
public void visitUris(@NonNull Consumer<Uri> visitor) {
// Nothing to visit by default
}
int viewId;
}RemoteViews in apply and reapply The difference between :
1. apply: Load layout , And update UI.
2. reApply: Update only UI.
3. When the notification bar and desktop widget are initialized , Would call apply Method , Subsequent update operations call reapply Method .
/**
* Inflates the view hierarchy represented by this object and applies
* all of the actions.
*
* <p><strong>Caller beware: this may throw</strong>
*
* @param context Default context to use
* @param parent Parent that the resulting view hierarchy will be attached to. This method
* does <strong>not</strong> attach the hierarchy. The caller should do so when appropriate.
* @return The inflated view hierarchy
*/
public View apply(Context context, ViewGroup parent) {
return apply(context, parent, null);
}
/** @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;
} /**
* Applies all of the actions to the provided view.
*
* <p><strong>Caller beware: this may throw</strong>
*
* @param v The view to apply the actions to. This should be the result of
* the {@link #apply(Context,ViewGroup)} call.
*/
public void reapply(Context context, View v) {
reapply(context, v, null);
}
/** @hide */
public void reapply(Context context, View v, OnClickHandler handler) {
RemoteViews rvToApply = getRemoteViewsToApply(context);
// In the case that a view has this RemoteViews applied in one orientation, is persisted
// across orientation change, and has the RemoteViews re-applied in the new orientation,
// we throw an exception, since the layouts may be completely unrelated.
if (hasLandscapeAndPortraitLayouts()) {
if ((Integer) v.getTag(R.id.widget_frame) != rvToApply.getLayoutId()) {
throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" +
" that does not share the same root layout id.");
}
}
rvToApply.performApply(v, (ViewGroup) v.getParent(), handler);
}
Reference link :
边栏推荐
- 2. single digit statistics
- 什么是数据合规?怎样做到数据合规?
- 5. Sum of N numbers
- [Beijing University of Aeronautics and Astronautics] information sharing for the first and second examinations of postgraduate entrance examination
- Remoteviews layout and type restriction source code analysis
- SoapUI rookie tutorial
- Convert black mask picture to color annotation file
- Dongyuhui, New Oriental and Phoenix Satellite TV
- 开源项目维权成功案例: spug 开源运维平台成功维权
- Prepare for Jin San Yin Si I. testers without experience in automated testing projects should look at it quickly
猜你喜欢

Android应用安全之JNI混淆

Deployment and optimization of vsftpd service

Django -- MySQL database reflects the mapping data model to models

纯纯大怨种!那些年被劝退的考研专业

. Net hybrid development solution 24 webview2's superior advantages over cefsharp

Redis 原理 - List

SEO优化的许多好处是与流量有直接关系

ArrayList源码解析

Share the easy-to-use fastadmin open source system - practical part

【C语言】二叉树的实现及三种遍历
随机推荐
Timestamp and date conversion "suggested collection"
What is DAPP system development and analytical understanding
1. print hourglass
Why do many people want to change careers as programmers, while some programmers want to change careers as others?
Random forest and poetry maker trained by AMR
The development and principle of the metacosmic system
2018 joint examination of nine provinces & Merging of line segment trees
Using MySQL database in the express framework of node
[Beijing University of Aeronautics and Astronautics] information sharing for the first and second examinations of postgraduate entrance examination
Prepare for Jin San Yin Si I. testers without experience in automated testing projects should look at it quickly
[no title] the virtual machine vmnet0 cannot be found and an error is reported: there is no un bridged host network adapter
.NET混合开发解决方案24 WebView2对比CefSharp的超强优势
JS foundation 10
Graphics view framework for QT learning (to realize startup animation)
Prefix and (2D)
Contract quantitative trading system development | contract quantitative app development (ready-made cases)
day29 js笔记 2021.09.23
day28 严格模式、字符串 js 2021.09.22
SoapUI rookie tutorial
SHA256加密工具类