Implementation of RemoteViews in Android

Tian Haili@CSDN

2012-8-22

 

This article combines the application scenarios of AppWidget to analyze the internal implementation of RemoteViews in Android.

From the previous article " Analysis and Application of AppWidget in Android : AppWidgetProvider " and " Analysis of AppWidget Processing by Launcher in Android: AppWidgetHost Role ", it is known that the graphics resources of AppWidget in Android are provided by AppWidgetProvider through RemoteViews; and the display is provided by AppWidgetHost displays the content provided by RemoteView on the local View through AppWidgetHostView. AppWidgetProvider and AppWidgetHostView run in different programs, and the graphical elements that they communicate and the bridge between clicks and feedback are RemoteViews.

 

For the sake of convenience and consistency, the content provider AppWidgetProvoder of RemoteViews is called the Remote side; the AppWidgetHost that displays the contents of RemoteViews is called the Local side.

 

1. Provide content to RemoteViews-SettingsAppWidgetProvider

 

The following figure is a sequence diagram of SettingsAppWidgetProvider (located in the com.android.settings.widget package in Settings) as an AppWidgetProvider after being notified of the update, creating RemoteViews, and putting the response Intent and graphic elements of the Remote side into RemoteViews.

RemoteViews setOnClickPendingIntent setImageViewResource

Figure 1. Provide content and listen to RemoteViews

 

In the figure,

1. When you create RemoteViews in Settings, pass in packageName and layoutId and save them. The packageName is very important , because the layoutId and various other resources here are relative to this program. Only by obtaining the corresponding Context through packageName can the resources be obtained, otherwise other programs cannot obtain these resources [Seq#1].

2. Settings set the PendingIntent that gets the response after the View indicated by the viewId in the layoutId is clicked to the RemoteViews [Seq#2~ #5].

  •  RemoteViews creates SetOnClickPendingIntent and passes in id and intent, SetOnClickPendingIntent saves these values;
  •  SetOnClickPendingIntent is a subclass of RemoteViews.Action, add SetOnClickPendingIntent to mActions:ArrayList<RemoteViews.Action> through addAction() and save it.

3. Settings set the ImageSourceID of the View indicated by the viewId in the layoutId to RemoteViews [Seq#6~ #10].

  •  There are many setXYZ() methods in RemoteViews, which are used to set according to different types of values ​​to be set;
  •  setXYZ() creates ReflectionAction and passes in viewId and value, and "setImageResource" as methodName, and ReflectionAction saves these values;
  •  ReflectionAction is a subclass of RemoteViews.Action, add ReflectionAction to mActions:ArrayList<RemoteViews.Action> through addAction() and save it.

What is described here is a sub-process. Later, the created RemoteViews will be put into the AppWidget system through the AppWidgetManager, so that the AppWidgetHost side of the AppWidget will update and display the content carried in the RemoteViews.

 

The process of setting the content on the remote side only sets these parameters, and RemoteViews just saves these parameters with different RemoteViews.Action. The internal structure is described below.

Note: The parameters here are all on the Remote side and are valid on the RemoteContext.

 

Second, the internal structure of RemoteViews

 

The following figure is a class diagram related to RemoteViews.

RemoteViews Class Hierarchy ReflectionAction OnClickPendingIntent

Figure 2. RemoteViews class diagram

 

Save the mPackage and mLayoutId of the Remote side in RemoteViews ; save various Actions with mActions:ArrayList<RemoteViews.Action>.

mPackage and mLayoutId are passed in when constructing RemoteViews [seq#1 in the above figure];

mActions is to set various remote-side response Intents and graphic elements, save them to the corresponding Action, and then add the Action here to save;

mLayoutId in a variety of controls by setTextViewText () / setImageViewResource () /at the remote end of the other functions provided. These methods then call set Type () [Type can be Boolean / Byte / Short / Int/ Long / Char / String / Uri / Bitmap/ Bundle, etc] and save it to ReflectionAction.

SetOnClickPendingIntent is used to send a pendingIntent notification when the local user clicks on the viewId. Save viewId and pendingIntent in the constructor of SetOnClickPendingIntent.

ReflectionAction is used to obtain remote resources through the Reflect mechanism when displayed on the local side. Save the viewId, methodName, type and value in the construction method of ReflectionAction.

ViewGroupAction and SetDrawableParameters are also subclasses of RemoteViews.Action, which are not used in this scenario. The basic principles are similar and readers can analyze by themselves.

 

Three, display the content of RemoteViews-AppWidgetHostView

 

After providing content for RemoteViews in Figure 1, AppWidgetHost will be notified through IAppWidgetHost.updateAppWidget() that there is an update on the Remote side, and the local side will display the content provided by RemoteViews on AppWidgetHostView. The following sequence diagram describes this process.

RemoteViews updateAppWidget apply

Figure 3. Local display of the content in RemoteViews

 

In the picture:

1. Get the packageName and layoutId of the Remote side (AppWidgetProvider) in RemoteViews, and create a remote context——remoteContext through packageName. [Seq#1~ 6]

2. Through the apply() method of RemoteViews, the action of listening to the Click operation is actually executed; the locally used View is obtained through the remote Layout. [Seq#7~ 20]

2.1. Clone a local LayoutInflater; [Seq#8]

2.2. Use the cloned LayoutInflater to execute Inflate on the layoutId of the remote side to obtain the Hierarchy of the View described by the Layout, which is the rootView used later; [Seq#9~ 10]

2.3. Perform performApply on the view obtained in 2.2. [Seq#11~ 19]

performApply() performs the apply() operation on all Actions in mActions. such,

2.3.1 For setOnClickPendingIntent, [Seq#12~ 15]

  •  Find the View to listen to through findViewById(viewId) of rootView (the total View of the Layout on the Remote side obtained in 2.2); [Seq#13]
  •  Set the Listener of Click to the View found to listen. [Seq#14]

2.3.2 For ReflectionAction, [Seq#16~19]

  •  Find the object View whose content is to be set through findViewById(viewId) of rootView (the total View of the Layout on the Remote side obtained in 2.2); [Seq#17]
  •  Then through the Reflect mechanism, execute the method in the View implementation class (for example, setImageResource() here), and set the Id of the corresponding resource to it. [Seq#18]

3. Add the obtained View to the local View system. [Seq#21]

 

The following is a code snippet of ReflectionAction.apply() setting content through the Reflect mechanism (error handling and non-critical parts are ignored):

       @Override
       public void apply(View root) {
           final View view = root.findViewById(viewId);
           Class param = getParameterType();  // 通过this.type得到class:int.class
           Class klass = view.getClass();     // 这个类在Remote的Layout中定义,这里为ImageView
           Method method = klass.getMethod(this.methodName, param); // methodName是实现View类里的方法名:setImageResource(int)
 
           try {
               // 执行ImageView.setImageResource(value),value为resId
                method.invoke(view, this.value);
           } catch (Exception ex) {
               throw new ActionException(ex);
           }
        }

 

Four, summary

The content provider of RemoteViews provides displayed resources and Intents that listen for click events;

The local display side of RemoteViews obtains the display resources in the View through RemoteViews, and adds it to the local graphics system to complete the local display of Remote resources.

 

Articles for further reference

Through the other articles in this series, information related to this article can be obtained:

Android AppWidget framework

    AppWidget system framework.

Select and bind AppWidget in Android

    Launcher initiates the selection process. This article describes the selection and binding process. You can refer to this article to see the complete selection/binding/joining process of the display system.

Analysis and application of AppWidget in Android: AppWidgetProvider

    It is the AppWidgetProvider described in this article that creates RemoteViews and sets ImageViewResource and OnClickPendingIntent.

Analysis of AppWidget processing by Launcher in Android: AppWidgetHost role

    The RemoteViews provided by AppWidgetProvider described in this article is the time to start real application of RemoteViews in Launcher.

Implementation of RemoteViews in Android

    This article.

 

Guess you like

Origin blog.csdn.net/thl789/article/details/7893908