当前位置:   article > 正文

安卓开发四大组件——contentProvider基本使用介绍(1)_contentprovider具体使用

contentprovider具体使用

问题背景

我们在安卓日常开发和学习过程中,contentProvider是个很常见的概念,毕竟是四大组件之一。不过可能工作和学习过程中涉及到contentProvider的场景有时候不是很多。本文先初步介绍下contentProvider的基本使用。

问题分析

话不多说,直接上代码,代码主要可以分为两大部分,一个是内容提供者,提供contentProvider给其他客户端访问,一个是内容访问者,通过访问第三方APP提供的contentProvider,去对第三方数据进行增删改查等各类操作。

一、contentProvider提供方

(1)借助SQLiteOpenHelper,新建数据库管理类,代码如下:

  1. import android.content.Context;
  2. import android.database.sqlite.SQLiteDatabase;
  3. import android.database.sqlite.SQLiteOpenHelper;
  4. import androidx.annotation.Nullable;
  5. /**
  6. * 数据库管理类,创建和管理数据库
  7. *
  8. * @author baorant
  9. */
  10. public class MySqlHelper extends SQLiteOpenHelper {
  11. public MySqlHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
  12. super(context, name, factory, version);
  13. }
  14. @Override
  15. public void onCreate(SQLiteDatabase sqLiteDatabase) {
  16. // 创建student数据表
  17. sqLiteDatabase.execSQL("create table student ("+
  18. "id integer primary key autoincrement,name varchar,age integer)");
  19. }
  20. @Override
  21. public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
  22. }
  23. }

(2)新建数据库增删改查具体操作类,暂时先实现查询和插入操作,代码如下:

  1. import android.content.ContentUris;
  2. import android.content.ContentValues;
  3. import android.content.Context;
  4. import android.database.Cursor;
  5. import android.database.sqlite.SQLiteDatabase;
  6. import android.net.Uri;
  7. import android.util.Log;
  8. /**
  9. * 数据库操作类,增删改查操作
  10. *
  11. * @author baorant
  12. */
  13. public class MyDataBase {
  14. private Context context;
  15. private SQLiteDatabase database;
  16. private static String TAG = "TestResolver";
  17. public MyDataBase(Context context){
  18. this.context = context;
  19. MySqlHelper dbHelper = new MySqlHelper(context,"db",null,1);
  20. database = dbHelper.getWritableDatabase();
  21. }
  22. /**
  23. * 数据插入操作
  24. */
  25. public Uri insertDao(ContentValues contentValues){
  26. Log.d(TAG, contentValues.toString());
  27. long rowid = database.insert("student",null, contentValues);
  28. Uri uri = Uri.parse("content://com.baorant.provider.MyContentProvider/student");
  29. Uri inserturi = ContentUris.withAppendedId(uri,rowid);
  30. context.getContentResolver().notifyChange(inserturi,null);
  31. return inserturi;
  32. }
  33. /**
  34. * 数据查询操作
  35. */
  36. public Cursor queryDao(String[] whichone, String selection, String[] selectionArgs, String sortOrder) {
  37. return database.query("student",whichone,selection,selectionArgs, null,null,sortOrder);
  38. }
  39. }

(3)新建自定义的ContentProvider类,代码如下:

  1. import android.content.ContentProvider;
  2. import android.content.ContentValues;
  3. import android.database.Cursor;
  4. import android.net.Uri;
  5. import androidx.annotation.NonNull;
  6. import androidx.annotation.Nullable;
  7. /**
  8. * MyContentProvider 自定义内容提供者类
  9. *
  10. * @author baorant
  11. */
  12. public class MyContentProvider extends ContentProvider {
  13. private MyDataBase myDataBase;
  14. @Override
  15. public String getType(Uri uri) {
  16. return "1";
  17. }
  18. @Override
  19. public Uri insert(Uri uri, ContentValues values) {
  20. return myDataBase.insertDao(values);
  21. }
  22. @Override
  23. public boolean onCreate() {
  24. myDataBase =new MyDataBase(this.getContext());
  25. return false;
  26. }
  27. @Override
  28. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
  29. return myDataBase.queryDao(projection,selection,selectionArgs,sortOrder);
  30. }
  31. @Override
  32. public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
  33. return 0;
  34. }
  35. @Override
  36. public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
  37. return 0;
  38. }
  39. }

(4)manifest文件中配置自定义的contentProvider类,代码如下:

  1. <provider
  2. android:name=".MyContentProvider"
  3. android:authorities="com.baorant.provider.MyContentProvider"
  4. android:enabled="true"
  5. android:exported="true">
  6. </provider>

到此为止,contentProvider内容提供方的代码基本OK,我们下面一起看下内容访问者APP的代码。

二、contentResolver数据访问方

(1)manifest文件中对要访问的APP的包名进行一个query权限的配置,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools">
  4. <queries>
  5. <package android:name="com.baorant.providerapplication"/>
  6. </queries>
  7. ...

(2)新建activity执行contentProvider的访问操作,代码如下:

  1. import androidx.appcompat.app.AppCompatActivity;
  2. import android.annotation.SuppressLint;
  3. import android.content.ContentResolver;
  4. import android.content.ContentValues;
  5. import android.database.Cursor;
  6. import android.net.Uri;
  7. import android.os.Bundle;
  8. import android.util.Log;
  9. import android.view.View;
  10. import android.widget.Button;
  11. import android.widget.TextView;
  12. /**
  13. * @author baorant
  14. */
  15. public class MainActivity extends AppCompatActivity {
  16. private final StringBuffer stringBuffer = new StringBuffer();
  17. Button resovlerQueryBtn;
  18. Button resovlerInsertBtn;
  19. TextView resovlerText;
  20. final int[] count = {0};
  21. @Override
  22. protected void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.activity_main);
  25. resovlerQueryBtn = findViewById(R.id.queryBtn);
  26. resovlerInsertBtn = findViewById(R.id.insertBtn);
  27. resovlerText = findViewById(R.id.text);
  28. ContentResolver resolver = getContentResolver();
  29. ContentValues values = new ContentValues();
  30. values.put("name", "sb");
  31. values.put("age", "20");
  32. Uri uri = Uri.parse("content://com.baorant.provider.MyContentProvider/student");
  33. resovlerQueryBtn.setOnClickListener(v -> {
  34. Cursor cursor = resolver.query(uri, null, null, null, null);
  35. // 清除之前的数据
  36. stringBuffer.delete(0, stringBuffer.toString().length());
  37. while (cursor.moveToNext()) {
  38. @SuppressLint("Range") String name = cursor.getString(cursor.
  39. getColumnIndex("name"));
  40. @SuppressLint("Range") int age = cursor.getInt(cursor.
  41. getColumnIndex("age"));
  42. @SuppressLint("Range") int id = cursor.getInt(cursor.
  43. getColumnIndex("id"));
  44. Log.d("db", "id=" + id + "|name=" + name + "|age=" + age);
  45. stringBuffer.append("id=").append(id).append("|name=").append(name).append("|age=").append(age);
  46. }
  47. resovlerText.setText(stringBuffer.toString());
  48. }
  49. );
  50. ContentValues contentValues = new ContentValues();
  51. resovlerInsertBtn.setOnClickListener(v -> {
  52. // 先清空之前已经插入的数据
  53. contentValues.clear();
  54. contentValues.put("name", "name" + count[0]);
  55. contentValues.put("age", count[0]);
  56. count[0]++;
  57. resolver.insert(uri, contentValues);
  58. });
  59. }
  60. }

(3)activity对应的layout布局文件,代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <TextView
  9. android:id="@+id/text"
  10. android:layout_margin="10dp"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:gravity="center_horizontal"
  14. android:text="resolver text!"
  15. app:layout_constraintTop_toTopOf="parent" />
  16. <Button
  17. android:id="@+id/queryBtn"
  18. android:layout_margin="10dp"
  19. android:layout_width="match_parent"
  20. android:layout_height="wrap_content"
  21. android:gravity="center_horizontal"
  22. android:text="查询结果!"
  23. app:layout_constraintTop_toBottomOf="@id/text" />
  24. <Button
  25. android:id="@+id/insertBtn"
  26. android:layout_margin="10dp"
  27. android:layout_width="match_parent"
  28. android:layout_height="wrap_content"
  29. android:gravity="center_horizontal"
  30. android:text="插入一条数据!"
  31. app:layout_constraintTop_toBottomOf="@id/queryBtn" />
  32. </androidx.constraintlayout.widget.ConstraintLayout>

到此,内容提供方APP和内容访问方APP的代码基本OK,现在先运行内容提供方APP的代码,让内容提供方APP先跑起来。然后运行内容访问方APP的代码。内容访问方页面提供了两个按钮,一个用来查询,一个用来插入数,还有一个textView显示内容查询结果。我们点击几次插入按钮后,再点击查询按钮进行结果的查询,运行结果如下所示:

image.png

问题总结

本文先初步介绍下contentProvider的基本使用,后面会继续介绍contentProvider的源码执行逻辑以及应用启动过程contentProvider的执行流程,有兴趣的同学可以进一步深入研究。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/874116
推荐阅读
  

闽ICP备14008679号