Desarrollo práctico del código fuente detallado del widget de vehículo Android: curso práctico sobre el desarrollo del marco del vehículo Qianli Ma

Enlace de referencia del sitio web oficial: https://developer.android.google.cn/develop/ui/views/appwidgets/overview

1. ¿Qué es un widget?

Los widgets de aplicaciones son vistas de aplicaciones en miniatura que pueden integrarse en otras aplicaciones (como la pantalla de inicio) y recibir actualizaciones periódicas.
Explicación popular: una vista en miniatura que se puede actualizar periódicamente y agregar a otras aplicaciones.
Para obtener más contenido del marco de Android, chatee con Qianlima en privado: https://www.bilibili.com/video/BV1wj411o7A9/

2. ¿Cuál es el mecanismo operativo del widget?

Insertar descripción de la imagen aquíDefina el comportamiento del widget a través de AppWidgetProvider.
Defina la interfaz de usuario del widget a través de RemoteView y archivos de diseño.
Actualice la vista a través de AppWidgetManager.
Registre AppWidgetProvider (heredado de la transmisión) en el manifiesto y establezca la acción de escucha.

3. ¿En qué proceso se ejecuta el widget?

Primero, comprendamos el proceso del Host y el proceso del widget, como se muestra en la siguiente figura:
Insertar descripción de la imagen aquí
los procesos involucrados en la operación del widget y las responsabilidades de cada proceso:
Insertar descripción de la imagen aquí

La lógica de ejecución del widget debe dividirse en tres partes: la lógica en AppWidgetProvider se ejecuta en el proceso de aplicación donde se encuentra el widget. El almacenamiento de datos de los widgets, la lógica de verificación de permisos y el puente de comunicación entre el proceso del widget y el proceso del host son intermediarios de comunicación entre procesos y se ejecutan en system_process. La lógica de representación del widget está en el proceso del host.

4. ¿Cómo funciona RemoteView?

RemoteView hereda de Parcelable y se puede pasar entre procesos. RemoteView convertirá cada comportamiento establecido en una acción correspondiente. Luego, la acción se traduce en el comportamiento correspondiente durante el proceso del lado del Host.

Por ejemplo:
para el
método setText normal de TextView en su propio proceso, simplemente llame a mTextView.setText directamente.
Sin embargo, este widget no es renderizado por su propio proceso de widget. Solo puede operarse a través de RemoteView. El principio de RemoteView es en realidad ese la clase que pasa es un nombre de método. Caracteres, porque las cadenas se pueden pasar a través de procesos y luego llegar al proceso Host. El proceso Host puede realizar llamadas de reflexión basadas en la cadena del nombre del método. El diagrama esquemático es el siguiente
:
Insertar descripción de la imagen aquí

Se puede ver que RemoteViews es esencialmente un medio que puede controlar y mostrar vistas entre procesos. No es tan conveniente como controlar su propia vista. Las interfaces de control correspondientes a la vista deben convertirse una por una, por lo que todavía es muy inflexible Y preste atención aquí, porque la vista Puede haber muchos tipos, pero las vistas remotas solo tienen vistas fijas y no admiten vistas arbitrarias ni personalización.
Insertar descripción de la imagen aquí

5. Parte de desarrollo de widgets

AppWidgetProviderInfo object 
Describes the metadata for an App Widget, such as the App Widget's layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.
AppWidgetProvider class implementation
Defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.

1 Prepare la información de AppWidgetProviderInfo.
AppWidgetProviderInfo describe principalmente los metadatos del widget, como el diseño del widget y la frecuencia de actualización, y generalmente se define en xml.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="60dp"
    android:minHeight="30dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/appwidget_provider"
    android:configure="com.example.android.apis.appwidget.ExampleAppWidgetConfigure"
    android:resizeMode="horizontal"
    >
</appwidget-provider>

Lo más importante es que initialLayout tendrá un diseño de inicialización, que es el diseño de visualización predeterminado del widget, es decir, el diseño predeterminado que se muestra antes de que el programa del widget no llame al código updateWidget.

diseño/appwidget_provider

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/appwidget_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#ffff00ff"
    android:textColor="#ff000000"
/>

2 Prepare la clase de implementación de AppWidgetProvider.La
clase de implementación de AppWidgetProvider
se basa en la transmisión y la devolución de llamadas para notificar a AppWidget sobre la situación, como actualizaciones, habilitaciones, deshabilitaciones y otras notificaciones.

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    
    

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    
    
        //省略
    }
    //省略
}

3 Registrarse en manifiesto

     <receiver android:name=".appwidget.ExampleAppWidgetProvider">
            <meta-data android:name="android.appwidget.provider"
                    android:resource="@xml/appwidget_provider" />
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
        </receiver>

La etiqueta de metadatos también es muy importante, es el xml vinculado a AppWidgetProviderInfo

4. Cómo actualizar la interfaz de usuario del widget mediante código

  static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
            int appWidgetId, String titlePrefix) {
    
    

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider);
        views.setTextViewText(R.id.appwidget_text, text);

        // Tell the widget manager
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

Principalmente cree las RemoteViews correspondientes a través del diseño, luego realice operaciones de conjunto relacionadas en las Vistas específicas en el diseño y finalmente llame al método updateAppWidget de appWidgetManager para actualizar AppWidget.

Para obtener la dirección de demostración correspondiente, debe descargar el código fuente de aosp:
aosp/development/samples/ApiDemos/src/com/example/android/apis/appwidget/

El widget se muestra en la página del widget del escritorio móvil. Debido a que el manifiesto del widget anterior está configurado, el escritorio se puede escanear y mostrar:
Insertar descripción de la imagen aquí
Después de arrastrarlo correctamente al escritorio, el widget se muestra de la siguiente manera:
Insertar descripción de la imagen aquí

6. Explicación detallada del proceso de visualización del host del widget.

En CarLauncher de AOSP, el código de función en sí es realmente muy simple: no hay ningún punto de demanda relacionado con la visualización del widget de la aplicación, pero el escritorio móvil tiene una parte de código completa como widgethost. Por eso, entender cómo borrar un WidgetHost se vuelve muy importante.

necesidad

App widget host: The AppWidgetHost provides the interaction with the AppWidget service for apps that want to embed app widgets in their UI. An AppWidgetHost must have an ID that is unique within the host's own package. This ID remains persistent across all uses of the host. The ID is typically a hard-coded value that you assign in your application.

App widget ID: Each widget instance is assigned a unique ID at the time of binding (see bindAppWidgetIdIfAllowed(), covered in more detail in Binding widgets on this page. The unique ID is obtained by the host using allocateAppWidgetId(). This ID is persistent across the lifetime of the widget, that is, until it is deleted from the host. Any host-specific state (such as the size and location of the widget) should be persisted by the hosting package and associated with the app widget ID.

App widget host view: Think of AppWidgetHostView as a frame that the widget is wrapped in whenever it needs to be displayed. A widget is associated with an AppWidgetHostView every time the widget is inflated by the host. Note the following points:

By default, the system will create an AppWidgetHostView, but the host can create its own subclass of AppWidgetHostView by extending it.
Starting in Android 12 (API level 31), AppWidgetHostView introduces the the setColorResources() and resetColorResources() methods for handling dynamically overloaded colors. The host is responsible for providing the colors to these methods.

AppWidgetHost es responsable de interactuar con el servicio AppWidget del servidor del sistema, cada AppWidgetHost debe tener una identificación independiente, lo que significa que no solo el escritorio se puede usar como host, sino que el más común que usualmente usamos es el escritorio, que También significa que puede haber varios hosts. También muestra widgets.
Insertar descripción de la imagen aquí

El ID del widget de la aplicación representa que cada instancia del widget de la aplicación tendrá una identificación independiente, que se obtiene mediante el método allocateAppWidgetId de AppWidgetHost. Esta identificación se necesita principalmente al vincular el widget, es decir, el método bindAppWidgetIdIfAllowed requiere esta identificación.

AppWidgetHostView
sirve como vista que representa el widget y es responsable de inflar las vistas relacionadas del widget.


El nivel de permiso BIND_APPWIDGET requerido
Insertar descripción de la imagen aquí es el siguiente: debe tener una firma de plataforma o debe ser una aplicación / privado incorporada. De hecho, CarLauncher generalmente está satisfecho con esto y la firma de la plataforma es generalmente la misma que la del sistema. .

Análisis real específico (consulte la demostración del código fuente de aosp: development/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java):

  第一步,根据独特HOST_ID,构造出AppWidgetHost :
  mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);
  第二步,AppWidgetHost 申请出独特的widget id:
  int id = mAppWidgetHost.allocateAppWidgetId();
  第三步,用申请的widget id绑定到对应的widget的provider的componentName:
  mAppWidgetManager.bindAppWidgetId(mAppWidgetId, intent.getComponent(), options);
  第四步,获取providerInfo,创建对应的AppWidgetHostView,进行add:
	 AppWidgetProviderInfo providerInfo =
            AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId);
mAppWidgetView = mAppWidgetHost.createView(getBaseContext(), appWidgetId, providerInfo);
mAppWidgetFrame.addView(mAppWidgetView, mPreviewWidth, mPreviewHeight);

Insertar descripción de la imagen aquíDemostración del fenómeno:
Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/learnframework/article/details/132707953
Recomendado
Clasificación