ContentProvide, uno de los cuatro componentes principales de Android

Introducción

Proveedor de contenido, uno de los cuatro componentes principales de Android, su función principal es realizar el intercambio de datos (entre aplicaciones) entre varias aplicaciones.

Aquí está involucrado el problema de la comunicación del proceso. Naturalmente, el archivador se usa en Android, pero debido a que la cantidad de datos proporcionados por el proveedor de contenido es generalmente relativamente grande, no se puede transmitir directamente.

Entonces, lo que se usa aquí es un método llamado memoria compartida anónima para la transferencia de datos, y solo se necesita transferir un descriptor de archivo en diferentes procesos.

Tenga una comprensión más intuitiva del proveedor de contenido a través de la siguiente figura:

f5c3a936d036a6b0ef53d5ec7bc7441b.png

ContentProvider proporciona un mecanismo para compartir datos entre aplicaciones.

  1. El almacenamiento y la recuperación de datos proporciona una interfaz unificada.

  2. Encapsule los datos sin preocuparse por los detalles del almacenamiento de datos.

  3. Android proporciona un ContentProvider predeterminado para algunos datos comunes (incluidos audio, video, imágenes y contactos, etc.).

Entonces, ¿cómo se da cuenta ContentProvider de compartir datos?

Identificador uniforme de recursos (URI)

El URI representa los datos que se van a operar y se puede utilizar para identificar cada ContentProvider, de modo que pueda encontrar el ContentProvider deseado a través del URI especificado y obtener o modificar datos de él.

El formato de una URI en Android es el siguiente:

URL =<schema>://<authority>/<path>/<id>

Por ejemplo: contenido://com.jeanboy.provider/User/1

  • tema (esquema)

El prefijo URI de ContentProvider indica un URI de contenido de Android, lo que indica que los datos están controlados por ContentProvider. Esta parte es fija y no se puede cambiar.

  • Información de autorización (autoridad)

La parte de autorización del URI es un identificador único que se utiliza para ubicar el ContentProvider. El formato suele ser el nombre completo de la clase ContentProvider personalizada, que se requiere para el registro. Tales como: com.jeanboy.provider.TestProvider.

  • nombre de la tabla (ruta)

El fragmento de ruta, generalmente el nombre de la tabla, apunta a un nombre de tabla en la base de datos.

  • registro (identificación)

Apunta a un registro específico, como un registro en una tabla (devuelve todos los registros si no se especifica).

tipo de datos MIME

MIME es para especificar un archivo con una extensión para abrir con una aplicación, al igual que usa un navegador para ver un archivo PDF, y el navegador elegirá la aplicación apropiada para abrir.

La forma en que funciona en Android es similar a HTTP, ContentProvider devolverá el tipo MIME según el URI y ContentProvider devolverá una cadena que contiene dos partes.

Composición MIME = tipo + subtipo.

texto/aplicación html/pdf

...

ContentProvider devuelve el tipo MIME según URI

ContentProvider.geType(uri) ;

Android sigue una convención similar para definir tipos MIME, y hay dos formas de tipos MIME de Android para cada tipo de contenido: registros múltiples (colecciones) y registros únicos.

  • Múltiples registros:vnd.android.cursor.dir/<custom>

  • Registro único:vnd.android.cursor.item/<custom>

vnd indica que estos tipos y subtipos tienen un formato no estándar específico del proveedor. El tipo en Android se ha corregido y no se puede cambiar. Solo se puede distinguir si es una colección o un solo registro específico. El contenido después del subtipo vnd. se puede completar de acuerdo con el formato.

Al usar Intent, MIME se usará para abrir la actividad que cumpla con las condiciones según el Tipo MIME.

<actividad android:name=".TestActivity"> 
  <intent-filter> 
    <categoría android:name="android.intent.category.DEFAULT" /> 
    <data android:mimeType="vnd.android.cursor.dir/jeanboy. primero" /> 
  </intent-filter> 
</actividad>

Crear un proveedor de contenido

A continuación, aprenda a crear un ContentProvider personalizado a través de una demostración simple. La fuente de datos puede elegir SQLite, la más utilizada es esta, por supuesto, también puede elegir otra, como SharedPreferences.

Primero, cree una clase TestContentProvider, herede ContentProvider e implemente el método.

clase pública TestContentProvider extiende ContentProvider { 
  ​@Override
 
  public boolean onCreate() { 
    // TODO 做一些初始化操作
    return false; 
  } 
  ​@Override
 
  public Cursor query(Uri uri, String[] proyección, String selection, 
                      String[] selectionArgs, String sortOrder) { 
    // TODO 查询
    return null; 
  } 
  ​@Override
 
  public String getType(Uri uri) { 
    // TODO MIME Type 
    return null; 
  } 
  ​@Override
 
  public Uri insert(Uri uri, valores ContentValues) { 
    // TODO 插入
}
  
    return null;
  @Override 
  public int delete(Uri uri, String selection, String[] selectionArgs) { 
    // TODO 删除
    return 0; 
  } 
  ​@Override
 
  public int update(Uri uri, valores de ContentValues, selección de cadenas, 
                    cadenas[] argumentos de selección) { 
    // TODO 更新
    return 0; 
  } 
}

Luego, debe registrarse AndroidManifest.xmlcon .

<proveedor 
    android:name=".ui.provider.TestProvider" 
    android:authorities="com.jeanboy.testprovider" />

Usar proveedor de contenido

En aplicaciones de terceros, ¿cómo usamos URI para realizar operaciones en datos compartidos? Se hace usando la clase ContentResolver.

El método para obtener una instancia de ContentResolver es:

Resolución de ContentResolver = getContentResolver();

ContentResolver tiene las siguientes operaciones de base de datos: consulta, inserción, actualización, eliminación.

consulta de cursor final pública (uri uri, proyección de cadena [], selección de cadena, 
                           argumentos de selección de cadena [], orden de clasificación de cadena) 
inserción de uri final pública (url de uri, valores de ContentValues) 
actualización de int final pública (uri de uri, valores de valores de contenido, cadena donde, 
                         cadena [] selectionArgs) 
public final int delete (Uri url, String where, String[] selectionArgs)

Un ejemplo completo es el siguiente:

clase pública ContentProviderActivity extiende BaseActivity { 
private
  Uri uriUser = 
    Uri.parse("content://com.jeanboy.testprovider/user"); 
  ​@Override
 
  protected void onCreate(Bundle SavedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.actividad_contenido_proveedor); 
  } 
​public
  void toInsert(View view) { 
    valores de ContentValues ​​= new ContentValues(); 
    valores.put("id", 3); 
    valores.put("nombre", "张三"); 
    Resolución de ContentResolver = getContentResolver(); 
    resolver.insert(uriUser, valores); 
  } 
​public
  void toUpdate(Ver vista) {
    Valores de ContentValues ​​= nuevos ContentValues(); 
    valores.put("id", 3); 
    valores.put("nombre", "张三三"); 
    Resolución de ContentResolver = getContentResolver(); 
    resolver.update(uriUser, valores, "id = ?", new String[]{"3"}); 
  } 
​public
  void toSelect(Ver vista) { 
    ContentResolver resolver = getContentResolver(); 
    Cursor cursor = resolver.query(uriUser, new String[]{"id", "name"}, 
                                   null, null, null); 
    while (cursor.moveToNext()) { 
      Log.e(TAG, "=========== consulta :" + cursor.getInt(0) + "==" 
            + cursor.getString(1)) ; 
    } 
    cursor.cerrar(); 
}
  
  public void toDelete(Ver vista) {
    resolver.delete(uriUser, "id = ?", new String[]{"3"}); 
  } 
}

Permisos de proveedor de contenido

Hay tres parámetros adicionales permiso, readPermission y writePermission en la etiqueta del proveedor en AndroidManifest.xml.

Primero mira el siguiente código:

<proveedor 
        android:name=".ui.provider.TestProvider" 
        android:authorities="com.jeanboy.testprovider" 
        android:exported="true" 
        android:readPermission="com.jeanboy.provider.permission.read" 
        android:writePermission ="com.jeanboy.proveedor.permiso.escribir" 
        android:permiso="com.jeanboy.proveedor.permiso"/>

Hay varios parámetros en este código a los que hay que prestar especial atención:

  • exportado

Este atributo se utiliza para indicar si el servicio se puede invocar o interactuar con otros componentes de la aplicación del programa; el valor es (verdadero | falso).

Si se establece en verdadero, se puede invocar o interactuar con él; de lo contrario, no; cuando se establece en falso, solo los componentes de la misma aplicación o las aplicaciones con el mismo ID de usuario pueden iniciar o vincular el servicio.

  • permiso de lectura

La autoridad necesaria para usar la función de consulta del Proveedor de contenido, es decir, la autoridad para usar query()las funciones .

  • permiso de escritura

La autoridad necesaria para usar la función de modificación de ContentProvider, es decir, la autoridad para usar las funciones insert(), update()y delete()de ContentProvider.

  • permiso

El nombre del permiso necesario para que el cliente lea y escriba datos en el Proveedor de contenido.

Esta propiedad proporciona un atajo para establecer permisos de lectura y escritura a la vez. Sin embargo, los atributos readPermission y writePermission tienen prioridad sobre esta configuración.

Si también se establece la propiedad readPermission, controlará la lectura del proveedor de contenido. Si se establece el atributo writePermission, también controlará la modificación de los datos del proveedor de contenido.

Es decir, si solo se establece el permiso permiso, entonces la aplicación con este permiso puede leer y escribir el ContentProvider aquí; si tanto el permiso como el permiso de lectura están configurados, entonces solo la aplicación con permiso de lectura puede leer, y solo la aplicación con permiso permiso permiso puede escribir! Es decir, no puede leer solo con el permiso, porque la prioridad del permiso de lectura es mayor que la del permiso; si se configuran al mismo tiempo el permiso de lectura, el permiso de escritura y el permiso, el permiso no será válido.

permiso de uso

Después de declarar el permiso anterior, debe registrarlo en el directorio al mismo nivel que la etiqueta de la aplicación.

<manifiesto...> 
		<permiso 
				android:name="com.jeanboy.provider.permission.read" 
				android:label="provider pomission" 
				android:protectionLevel="normal" /> 
  <aplicación...> 
    ... 
  < /aplicación> 
</manifiesto>

De esta forma, nuestro permiso quedará registrado en el sistema y se utilizará en aplicaciones de terceros <uses-permission>para usar permisos.

<usos-permiso android:name="com.jeanboy.provider.permission.read"/>

ContentObserver

La función principal de ContentObserver es monitorear los cambios de la base de datos en el URI especificado.

Primero, cree un ContentObserver.

public class DataObserver extiende ContentObserver { 
  public DataObserver(Handler handler) { 
    super(handler); 
  } 

  @Override 
  public void onChange(boolean selfChange) { 
    super.onChange(selfChange); 
    // TODO escucha los cambios de datos 
  } 
}

Registre un ContentObserver.

clase pública ContentProviderActivity extiende BaseActivity { 

  private Uri uriUser = 
    Uri.parse("content://com.jeanboy.myprovider/user"); 

  observador de datos privado observador de datos; 

  @Override 
  protected String getTAG() { 
    return ContentProviderActivity.class.getSimpleName(); 
  } 

  @Override 
  protected void onCreate(Paquete de estado de instancia guardado) { 
    super.onCreate(estado de instancia guardado); 
    setContentView(R.layout.actividad_contenido_proveedor); 
		// 创建 DataObserver 
    dataObserver = new DataObserver(new Handler()); 
    // 注册 DataObserver 
    getContentResolver().registerContentObserver(uriUser, true,
                                                 observador de datos); 
  } 
 
  @Anular
  vacío protegido onDestroy() { 
    super.onDestroy(); 
    // 取消注册
    getContentResolver().unregisterContentObserver(dataObserver); 
  } 
}

Finalmente, observe el uso de la función de escucha registerContentObserver()registrada :

public final void registerContentObserver(Uri uri, 
		boolean notificar a Descendientes, ContentObserver observador)
  • uri

El URI a observar.

  • notificar a los descendientes

Si es falso, significa coincidencia exacta, es decir, solo coincide con este URI; si es verdadero, significa que puede coincidir con su URI derivado al mismo tiempo.

Supongo que te gusta

Origin blog.csdn.net/fry3309/article/details/125281146
Recomendado
Clasificación