-1

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

  1. 应用程序启动服务,这将从服务器上下载数据并存储 它分贝
  2. 应用程序使用CursorLoader从资料库

问题是第一次加载数据,就不会有任何数据以db为单位,直到服务下载数据并存储它。当发生这种情况时,CursorLoader不会从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; 
} 

这些都是装载机callbacks

@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); 
} 

我失去的是什么?即使我使用getContext().getContentResolver().notifyChange(uri, null),但它仍不刷新Cursor一些指导将不胜感激。

回答

1

错误!有一些我错过了。我花时间在这个问题上到处找,然后我走进文件,我发现这种方法

/** 
* 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);

我希望这会帮助别人。 :)