【问题标题】:CursorLoader not showing DB entiresCursorLoader 不显示数据库条目
【发布时间】:2013-07-30 05:12:34
【问题描述】:

我在查询数据库的ListFragment(位于ViewPager 内)中有一个CursorLoader。我有一个该数据库的内容提供者,我已经验证了它的工作原理。

问题是这样的:当应用程序第一次运行时,一个单独的服务在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 会很好地返回我需要的内容。我试图通过处理程序实现等待,但它似乎没有帮助。这是利用CursorLoaderListFragment

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

谁能告诉我为什么会发生这种情况,或者至少引导我朝着正确的方向前进?谢谢!

【问题讨论】:

    标签: android database android-contentprovider android-cursorloader


    【解决方案1】:

    除非你暂停主线程,否则创建一个新线程并让它休眠并不能真正解决任何问题。

    我真的不能说到底可能出了什么问题,但听起来您可能需要刷新数据。要进行测试,您可以尝试制作一个带有 OnClickListener 的按钮来刷新数据内容,然后将其从数据库中重新拉出。

    【讨论】:

    • 我认为实现一个 ContentProvider 可以处理所有的刷新?我能够通过绑定到最初写入 ContentProvider 的服务来使其工作。一旦服务通知它完成,那么如果我调用 getLoaderManager().initLoader(0, null, this);它工作得很好。但是我很好奇内容提供程序的某些部分,或者我没有正确实现的 SQLiteOpenHelper 会导致它在应该刷新时不刷新。
    【解决方案2】:

    每当您的批量插入完成时,您应该将消息发送回实现 LoaderManager.LoaderCallbacks 接口的片段/活动。 当活动/片段收到消息时,您需要调用 getLoaderManager().restartLoader(0, null, this) 来重新查询数据库。

    这也是示例应用的作用http://developer.android.com/guide/topics/fundamentals/loaders.html

    【讨论】:

      【解决方案3】:

      尝试这样修改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);           
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-10
        相关资源
        最近更新 更多