2

我在ListFragment(即在ViewPager之內)中有一個CursorLoader查詢數據庫。我有一個該數據庫的內容提供者,我已經驗證了它的作用。CursorLoader未顯示DB entires

的問題是這樣的:當應用程序在第一次單獨的服務調用批量插入ContentProvider運行:

public int bulkInsert(Uri uri, ContentValues[] values) { 
    if(LOGV) Log.v(TAG, "insert(uri=" + uri + ", values" + values.toString() + ")"); 

    final SQLiteDatabase db = openHelper.getWritableDatabase(); 
    final int match = uriMatcher.match(uri); 

    switch(match) { 
     case SNAP: { 
      db.beginTransaction(); 
      for(ContentValues cv : values) { 
       db.insertOrThrow(Tables.SNAP, null, cv);       
      } 
      db.setTransactionSuccessful(); 
      db.endTransaction(); 

      getContext().getApplicationContext().getContentResolver().notifyChange(uri, null); 
      return values.length; 
     } 

列表中的片段回報的CursorLoader 0行,雖然在第一次運行(當數據庫被創建時)。如果我關閉並重新啓動應用程序,那麼CursorLoader工作得很好,並返回我所需要的。我試圖通過處理程序實現等待,但似乎沒有幫助。這裏是ListFragment利用的CursorLoader

public class DataBySnapFragment extends ListFragment implements LoaderCallbacks<Cursor> { 
    public static final String TAG = "DataBySnapFragment"; 

    protected Cursor cursor = null; 
    private DataBySnapAdapter adapter; 

    private Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
      Log.d(TAG, "RELOADING!!!!!"); 
      onLoadDelay(); 
     } 
    }; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     Log.d(TAG, "onActivityCreated"); 

     adapter = new DataBySnapAdapter(getActivity(), 
             R.layout.list_item_databysnap, 
             null, 
             new String[]{}, 
             new int[]{}, 
             0); 
     setListAdapter(adapter);   
     getLoaderManager().initLoader(0, null, this);  
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_databysnap, null); 
     return view; 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("error_workaround_1", 
          "workaroundforerror:Issue 19917, 
          http://code.google.com/p/android/issues/detail?id=19917"); 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     CursorLoader cursorLoader = new CursorLoader(getActivity(), 
                Snap.CONTENT_URI, 
                null, 
                null, 
                null, 
                Snap.DATA_MONTH_TO_DATE + " DESC LIMIT 6"); 

     return cursorLoader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     Log.d(TAG, "data rows: " + data.getCount()); 
     if(data.getCount() <= 0) { 
      delayThread(); 
     } else { 
      adapter.swapCursor(data);   
     } 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     adapter.swapCursor(null); 
    } 

    private void onLoadDelay() { 
     getLoaderManager().initLoader(0, null, this);  
    } 

    private void delayThread() { 
     new Thread() { 
      public void run() { 
       longTimeMethod(); 
       handler.sendEmptyMessage(0); 
      } 
     }.start(); 
    } 

    private void longTimeMethod() { 
     try { 
      Thread.sleep(12000); 
     } catch (InterruptedException e) { 
      Log.e("tag", e.getMessage()); 
     } 
    } 
} 

任何人都可以讓我知道這可能是爲什麼發生的,或者至少引導我朝着正確的方向?謝謝!

回答

0

除非你拖延主線程,否則創建一個新線程並告訴它入睡並不能真正解決任何問題。

我真的不知道究竟會出現什麼問題,但聽起來您可能需要刷新數據。要測試你可以嘗試使用OnClickListener創建一個刷新數據內容的按鈕,並從數據庫中重新獲取它。

+0

我想實現一個ContentProvider的處理所有的清爽?我能夠通過綁定到最初寫入ContentProvider的服務來實現它。一旦服務通知其完成,那麼如果我調用getLoaderManager()。initLoader(0,null,this);它工作得很好。 但我很好奇,如果有一部分內容proivder,或SQLiteOpenHelper我沒有正確實現,會導致它不刷新時,它應該。 – Chris 2012-02-13 21:14:15

0

每當你的批量插入完成,你應該發回一個消息到實現LoaderManager.LoaderCallbacks接口的片段/活動。 當活動/片段收到消息時,您需要調用getLoaderManager()。restartLoader(0,null,this)來重新查詢數據庫。

這是個什麼樣的應用程序確實太http://developer.android.com/guide/topics/fundamentals/loaders.html

0

嘗試修改onLoadFinished這樣:

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    Log.d(TAG, "data rows: " + data.getCount()); 
    if(data.getCount() <= 0) { 
     delayThread(); 
    } else { 
     // set the notification for the cursor 
     data.setNotificationUri(getActivity().getContentResolver(), Snap.CONTENT_URI); 
     adapter.swapCursor(data);   
    } 
}