ContentProvider、AsyncTaskLoader
2016-10-14 21:39
176 查看
IPC 进程间通信 在android中每个app都是独立的进程
ContentProvider
内容提供者
它是一个提供共享数据访问接口的应用程序组件
例如:通讯录这个app允许它的数据被其它的app访问 就可以通过ContentProvider暴露对外访问数据的方式
访问通话纪录
如果app中需要将私有访问的数据共享给其它的app访问 就需要创建类继承ContentProvider 重写
相应的函数暴露数据访问的方式 增删改查
ContentProvider使用步骤:
1.创建类继承ContentProvider
2.重写相应的暴露数据访问接口的方法
3.注册ContentProvider
ContentProvider 服务端 需要共享数据的app
public class xx extends ContentProvider{
private static final UriMatcher matcher=new
UriMatcher(UriMatcher.NO_MATCH);
static{
matcher.adduri(String authority 自定义字符串 一般情况设置为包名,
String path 路径 自定义字符串 操作的表名 功能名称 * 表示匹配所有文本 # 表示匹配所有数字,
int code 表示client访问的uri地址与contentrovider提供的地址一致时返回的数字码);
…..
}
public Uri insert(Uri uri,ContentValues values){
if(matcher.match(uri)==数字码){
操作共享数据的插入
}
}
public Cursor query(Uri uri,String[] projection,String seletion,String[] seletionArgs,String sortOrder){
if(matcher.match(uri)==数字码){
操作共享数据的查询
}
}
public int update(Uri uri,ContentValues values,String seletion,String[] seletionArgs){
if(matcher.match(uri)==数字码){
操作共享数据的修改
}
}
public int delete(Uri uri,String seletion,String[] seletionArgs){
if(matcher.match(uri)==数字码){
操作共享数据的删除
}
}
}
全局清单文件中:
ContentResolver client客户端 专门访问ContentProvider暴露的数据
private ContentResolver resolver;
public class xxx extends Activity{
public void onCreate(Bundle…){
super.onCreate(..)
setContentView(R.layout.xxx);
resolver=getContentReslover();
Cursor cursor=resolver.query(xxxx);
resolver.insert(xxxx);
int count=resolver.update(xxxx);
int count2=resolver.delete(xxxxx);
}
}
AsyncTaskLoader:
Loader sdk3.0之后引入 异步加载数据
特点:使用Loader异步加载数据时 数据源发生改变时会直接将改变的数据展示到控件中 不需要重新查询
Loader可以在activity或者时fragment中使用
Loader 接口
AsyncTaskLoader 抽象类
CursorLoader主要适用场景:主要适合查询contentProvider提供的数据
使用步骤:
1.创建一个LoadManger对象
2.调用 initLoader()方法对loader进行初始化操作
ContentProvider
内容提供者
它是一个提供共享数据访问接口的应用程序组件
例如:通讯录这个app允许它的数据被其它的app访问 就可以通过ContentProvider暴露对外访问数据的方式
访问通话纪录
public class MainActivity extends AppCompatActivity { private ListView lv; private ContentResolver resolver;//内容观察者 解析者 获取ContentProvider暴露的数据 // private String callLog="content://call_log/calls"; //字符串 private Uri callLogUri= CallLog.Calls.CONTENT_URI;//常量形式uri @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv= (ListView) findViewById(R.id.lv); resolver=getContentResolver();//实例化 //调用ContentResolver中的query()方法查询contentprovider提供的数据 Cursor cursor=resolver.query(callLogUri,null,null,null,null); SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.list_item,cursor, new String[]{CallLog.Calls.NUMBER,CallLog.Calls.DATE,CallLog.Calls.TYPE}, // new String[]{"number","date","type"} new int[]{R.id.tv_number,R.id.tv_date,R.id.tv_type}, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(adapter); } }
如果app中需要将私有访问的数据共享给其它的app访问 就需要创建类继承ContentProvider 重写
相应的函数暴露数据访问的方式 增删改查
ContentProvider使用步骤:
1.创建类继承ContentProvider
2.重写相应的暴露数据访问接口的方法
3.注册ContentProvider
ContentProvider 服务端 需要共享数据的app
public class xx extends ContentProvider{
private static final UriMatcher matcher=new
UriMatcher(UriMatcher.NO_MATCH);
static{
matcher.adduri(String authority 自定义字符串 一般情况设置为包名,
String path 路径 自定义字符串 操作的表名 功能名称 * 表示匹配所有文本 # 表示匹配所有数字,
int code 表示client访问的uri地址与contentrovider提供的地址一致时返回的数字码);
…..
}
public Uri insert(Uri uri,ContentValues values){
if(matcher.match(uri)==数字码){
操作共享数据的插入
}
}
public Cursor query(Uri uri,String[] projection,String seletion,String[] seletionArgs,String sortOrder){
if(matcher.match(uri)==数字码){
操作共享数据的查询
}
}
public int update(Uri uri,ContentValues values,String seletion,String[] seletionArgs){
if(matcher.match(uri)==数字码){
操作共享数据的修改
}
}
public int delete(Uri uri,String seletion,String[] seletionArgs){
if(matcher.match(uri)==数字码){
操作共享数据的删除
}
}
}
全局清单文件中:
<application> ... <provider android:authorities="自定义字符串 matcher.adduri中的指定的权限一致即可" android:name="当前住的contentrovider的包名.类名" android:exported="true" 表示允许程序的数据被其它app访问/> ... </applicaiton>
ContentResolver client客户端 专门访问ContentProvider暴露的数据
private ContentResolver resolver;
public class xxx extends Activity{
public void onCreate(Bundle…){
super.onCreate(..)
setContentView(R.layout.xxx);
resolver=getContentReslover();
Cursor cursor=resolver.query(xxxx);
resolver.insert(xxxx);
int count=resolver.update(xxxx);
int count2=resolver.delete(xxxxx);
}
}
AsyncTaskLoader:
Loader sdk3.0之后引入 异步加载数据
特点:使用Loader异步加载数据时 数据源发生改变时会直接将改变的数据展示到控件中 不需要重新查询
Loader可以在activity或者时fragment中使用
Loader 接口
AsyncTaskLoader 抽象类
CursorLoader主要适用场景:主要适合查询contentProvider提供的数据
使用步骤:
1.创建一个LoadManger对象
2.调用 initLoader()方法对loader进行初始化操作
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{ private ListView lv; private LoaderManager manager; private MyCursorAdapter cursorAdapter; private ContentResolver resolver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv= (ListView) findViewById(R.id.lv); resolver=getContentResolver(); ////实例化 LoadManger对象 每个Activity或者Fragment只能存在一个 LoaderManger对象 // 一个 LoadManger可以管理多个 Loader对象 manager=getLoaderManager(); /* 对Loader进行初始化 initLoader(int id, Bundle args,LoaderManager.LoaderCallbacks<D> callback) 如果不存在loader对象则直接创建 如果存在则复用最后创建的 Loader对象 int id, 表示唯一标示当前loader对象的id Bundle args, 可选参数 表示传递到loader对象中的参数 LoaderManager.LoaderCallbacks<D> callback 回调接口 包括回调函数 针对loader不同状态会回调 范型 表示使用当前初始化的loader对象异步加载数据的类型 */ Bundle bundle=new Bundle(); bundle.putString("key","annsngsgdofrgldghgfh"); manager.initLoader(1,bundle,this); cursorAdapter=new MyCursorAdapter(this,null,CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(cursorAdapter); } /** * 表示创建loader对象时回调的函数 * @param id 初始化指定的loader的id标示 * @param args * @return 创建完成的loader对象 */ @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { //new CursorLoader(上下文,使用cursorLoader异步加载contentProvider数据的uri地址,查询字段, // 查询的条件,查询条件占位符,排序字段) //之前使用ContentResolver访问provider提供数据现在变成使用cursorloader CursorLoader loader=new CursorLoader(MainActivity.this, ContactsContract.Contacts.CONTENT_URI, null,null,null,null); Log.i("tag","-----onCreateLoader----"+args.getString("key")); return loader; } /** * 表示loader加载完毕数据时回调的函数 * @param loader 创建的loader * @param data 表示通过loader对象加载获取的数据结果 */ @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { cursorAdapter.swapCursor(data);//将查询获取的cursor对象加载到适配器中 Log.i("tag","-----onLoadFinished----"); } /** * 表示loader重载或者是退出时回调的函数 * @param loader */ @Override public void onLoaderReset(Loader<Cursor> loader) { cursorAdapter.swapCursor(null); Log.i("tag","-----onLoaderReset----"); } public class MyCursorAdapter extends CursorAdapter{ public MyCursorAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item,null); } @Override public void bindView(View view, Context context, Cursor cursor) { TextView tv_id= (TextView) view.findViewById(R.id.tv_id); TextView tv_displayName= (TextView) view.findViewById(R.id.tv_displayname); tv_id.setText(cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID))+""); tv_displayName.setText(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main,menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.action_add://向系统通讯录应用中的 raw_contact表中插入联系人姓名和id // content://con/person insert content://con/person/3 //向raw_contact表中插入一条空纪录 目的是为了得到raw_contact表中的自增的主键id Uri newUri=resolver.insert(ContactsContract.RawContacts.CONTENT_URI, new ContentValues());//content://con/person/3 long contactId= ContentUris.parseId(newUri);//3 //获取raw_contactId name mimtType data表中插入 ContentValues values=new ContentValues(); values.put(ContactsContract.Data.RAW_CONTACT_ID,contactId); values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,"赵六赵六"); resolver.insert(ContactsContract.Data.CONTENT_URI,values); break; } return super.onOptionsItemSelected(item); } }
相关文章推荐
- contentprovider实例总结
- ContentProvider
- Android ContentProvider使用样例
- ContentProvider浅析---写点你平时没注意到
- ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结
- android中ContentProvider实现联系人的读取和插入
- ContentProvider和Uri详解
- ContentProvider
- ContentProvider详解
- contentprovider 总结(三)
- contentprovider的示例代码
- ContentProvider
- 使用AsyncTaskLoader获取本地数据(图片)
- 创建数据库,并定义ContentProvider接口
- android contentprovider的使用(二)
- 使用 ContentProvider 管理联系人(包括每人有多个电话号码)
- 四大基本组件之ContentProvider
- ContentProvider(内容提供者)简单运用
- Android四大核心组件之contentProvider
- ContentProvider的用法与理解