ContentProvider如何自定义与使用场景是什么?
这道题想考察什么?
- 是否了解ContentProvider真实场景使用,是否熟悉ContentProvider使用场景?
考察的知识点
- ContentProvider在项目中使用与基本知识
考生应该如何回答
1.请你说下ContentProvider是什么?
答:
ContentProvider是Android提供的一个组件,主要用于实现统一管理和数据共享。这里的数据管理是通过定义统一的访问接口来实现,如增删改查。同时,它采用了类似Internet的URL机制,将数据以URI的形式来区分,这样其他App就可以采用一套标准的URI规范来访问同一处数据,而不用了解具体的实现细节。我们知道在Android系统中可能会涉及到一个App的数据被其他App使用的情况,比如通讯录,日历,短信等,这时就需要一套能实现数据共享的机制,这里的ContentProvider就可以实现此功能,其底层使用了binder来完成App进程之间的交流通信,同时使用匿名共享内存来作为共享数据的实现方法。当然为了保证数据访问的安全性,ContentProvider还对每处的数据URI添加了权限管理机制,以控制该数据的访问者及访问方式。
2.请你描述下如何自定义ContentProvider?
答:
ContentProvider提供了一套通用的数据访问接口:
public class MyContentProvider extends ContentProvider {
public MyContentProvider() {
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
初一看,这些接口跟数据库的访问接口类似。没错,ContentProvider就是特地来管理数据库中的数据的。那么既然作为通用的数据访问接口,ContentProvider为什么没有提供对普通文件的访问接口呢?我觉得是因为普通文件的数据是非结构化的,无法抽象出一套统一的访问接口,而数据库中的数据都是结构化数据,就相对比较简单了。
此外一般我们不会直接运用ContentProvider来访问,而是会通过ContentResolver来访问ContentProvider,是因为ContentProvider作为一个数据源处理中心,不仅仅给App内部使用,还会被其他App访问。所以这里的ContentProvider就好比一个server,其他的App在访问这个ContentProvider的时候都必须先得到一个Server的Client才行,这里的ContentResolver就是Android提供给开发者使用来得到一个ContentProvider Client的管理工具类。示例代码如下:
//根据号码获取联系人的姓名
public void getContactNameByNumber() throws Exception {
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Data.DISPLAY_NAME}, null, null, null);
if(cursor.moveToFirst()){
String name = cursor.getString(0);
Log.i(TAG, name);
}
cursor.close();
}
此外我们在创建一个ContentProvider组件的时候,必须要配置一个authorities,并且必须保证系统内该字段不重名,它就好比URL中的主机地址。示例如下:
<provider
android:name=".MyContentProvider"
android:authorities="com.xiaofei"
android:enabled="true"
android:exported="true">
最后再讲下为何ContentProvider在我们平时开发App中使用的不多?其实,虽然ContentProvider具有数据管理和数据共享的功能,但是大半的优势还是集中在数据共享上,在数据共享的前提下,这个数据管理的优势也才能更加明显。像一些系统内置应用,联系人,日历和短信,就比较合适使用ContentProvider,因为他们经常需要提供数据给其他App。而对于像普通的应用,一般出于安全原因,不会把数据提供给第三方App使用,而在App内部访问数据库的话,完全可以自己实现一套数据库访问框架,因为ContentProvider为了屏蔽数据库的访问细节,本质是在其基础上再封装了一层接口而已,而对于App内部的数据库访问来讲,没有这个必要,而且ContentProvider作为一个组件与系统依赖性较强,相比自己实现一套数据库管理框架,扩展性和灵活性肯定没那么好。当然也有很多第三方开源的数据库框架可用,比如greenDao,ormlite,realm等
3.你对ContentProvider的使用场景能画图举例吗:
答:
image.png例如:Android操作系统中,就提供联系人的ContentProvider去暴露联系人的所有数据,我们各个APP引用就可以使用Uri去访问这个联系人ContentProvider暴露出来的数据,有点类似 多个客户端 与 一个服务端的这种关系一样。
最后
有需要面试题的朋友可以关注一下哇哇,以上都可以分享!!!
网友评论