一个
个人理解:ContentProvider对应的还有一个ContentResolver,它们的作用就是,应用之间数据的交互,举个例子就是:一个工程是ContentProvider,一个工程是ContentResolver。ContentProvider的数据库可以给ContentResolver访问。
步骤:
我们就先写ContentProvider吧。创一个工程(不是activity,而是工程)。然后类继承ContentProvider。其中要重写的方法就有CRUD了。这里的CRUD的作用是当另一个工程访问该工程数据库时,该工程时如何返回数据给另一个工程的。
好吧,上代码:
/*
操作student的provider类
*/
public class StudentProvider extends ContentProvider {
private DBHelper dbHelper;
//里面参数代表的是,当查询不到时,然会这个参数,这个参数的值为-1
private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
//com.example.mycotentprovider.studentprovider/student 不根据id查询
//com.example.mycotentprovider.studentprovider/student/3 根据id查询
//保存一些合法uri
static {
//里面的code并不是要查询的id,而是标识它是根据id查询还是不是根据id查询,也就是1是根据id查询,2是不跟据id查询
matcher.addURI("com.example.mycotentprovider.studentprovider","/student",1);
matcher.addURI("com.example.mycotentprovider.studentprovider","/student/#",2);// #匹配任意数字
}
public StudentProvider(){
Log.e("TAG","StudentProvider()");
}
@Override
public boolean onCreate() {
dbHelper=new DBHelper(getContext());
Log.e("TAG","StudentProvider() onCreate()");
return false;
}
//com.example.mycotentprovider.studentprovider/student 不根据id查询
//com.example.mycotentprovider.studentprovider/student/3 根据id查询
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
Log.e("TAG","StudentProvider() query");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri,返回code
int code = matcher.match(uri);
if(code==1){//不根据id查询
Cursor cursor = database.query("student", projection, selection, selectionArgs, null, null, null);
return cursor;
}else if(code==2){//根据id查询
//得到id
long id = ContentUris.parseId(uri);
Cursor cursor = database.query("student", projection, "_id=?", new String[]{id+""}, null, null, null);
return cursor;
}else{
throw new RuntimeException("查询Uri不合法");
}
}
//不知道干什么的....(不理它)
@Nullable
@Override
public String getType(@NonNull Uri uri) {
Log.e("TAG","StudentProvider() getType");
return null;
}
//添加数据
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
Log.e("TAG","StudentProvider() insert");
SQLiteDatabase database = dbHelper.getReadableDatabase();
int code=matcher.match(uri);
if(code==1){
long id = database.insert("student", null, values);
uri=ContentUris.withAppendedId(uri,id);
database.close();
return uri;
}else{
database.close();
throw new RuntimeException("添加Uri不合法");
}
}
/*
根据id和不跟据id删除
*/
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
Log.e("TAG","StudentProvider() delete");
SQLiteDatabase database=dbHelper.getReadableDatabase();
int code = matcher.match(uri);
int deleteCount = -1;
if(code==1){
deleteCount = database.delete("student", selection, selectionArgs);
}else if(code==2){
long id =ContentUris.parseId(uri);
deleteCount = database.delete("student", "_id=" + id, null);
}else{
database.close();
throw new RuntimeException("删除Uri不合法");
}
database.close();
return deleteCount;
}
//根据id或不根据id更新
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
Log.e("TAG","StudentProvider() update");
SQLiteDatabase database=dbHelper.getReadableDatabase();
int code = matcher.match(uri);
int count=-1;
if(code==1){
count=database.update("student",values,selection,selectionArgs);
}else if(code==2){
long id = ContentUris.parseId(uri);
count=database.update("student",values,"_id="+id,null);
}else{
database.close();
throw new RuntimeException("更新Uri不合法");
}
return count;
}
}
上面每个CRUD的方法里面都有code,code是标识,是去判断传过来的Uri是根据id还是不根据id。因为另一个工程是来取数据。所以这个工程下也得要有个sql数据库。这样为什么是sql数据库呢,个人理解是。如果是mysql之类的数据库…是联网请求数据的。那另一个工程直接联网请求不香吗…
差点忘了。由于要将数据库数据提供给另一个工程。所以要记得配置文件
<provider
android:authorities="com.example.mycotentprovider.studentprovider"
android:name="com.example.mycotentprovider.StudentProvider"
android:exported="true"/>
其中authorities是唯一标识。然后exported的默认值是false。true代表运行别的应用程序访问。authorities一般都设为全类名,然后全部小写。
ContentResolver代码:
public class MyContentResolver extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_content_resolver);
}
public void query(View view){
//1,得到ContentResolver对象
ContentResolver resolver=this.getContentResolver();
//2,调用其query,得到cursor
Uri uri=Uri.parse("content://com.example.mycotentprovider.studentprovider/student/1");
Cursor cursor = resolver.query(uri, null, null, null, null);
//3,取出cursor中的数据,并显示
if(cursor.moveToNext()){
int id=cursor.getInt(0);
String name=cursor.getString(1);
Toast.makeText(this,id+"-----"+name,Toast.LENGTH_SHORT).show();
}
}
public void insert(View view){
ContentResolver resolver=getContentResolver();
Uri uri=Uri.parse("content://com.example.mycotentprovider.studentprovider/student/");
ContentValues values=new ContentValues();
values.put("name","Sam");
Uri insert = resolver.insert(uri, values);
Toast.makeText(this,uri.toString()+"",Toast.LENGTH_SHORT).show();
}
public void update(View view){
ContentResolver resolver=getContentResolver();
Uri uri=Uri.parse("content://com.example.mycotentprovider.studentprovider/student/2");
ContentValues values=new ContentValues();
values.put("name","jack");
int updateCount = resolver.update(uri, values, null, null);
Toast.makeText(this,""+updateCount,Toast.LENGTH_SHORT).show();
}
public void delete(View view){
ContentResolver resolver=getContentResolver();
Uri uri=Uri.parse("content://com.example.mycotentprovider.studentprovider/student/2");
int deleteCount = resolver.delete(uri, null, null);
Toast.makeText(this,""+deleteCount,Toast.LENGTH_SHORT).show();
}
}
上面的就不讲太多了吧。就是通过合法的Uri,然后通过ContentResolver的对象调用相对应的方法。