ContentProvider、AsyncTaskLoader

2024-05-11 03:18

本文主要是介绍ContentProvider、AsyncTaskLoader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

IPC 进程间通信 在android中每个app都是独立的进程

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@Overrideprotected 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>...<providerandroid: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;@Overrideprotected 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对象的idBundle 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对象*/@Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {//new CursorLoader(上下文,使用cursorLoader异步加载contentProvider数据的uri地址,查询字段,// 查询的条件,查询条件占位符,排序字段)//之前使用ContentResolver访问provider提供数据现在变成使用cursorloaderCursorLoader 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对象加载获取的数据结果*/@Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {cursorAdapter.swapCursor(data);//将查询获取的cursor对象加载到适配器中Log.i("tag","-----onLoadFinished----");}/*** 表示loader重载或者是退出时回调的函数* @param loader*/@Overridepublic 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);}@Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) {return LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item,null);}@Overridepublic 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)));}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main,menu);return true;}@Overridepublic 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表中的自增的主键idUri newUri=resolver.insert(ContactsContract.RawContacts.CONTENT_URI,new ContentValues());//content://con/person/3long 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、AsyncTaskLoader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/978353

相关文章

Android Service、 BroadcastReceiver、ContentProvider ANR 原理详解

Service ANR: 启动Service 的时候,会调用到ActiveServices 类的 realStartServiceLocked方法。 private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) throws RemoteException {

Android创建自己的内容提供器(ContentProvider)

文章目录 Android创建自己的内容提供器(ContentProvider)创建内容提供器的步骤新建MyProvider继承自ContentProvider内容URI的格式修改MyProvider中的代码MIME类型 Android创建自己的内容提供器(ContentProvider) 在上一节当中,我们学习了如何在自己的程序中访问其他应用程序的数据。总体来说思路还是非常简

安卓中使用ContentProvider获取和添加联系人

一样,因为这是对通讯录进行操作,因此我们需要添加相应的权限。 <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> 代码如下所示: package com.itfom.co

ContentProvider query操作过程源码分析(Android Q)

ContentProvider query调用过程源码分析(Android Q) ContentProvider 是 Android 的四大组件之一,可以很方便的跨进程查询数据,那么 Android 系统是如何实现 ContentProvider 的查询等操作的呢? ContentProvider 的使用示例 我们首先来看一个 ContentProvider 调用示例: pub

Android开发入门之监听ContentProvider中数据的变化

新建Aapp工程,向主页面添加一个按钮 public void insert(View v) {Uri uri = Uri.parse("content://cn.leigo.providers.personprovider/person");ContentResolver resolver = this.getContentResolver();ContentValues values

Android开发入门之采用ContentProvider对外共享数据

在cn.leigo,db下新建PersonProvider类,该类集成ContentProvider: package cn.leigo.db;import android.content.ContentProvider;import android.content.ContentValues;import android.database.Cursor;import android.

Android ContentProvider之联系人数据库及操作

通讯录数据库的主要表之间架构关系: 第一层:Data层,每种独立的数据类型占一行。具体哪些独立的数据可以占一行,可以在mimetypes这张表中找到, 原生Android的系统 一共12种,例如name,phone,email ect.. 第二层:RawContracts层,由Data层的多条数据组合成一个完整的联系人信息。 第 三层:Contracts层,这一

Android 进阶11:进程通信之 ContentProvider 内容提供者

学习启舰大神,每篇文章写一句励志的话,与大家共勉。 When you are content to be simply yourself and don’t compare or compete, everyone will respect you. 当你满足于做自己而不去比较或竞争时,每个人都会尊重你。 读完本文你将了解: ContentProvider 简介Content

ContentProvider解析

1.ContentProvider是什么: 四大组件之一用于共享数据。多个进程间共享数据,可以通过共享文件的方法,而共享文件的话,权限自己怎么控制呢?ContentProvider让开发者能够在拥有读写权限的情况下通过一条地址(比如content://com.fool/tab1)来访问共享数据。 2.应用场景 android 中许多系统软件和应用软件都使用该方式实现数据共享,比如电话本,相片,