ContentProvider

ContentProvider是Android四大组件之一,用于实现应用程序间的数据共享。它允许一个应用通过ContentResolver访问其他应用的数据,如数据库中的内容。自定义ContentProvider需要创建数据库,继承ContentProvider并重写相关方法。在使用ContentProvider时,需在清单文件中注册,并可以通过自定义权限提高安全性。

1.ContentProvider是Android四大组件之一,其特点是能够实现进程间应用程序的共享。

2.数据在Android的应用程序中是私有的,该类数据包括文件数据、数据库数据以及其他类型的数据。因此要进行数据间的共享及传递数据,就要创建一个ContentProvider。因为一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型,即一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去。

解决问题需要运用知识点:ContentProvider的使用,进程内数据共享,进程间数据共享,自定义权限。

定义:ContentProvider是操作其他应用程序内容的组件

内涵:可以操作其他运用程序,运用间数据共享

如何定义内容提供者:

内容提供方:ContentProvider

内容获取放:ContentResolver

谈到内容提供者,大家就应该想到提供方和索要方,之前我们获取手机联系人,提供方是系统APP本身,索要方是我们;现在,我们想要做提供方,别人来访问我们的数据库,那我们就需要自定义内容提供者了。

(1)数据库默认是私有的,不能被其他app访问,只能通过内容提供者访问            

(2)内容提供者是安卓的四大组件之一,必须在清单文件中注册

思路:

1.提供方moudle:ContentProvider

(1)创建数据库,自定义类继承SQLiteOpenHelper

(2)自定义内容提供者类,继承ContentProvider,重写insert/delete/update/query方法,向外界提供方法

(3)清单文件中注册内容提供者 第2步和第3步可以通过快捷键生成

2.索要方moudle:ContentResolver

(1)通过Context的getContentResolver方法获得ContentResolver对象

(2)确定uri(注意:前面一定要加conten://)

(3)调用insert/delete/update/query方法访问数据库

自定义权限使用场景

定义权限一般用于暴露出去的组件,提高安全性。Android允许一个应用(客户端)调用另一个应用(服务端)的组件。那么作为服务端的应用就得暴露相应的组件,客户端应用才能访问。当然,在暴露的时候,权限是非必须的,如果暴露的组件没有权限的话,那么任何的其他应用都可以来调用该组件;如果该组件申请了权限,那么只有拥有该权限的应用才能调用该组件。

 MySqlite mySqlite;
    SQLiteDatabase sqLiteDatabase;
    public MyContentProvider() {
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        int stu = sqLiteDatabase.delete("stu", selection, selectionArgs);
        return stu;
    }

    @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.
        sqLiteDatabase.insert("stu",null,values);
        return uri;
    }

    @Override
    public boolean onCreate() {
        mySqlite = new MySqlite(getContext(),"stu.db",null,1);
        sqLiteDatabase = mySqlite.getReadableDatabase();
        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.
        Cursor stu = sqLiteDatabase.query("stu", projection, selection, selectionArgs, null, null, sortOrder);
        return stu;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: Implement this to handle requests to update one or more rows.
        int stu = sqLiteDatabase.update("stu", values, selection, selectionArgs);
        return stu;
    }
ContentResolver contentResolver;
    Uri uri;
    private ListView lv;
    List<Student> students;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contentResolver = getContentResolver();
        uri = Uri.parse("content://com.bw.stu");
        lv = findViewById(R.id.lv);
    }

    public void insert(View view) {
        ContentValues contentValues  = new ContentValues();
        contentValues.put("name","牛马韩");
        contentValues.put("phone","54250");
        contentResolver.insert(uri,contentValues);
    }

    public void update(View view) {
        ContentValues contentValues = new ContentValues();
        contentValues.put("name","阿巴阿巴");
        contentResolver.update(uri,contentValues,"name=?",new String[]{"牛马韩"});
    }

    public void delete(View view) {
        contentResolver.delete(uri,"name=?",new String[]{"牛马韩"});
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void query(View view) {
        students = new ArrayList<>();
        Cursor query = contentResolver.query(uri, null, null, null, null,null);
        if (query!=null){
            while (query.moveToNext()) {
                String name = query.getString(query.getColumnIndexOrThrow("name"));
                String phone = query.getString(query.getColumnIndexOrThrow("phone"));
                Student student = new Student(name,phone);
                students.add(student);
            }
        }
        MyAdapter myAdapter = new MyAdapter();
        lv.setAdapter(myAdapter);
    }

    class MyAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return students.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item,null);
            TextView name = view.findViewById(R.id.name);
            TextView phone = view.findViewById(R.id.phone);
            name.setText(students.get(i).getName());
            phone.setText(students.get(i).getPhone());
            return view;
        }
    }

<think>好的,用户想了解Android开发中ContentProvider的用法和示例。首先,我需要回顾ContentProvider的基本概念,它是Android四大组件之一,主要用于不同应用间的数据共享。接着,要说明它的核心作用,比如封装数据访问、提供统一接口等。 然后,用户可能需要知道如何创建自定义的ContentProvider。这包括继承ContentProvider类,实现必要的方法如query、insert、update、delete等。还需要提到在AndroidManifest.xml中注册Provider,并设置android:exported属性来控制是否对外暴露。引用中的内容提到android:exported=false可以限制仅供内部使用,这点很重要,特别是涉及安全性的问题,必须包含进去。 接下来,应该给出一个简单的示例代码,展示如何定义ContentProvider的子类,并实现各个方法。同时,示例中的UriMatcher和SQLiteOpenHelper的使用也是关键点,需要解释清楚。代码部分要注意使用正确的格式,并确保语法正确。 另外,用户可能关心ContentProvider的使用场景,比如数据共享、与CursorLoader结合使用等。还要提到ContentResolver的用法,因为这是访问Provider的主要方式。需要强调线程安全,引用中提到5.4节关于线程安全的内容,应该指出在实现时需要注意同步机制,避免多线程问题。 最后,生成相关问题时要围绕用户可能进一步想知道的内容,比如如何限制访问权限、与数据库交互的细节、性能优化等。确保问题覆盖常见的使用场景和潜在的问题点,帮助用户深入理解。 现在需要检查回答是否符合系统指令,比如行内公式是否正确使用(虽然这里可能用不上,但要注意其他格式要求),独立公式是否单独成段,中文回答,以及引用标识是否正确添加。同时,确保示例代码正确,并且引用的内容自然插入到回答中,比如在讲解注册Provider时引用[^2],在讲解线程安全时引用[^1]等。 总结步骤:介绍ContentProvider的作用,创建步骤,示例代码,使用场景,安全配置,线程安全,最后生成相关问题。确保每个部分都清晰,并且引用正确。</think>### ContentProviderAndroid开发中的使用及示例 ContentProviderAndroid四大组件之一,主要用于**跨应用数据共享**,提供标准化的数据访问接口。以下是其核心知识点: #### 一、核心作用 1. **数据封装**:将数据源(如SQLite、文件、网络)封装为统一的访问接口。 2. **跨进程通信**:通过URI标识数据路径,支持其他应用通过ContentResolver访问数据。 3. **权限控制**:通过AndroidManifest.xml定义读写权限,例如: ```xml <provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:exported="false" <!-- 禁止外部访问 --> android:readPermission="android.permission.READ_DATA" android:writePermission="android.permission.WRITE_DATA"/> ``` 通过`android:exported=false`可限制仅供内部使用[^1]。 #### 二、自定义ContentProvider步骤 1. **继承ContentProvider类**并实现六个核心方法: ```java public class MyProvider extends ContentProvider { @Override public boolean onCreate() { // 初始化数据库等操作 return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询数据逻辑 } // 实现insert、update、delete、getType方法 } ``` 2. **定义数据URI**: ```java private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { uriMatcher.addURI("com.example.provider", "books", 1); // 匹配路径:/books } ``` #### 三、数据访问示例 通过ContentResolver操作数据: ```java // 查询数据 Cursor cursor = getContentResolver().query( Uri.parse("content://com.example.provider/books"), null, null, null, null ); // 插入数据 ContentValues values = new ContentValues(); values.put("title", "Android Guide"); getContentResolver().insert(uri, values); ``` #### 四、线程安全与性能 1. **线程安全**:ContentProvider方法默认运行在主线程,需自行实现同步机制(如使用`synchronized`块)。 2. **数据库优化**:建议配合SQLiteOpenHelper管理数据库连接,避免频繁打开关闭。 #### 五、典型应用场景 1. 应用内多个模块共享同一数据库 2. 向系统提供数据(如自定义联系人存储) 3. 与SyncAdapter配合实现后台数据同步
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值