文章目录
ContentProvider概述
- ContentProvider是不同应用程序间共享数据的一个组件。
- 为什么使用?通过数据持久化,.db或者SP(SharedPreferences)中的数据的仅限于被创建的应用所访问,无法做到应用程序间的数据交互和共享。而内容提供者就相当于对外部提供了一个操作当前应用数据库表的API,通过UriMatcher匹配相应的uri,达到对数据库中不同表CRUD的操作。
自定义ContentProvider
-
四大组件模式大同小异,首先编写一个类,XXXService继承Service,XXXActivity继承自Activity,内容提供者当然继承自ContentProvider,这里以UserProvider为例,实现对user表数据的CRUD。
URI: 统一资源标识符(Uniform Resource Identifier), 它和URL(统一资源定位符)什么关系呢,其实URI和URL都可以标识web主机上的资源,但URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。而URI是对资源的抽象,实际应用还是URI居多。
URI分为系统预制(已经定义好了相应的约束)和自定义,下面以自定义作为讲解。
uriMatcher:外部若想对当前应用进行访问,必须能够匹配uriMatcher中的uri。两个主要方法:UriMatcher.addURI(String authorities, String path, int code)
每个参数 的含义下面都已经有所标明。UriMatcher.match(Uri uri)
对第三方传递的uri进行匹配。
public class UserProvider extends ContentProvider { public static final String TAG = "UserProvider"; private static UriMatcher sUriMatcher = null; private static final int MATH_CODE = 1; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); /** * addURI(String authority, String path, int code); * authority:添加匹配规则,对应Manifest中的authorities * path:一般标识表名 和intent-filter中的schema有点类似 * code:dangURI被匹配之后会返回后面的matchCode */ sUriMatcher.addURI("cn.wjx.contentprovider", "user", MATH_CODE); } private UserDatabaseHelper mUserDatabaseHelper; @Override public boolean onCreate() { // 这里面就可以获取上下文Context,然后初始化操作数据库的Help对象 mUserDatabaseHelper = new UserDatabaseHelper(getContext()); return false; } @Override public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { int match = sUriMatcher.match(uri); // 若匹配成功 if (match == MATH_CODE) { SQLiteDatabase sqLiteDatabase = mUserDatabaseHelper.getReadableDatabase(); return sqLiteDatabase.query(Constants.TB_NAME, projection, selection, selectionArgs, null, null, sortOrder); } else { throw new IllegalArgumentException("Uri not match!"); } } @Override public String getType( Uri uri) { return null; } @Override public Uri insert( Uri uri, ContentValues values) { int match = sUriMatcher.match(uri); // 若匹配成功 if (match == MATH_CODE) { SQLiteDatabase sqLiteDatabase = mUserDatabaseHelper.getReadableDatabase(); long id = sqLiteDatabase.insert(Constants.TB_NAME, null, values); Uri uri0 = Uri.parse("content://cn.wjx.contentprovider/user/"+id); Log.d(TAG, "insert: user id-->"+id); // 插入数据成功,通知其他应用(谁监听通知谁) getContext().getContentResolver().notifyChange(uri0, null); return uri0; } else { throw new IllegalArgumentException("Uri not match!"); } } @Override public int delete( Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
-
清单文件中进行注册,authorities相当于令牌,外部应用如果想要操作当前app,必须通过设置uri,然后UserProvider类中的UriMathcer会匹配外部app传递过来的uri来查看是否有权限操作当前app中的数据。
authorities可以是多个,以";"进行分隔。<provider android:authorities="cn.