android的五种存储方式分别是:
1,SharedPreferences
2,file
3,sqlite
4,contentproviter
5,http
ContentProvider
注意:
大多数ContentProvider使用Android文件系统或者SQLite数据库来保持数据,但是也可以以任何方式来存储。
在清单文件中注册一个自定义ContentProviter
<!--内容提供者,精准匹配-->
<provider
android:name=".content_provider.TestContentProvider"
android:authorities="com.lh.knowledge.contentprovider"
android:exported="true" />
重写一个TestContentProvider类继承ContentProviter
public class TestContentProvider extends ContentProvider {
//这里的AUTHORITY就是我们在AndroidManifest.xml中配置的authorities
public static final String AUTHORITY = "com.lh.knowledge.contentprovider";
//匹配成功后的匹配码
private static final int MATCH_ALL_CODE = 100;
private static final int MATCH_ONE_CODE = 101;
private static UriMatcher uriMatcher;//uri匹配器
private Cursor cursor = null;//游标
List<TestBean> testBeanList = new ArrayList<>();
@Override
public boolean onCreate() {
initData();
//添加要匹配的uri,匹配不成功返回NO_MATCH(-1)
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
/**
* uriMatcher.addURI(authority, path, code); 其中
* authority:主机名(用于唯一标示一个ContentProvider,这个需要和清单文件中的authorities属性相同)
* path:路径路径(可以用来表示我们要操作的数据,路径的构建应根据业务而定)
* code:返回值(用于匹配uri的时候,作为匹配成功的返回值)
*/
uriMatcher.addURI(AUTHORITY, "student", MATCH_ALL_CODE);// 匹配记录集合
uriMatcher.addURI(AUTHORITY, "student/#", MATCH_ONE_CODE);// 匹配单条记录
return false;
}
private void initData() {
TestBean testBean1 = new TestBean();
testBean1.setId(1);
testBean1.setName("aaa");
testBean1.setPrice(5.2);
testBean1.setSex(false);
testBeanList.add(testBean1);
TestBean testBean2 = new TestBean();
testBean1.setId(2);
testBean1.setName("bbb");
testBean1.setPrice(6.2);
testBean1.setSex(true);
testBeanList.add(testBean2);
TestBean testBean3 = new TestBean();
testBean1.setId(3);
testBean1.setName("ccc");
testBean1.setPrice(0.2);
testBean1.setSex(false);
testBeanList.add(testBean3);
}
/**
* @param uri
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return
*/
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
//这里的查询需要配合sqlite来使用
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
int match = uriMatcher.match(uri);
if (match != MATCH_ALL_CODE) {//这里不能匹配集合,只能匹配单个
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
//
int indexId = values.getAsInteger("indexId");
Uri insertUri = ContentUris.withAppendedId(uri, indexId);
if (indexId > 0) {
TestBean testBean = new TestBean();
testBean.setId(indexId);
testBean.setName("content provider userid " + indexId);
testBeanList.add(testBean);
return insertUri;
}
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
//匹配uri
switch (uriMatcher.match(uri)) {
case MATCH_ALL_CODE://集合
int i = testBeanList.size();
testBeanList.clear();
return i;
case MATCH_ONE_CODE://单个
int postion = Integer.parseInt(selection);
testBeanList.remove(postion);
return 1;
default://抛出异常,没有匹配到uri
//throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
return 0;
}
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
int postion = Integer.parseInt(selection);
if (postion > testBeanList.size() - 1) return 0;
TestBean testBean = testBeanList.get(postion);
if (testBean == null) return 0;
String name = values.getAsString("name");
testBean.setName(name);
return 1;
}
}
如何使用ContentProvider来存储数据
public class ContentProviderActivity extends Activity {
private ContentResolver contentResolver;
private final Uri STUDENT_ALL_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student");
private final Uri STUDENT_ONE_URI = Uri.parse("content://" + TestContentProvider.AUTHORITY + "/student/#");
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
//这里说明内容提供者的uri正确,随机操作增删改查
/**
* @param uri
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return cursor
*/
Cursor cursorAll = contentResolver.query(STUDENT_ALL_URI, null, null, null, null);
//查询userid为1的用户
Cursor cursorOne = contentResolver.query(STUDENT_ONE_URI, null, "1", null, null);
//删除userid为2的用户,返回当前删除条数
int i = contentResolver.delete(STUDENT_ONE_URI, "2", null);
//修改
ContentValues contentValues = new ContentValues();
contentValues.put("name", "test");
int updateNumber = contentResolver.update(STUDENT_ONE_URI, contentValues, "1", null);
//这里的方法都与TestContentProvider中的方法相对应
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//获得内容提供者解析器
contentResolver = getContentResolver();
//注册内容观察者
contentResolver.registerContentObserver(STUDENT_ALL_URI, true, new PersonOberserver(handler));
}
/**
* 观察者,如果找到了当前uri的提供者,则会回调
*/
public class PersonOberserver extends ContentObserver {
private Handler handler;
public PersonOberserver(Handler handler) {
super(handler);
this.handler = handler;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//向handler发送消息,找到了当前的提供者
Message msg = new Message();
handler.sendMessage(msg);
}
}
ContentProviter能够跨进程的存储数据,通过调用相对应的方法能够增、删、改、查。