1

CursorLoader を使用して Fragment で SQLite からデータを取得しています。このための initLoader() は onActivityCreated() で実行されます...

public class MyFragment extends Fragment implements LoaderCallbacks<Cursor>
{
    MenuItem menuItemOne;

    @Override
    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {
        inflater.inflate(R.menu.myMenu, menu);
        menuItemOne = menu.findItem(R.id.menuItemOne);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
    {
        menuItemOne.doSomething();
    }
}

上記のコードは、読みやすくするために単純化されています。ここに私の問題があります...

  • Nexus Sでは問題ありません。
  • Nexus 7では、onLoadFinishedで null ポインターが発生します。ここでは menuItemOne は null です。

Nexus S は Android 4.1.2 を使用しており、Nexus 7 は Android 4.2.2 を使用しています。

  • 他の場所で initLoader() を実行する必要がありますか?
  • Android のバージョンにバグや違いがあると思いますか?
4

2 に答える 2

1

ここに私の他の考えがあります:

public class MyFragment extends Fragment implements LoaderCallbacks<Cursor>
{
    MenuItem menuItemOne;
    boolean executeMenuItemAction = false;

    @Override
    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
    {
        inflater.inflate(R.menu.myMenu, menu);
        menuItemOne = menu.findItem(R.id.menuItemOne);
        if(executeMenuItemAction )
            menuItemOne.doSomething();
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
    {
        executeMenuItemAction = true;
        getActivity.invalidateOptionsMenu(); //or getActivity().supportInvalidateOptionsMenu() if you are using sherlock
    }
}
于 2013-04-09T13:25:38.047 に答える
1

それらは異なるデバイスであるため、確かに違いがあります。

しかし、おそらく/おそらく、あなたが見ているのははるかに微妙なエラーです. N7 での DB アクセスは、Nexus S よりもはるかに高速です。そのため、メニューが作成される前でも onLoadFinished が呼び出されます。

このコードの大きな誤りは、定義された順序で完了するために、非同期で完全に独立したプロセスに依存していることです。

実行を保証するために、さまざまなコールバックでロードを開始するか、以下のコードのようなスキームを実行できます。

Cursor c;

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
    inflater.inflate(R.menu.myMenu, menu);
    menuItemOne = menu.findItem(R.id.menuItemOne);
    loadFinishMenuInflated();
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
     c = cursor;
     loadFinishMenuInflated();
}

private void loadFinishMenuInflated(){
    if(c!=null && menuItemOne!=null){
       // do something...
    }
}

// do somethingそうすれば、両方のアイテムが初期化された後にのみ実行されることを保証できます。

于 2013-04-09T13:16:17.793 に答える