当前位置:网站首页>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 :
边栏推荐
- 纯纯大怨种!那些年被劝退的考研专业
- Array method in JS 2021.09.18
- Day28 strict mode, string JS 2021.09.22
- Int~long long indicates the maximum and minimum number
- NFT card chain game system development DAPP construction technical details
- day32 js笔记 事件(上)2021.09.27
- Using MySQL database in the express framework of node
- AcWing 606. Average 1 (implemented in C language)
- RemoteViews布局和类型限制源码分析
- 【C语言】NextDay问题
猜你喜欢

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

Day31 JS notes DOM 2021.09.26

2018 joint examination of nine provinces & Merging of line segment trees

Build your own website (18)

Prepare for Jin San Yin Si I. testers without experience in automated testing projects should look at it quickly

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

Redis 原理 - List

Unity屏幕截图功能

Self use demo of basic component integration of fluent

day33 js笔记 事件(下)2021.09.28
随机推荐
Pre parsing, recursive functions and events in day25 JS 2021.09.16
Prefix and (2D)
Multi dimensional monitoring: the data base of intelligent monitoring
不到一小时,苹果摧毁了15家初创公司
Chendanqi, Fang Fei, guquanquan and Li Bo won the prize, and the list of Sloan research award in 2022 was released
RemoteViews的作用及原理
Two writing methods of JNI function
Oracle date format exception: invalid number
Random forest and poetry maker trained by AMR
Packaging and publishing application of jetpack compose desktop version
Day36 JS notes ecma6 syntax 2021.10.09
Web3 security serials (3) | in depth disclosure of NFT fishing process and prevention techniques
day23 js笔记 2021.09.14
Zero basic C language (I)
If you want to change to software testing, how can you package your resume as a test engineer with 1 year of work experience
Solutions to connection failures and errors when accessing mysql8 using the SSM project
Software test interview classic + 1000 high-frequency real questions, and the hit rate of big companies is 80%
recent developments
Swin, three degrees! Eth open source VRT: a transformer that refreshes multi domain indicators of video restoration
Day30 JS notes BOM and DOM 2021.09.24