Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用内容提供程序从数据库加载数据_Android_Android Contentprovider_Android Contentresolver_Android Cursorloader_Android Loadermanager - Fatal编程技术网

Android 使用内容提供程序从数据库加载数据

Android 使用内容提供程序从数据库加载数据,android,android-contentprovider,android-contentresolver,android-cursorloader,android-loadermanager,Android,Android Contentprovider,Android Contentresolver,Android Cursorloader,Android Loadermanager,我使用内容提供者来存储和检索数据库中的数据。这就是用户安装应用程序时应用程序中发生的情况 应用程序启动一项服务,该服务将从服务器下载数据并存储 它以db表示 应用程序正在使用CursorLoader从数据库加载数据 问题是,在服务下载并存储数据之前,数据库中第一次并没有任何数据。当这种情况发生时,CursorLoader不会从db加载数据。如果我关闭并重新打开应用程序,它会从db加载数据 这就是我如何使用ContentProvider @Override public int bulkInser

我使用内容提供者来存储和检索数据库中的数据。这就是用户安装应用程序时应用程序中发生的情况

  • 应用程序启动一项服务,该服务将从服务器下载数据并存储 它以db表示
  • 应用程序正在使用
    CursorLoader
    从数据库加载数据
  • 问题是,在服务下载并存储数据之前,数据库中第一次并没有任何数据。当这种情况发生时,CursorLoader不会从db加载数据。如果我关闭并重新打开应用程序,它会从db加载数据

    这就是我如何使用
    ContentProvider

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        final SQLiteDatabase db = feederDbHelper.getWritableDatabase();
        int match = sUriMatcher.match(uri);
        switch (match) {
            case CODE_INSERT_SOURCE:
                //Return the number of rows inserted from our implementation of bulkInsert
                return insertRecords(FeederContract.SourceEntry.TABLE_NAME, db, values, uri);
            case CODE_INSERT_ARTICLE:
                return insertRecords(FeederContract.ArticleEntry.TABLE_NAME, db, values, uri);
            default:
                return super.bulkInsert(uri, values);
        }
    }
    
    下面是
    insertRecords
    方法

    public int insertRecords(String tabbleName, SQLiteDatabase db, ContentValues[] values, Uri uri) {
            db.beginTransaction();
            int rowsInserted = 0;
            try {
                for (ContentValues value : values) {
                    long _id = db.insertWithOnConflict(tabbleName, null, value, SQLiteDatabase.CONFLICT_REPLACE);
                    if (_id != -1) {
                        rowsInserted++;
                    }
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
    
            if (rowsInserted > 0) {
                getContext().getContentResolver().notifyChange(uri, null);
            }
            //Return the number of rows inserted from our implementation of bulkInsert
            return rowsInserted;
        }
    
    以下是用户第一次启动应用程序时发生的情况。我也添加了评论

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.feeds_fragment, container, false);
        ButterKnife.bind(this, view);
        loadAd();
        initRc();
        // Starting service to download feeds
        FeederSyncUtil.startSync(getActivity());
        // Starting loader to load feeds
        getActivity().getSupportLoaderManager().initLoader(ID_FEEDS_LOADER, null, this); 
        return view;
    }
    
    这些是加载程序
    回调

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(getActivity(),
                FeederContract.ArticleEntry.CONTENT_URI,
                MAIN_FEED_PROJECTION,
                null,
                null,
                null);
    }
    
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Log.d(TAG, data.getCount() + "");
        mFeedsAdapter.swapCursor(data);
    }
    
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mFeedsAdapter.swapCursor(null);
    }
    
    @覆盖
    公共加载器onCreateLoader(int-id,Bundle-args){
    返回新的游标装入器(getActivity(),
    FeederContract.ArticleEntry.CONTENT\u URI,
    主馈电投影,
    无效的
    无效的
    无效);
    }
    @凌驾
    public void onLoadFinished(加载器、光标数据){
    Log.d(标记,data.getCount()+);
    mFeedsAdapter.swapCursor(数据);
    }
    @凌驾
    公共void onLoaderReset(加载器){
    mFeedsAdapter.swapCursor(空);
    }
    

    我错过了什么?尽管我使用的是
    getContext().getContentResolver().notifyChange(uri,null)
    ,但它仍然不会刷新
    光标
    ,请提供一些指导。

    错误!我遗漏了一些东西。我花了几个小时在这个问题上到处寻找,然后我进入文档,找到了这个方法

    /**
     * Register to watch a content URI for changes. This can be the URI of a specific data row (for 
     * example, "content://my_provider_type/23"), or a a generic URI for a content type.
     * 
     * @param cr The content resolver from the caller's context. The listener attached to 
     * this resolver will be notified.
     * @param uri The content URI to watch.
     */
    void setNotificationUri(ContentResolver cr, Uri uri);
    
    因此,我在提供者的
    query
    方法中添加了对该方法的连接调用。 下面是我的提供者的一些代码片段

     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            int match = sUriMatcher.match(uri);
            Cursor cursor = null;
            switch (match) {
                case CODE_INSERT_SOURCE:
                    cursor = feederDbHelper.getReadableDatabase().query(FeederContract.SourceEntry.TABLE_NAME,
                            projection,
                            selection,
                            selectionArgs,
                            null,
                            null,
                            sortOrder);
                    break;
                case CODE_VIEW_ARTICLE:
    
                    cursor = feederDbHelper.getReadableDatabase().query(FeederContract.ArticleEntry.TABLE_NAME,
                            projection,
                            selection,
                            selectionArgs,
                            null,
                            null,
                            sortOrder);
                    break;
    
                default:
                    throw new UnsupportedOperationException("Unknown uri " + uri);
            }
            cursor.setNotificationUri(getContext().getContentResolver(),uri);
            return cursor;
        }
    
    所以这一行
    cursor.setNotificationUri(getContext().getContentResolver(),uri)
    所有的魔力都在这里。当使用
    insert()
    delete()
    update()
    bulkInsert()
    对URI基础数据进行任何更改时,它会将更改通知contentresolver。 由于
    CursorLoader
    不会自动检测数据更改,我们需要使用
    setNotificationUri(ContentResolver cr,Uri-Uri)

    我希望这会对某人有所帮助。:)