zoukankan      html  css  js  c++  java
  • Android-ContentProvider流程

    Android-ContentProvider原理及流程

    Android为什么设计出一个ContentProvider ?

    答:ContentProvider的出现主要是暴露数据出去,暴露什么数据呢 (暴露数据库SqliteDatabase里面的数据),由ContentProvider管控好增删改查,让其他应用程序来访问增删改查

      Android设计了intent-filter对外暴露(可以隐式意图激活/远程服务绑定通讯)这属于最组件的暴露,而ContentProvider属于数据库的暴露

      ContentProvider属于四大组件之一,Android把它设计成组件,说明ContentProvider是很重要的,Android操作系统源码APP几乎都大量用ContentProvider暴露了数据。

    流程图:

    注意:在ContentProvider里面写对数据库增删改查的时候,千万不能 db.close();  cursor.close(); 等操作,不然其他应用访问不到数据,也没有必要写isOpen();


    ContentProviderServer应用

    ContentProvider是抽象类,所以写一个类继承ContentProvider,重写增删改查系列方法

    package liudeli.cp.server.cp;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.util.Log;
    
    public class MyContentProvider extends ContentProvider {
    
        private final String TAG = MyContentProvider.class.getSimpleName();
    
        /**
         * 只要在AndroidManifest.xml中配置了provider组件
         * 应用打开后,会自动启动此方法
         * @return
         */
        @Override
        public boolean onCreate() {
            Log.d(TAG, "onCreate()");
            return false;
        }
    
        /**
         * 查询
         * @param uri 其他应用传递过来的Uri
         * @param projection 其他应用传递过来的查询列
         * @param selection 其他应用传递过来的查询条件
         * @param selectionArgs 其他应用传递过来的查询条件参数值
         * @param sortOrder 其他应用传递过来的排序
         * @return
         */
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            Log.d(TAG, "查询到了数据....");
            return null;
        }
    
        /**
         * 增加
         * @param uri 其他应用传递过来的Uri
         * @param values  其他应用传递过来的ContentValues
         * @return
         */
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            Log.d(TAG, "插入了数据....");
            return null;
        }
    
        /**
         * 修改
         * @param uri 其他应用传递过来的Uri
         * @param values 其他应用传递过来的ContentValues
         * @param selection 其他应用传递过来的查询条件
         * @param selectionArgs 其他应用传递过来的查询条件参数值
         * @return
         */
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            Log.d(TAG, "修改了数据....");
            return 0;
        }
    
        /**
         * 删除
         * @param uri 其他应用传递过来的Uri
         * @param selection 其他应用传递过来的查询条件
         * @param selectionArgs 其他应用传递过来的查询条件参数值
         * @return
         */
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            Log.d(TAG, "删除了数据....");
            return 0;
        }
    
    
        /**
         * 得到类型 在后续的博客中会有讲解到
         * @param uri
         * @return
         */
        @Override
        public String getType(Uri uri) {
            return null;
        }
    }

    在AndroidManifest.xml文件中,配置ContentProvider组件,然后对外暴露数据(设置授权唯一标识,允许对外输出,允许实例化激活)等操作

        <!--
                ContentProvider是组件需要配置
                可以把ContentProvider看作是服务器
                authorities 看作是服务器 服务器有访问的链接,authorities(授权) ,是唯一标识
                android:enabled="true" 可以被系统实例化
                android:exported="true" 允许对外输出
            -->
            <provider
                android:authorities="autho.prov.cp.MyContentProvider"
                android:name=".cp.MyContentProvider"
                android:enabled="true"
                android:exported="true"
                />

    启动ContentProviderServer应用,注意看:一启动ContentProviderServer应用,就会自动初始化  MyContentProvider --> onCreate()方法

    12-14 09:22:55.187 2013-2013/liudeli.cp.server D/MyContentProvider: onCreate()


    ContentProviderClient应用

    点击Test按钮,成功调用到 ContentProviderServer应用的 MyContentProvider -- > query() 方法

    package liudeli.cp.client;
    
    import android.content.ContentResolver;
    import android.net.Uri;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void test(View view) {
            /**
             * 可以想象客户端访问服务器,需要需要用到协议HTTP
             * 而想访问ContentProvider,需要ContentResolver
             */
            ContentResolver contentProvider = getContentResolver();
    
            /**
             * 可以想象访问服务器,需要这样拼接访问地址 http://
             * 而想访问ContentProvider,需要这样拼接访问地址 content://
             * 必须拿到暴露的授权authorities="autho.prov.cp.MyContentProvider" 进行拼接
             */
            Uri uri = Uri.parse("content://autho.prov.cp.MyContentProvider");
    
            // 查询
            contentProvider.query(uri, null, null, null, null, null);
    
            // 增加
            // contentProvider.insert(uri, null);
    
            // 修改
            // contentProvider.update(uri, null, null, null);
    
            // 删除
            // contentProvider.delete(uri, null, null);
        }
    }

    ContentProviderServer应用的 MyContentProvider -- > query() 方法

    12-14 09:44:59.955 2013-2031/liudeli.cp.server D/MyContentProvider: 查询到了数据....

  • 相关阅读:
    python基础-枚举定义错误码
    凸包-Graham扫描法
    [USACO04OPEN]MooFest
    [USACO16OPEN]262144
    [ASPNETCORE] 抛砖引玉,EFCORE 软删除和自动添加审计的实现
    java 文件读取汇总
    java 各类型转换 convert
    java 各类型初始化汇总
    java 常用类型占用字节数
    Maven 常用命令
  • 原文地址:https://www.cnblogs.com/android-deli/p/10121028.html
Copyright © 2011-2022 走看看