2016-05-08 13 views
11

私はDBを照会するためにCursorLoaderを使用する主なアクティビティAを持っています。この私が活動のonCreate()メソッドで作成した:CursorLoader onLoaderReset()がデバイスローテーション後に呼び出されるのはなぜですか?

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ... 
    getSupportLoaderManager().initLoader(LOADER_MEASUREMENTS, null, A.this); 
} 

アクティビティAはまたCursorLoader 3つのコールバックを実装します。私は、デバイスを回転させる場合

public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) 
public void onLoaderReset(Loader<Cursor> loader) 

は、私が実行正しいライフサイクル・メソッドを参照してください。

A.onPause() 
A.onStop() 
A.onDestroy()   
A.onCreate()  <-- re-connect to existing loader, onCreateLoader() not called 
A.onLoadFinished() 
A.onStart() 
A.onResume() 

次に、サブアクティビティBを開き、デバイスを回転させます。私はBを終えるとアクティビティAに戻ったとき、私は次の実行を参照してください。私は活動Bが開いていたし、デバイスの回転をしたので

B.onPause() 
     A.onLoaderReset()  <- why does this run? 
     A.onDestroy()   
     A.onCreate() 
     A.onCreateLoader()  <- now runs as loader is null 
     A.onStart() 
     ... 

をなぜローダリセットされますか?そのアクティビティBは、DBまたはCursorLoaderとは関係がないことを追加するだけです。

+2

[この質問](http://stackoverflow.com/questions/15897547/loader-unable-to-retain-itself-during-certain-configuration-change?lq=1)とそこに関連する質問があります。おそらくあなたが助けてくれるものを見つけることができます。 –

+0

Georgeさん、ありがとうございます。その質問は私が持っている問題とまったく同じです。サポートローダーマネージャーのようだと思われます。 – MickeyR

+2

[link](https://code.google.com/p/android/issues/detail?id=183783)には、これはv24で修正される予定です。 – MickeyR

答えて

1

これはLoaderManagerと関係があり、活動状態を保持していないようです。

LoaderManagerは、このクラスのandroid.app.FragmentHostCallbackvoid doLoaderStop(boolean retain)で管理されています。引数に応じて、retain()またはstop()ローダーのいずれかになります。

アクティビティA(画面を回転させる)で設定を変更すると、アクティビティが破棄されてすぐに再作成されます。 ActivityThread#handleRelaunchActivity()には、mChangingConfigurationsの値がtrueに設定されています。設定変更のあなたの活動を停止したときに、これはActivityに呼び出されるので、これは、重要です:

final void performStop() { 
    mDoReportFullyDrawn = false; 
    mFragments.doLoaderStop(mChangingConfigurations /*retain*/); 
    // ... 
} 

あなたはあなたのアンドロイドインストールはソースを持っている必要があり、grepこの—を行うことが素晴らしいです—何が起こるのかを深く下降してみてください私は残りを要約します。

免責事項:私は徹底的に以下を確認していなかったが、これは何が起こっているのか私は理解しています。リニューアルのためのフィット活動が見られたときに、上記の図から分かるように

それはにそれらを停止ローダーの代わりを保持します。アクティビティAを回転すると、ローダーが保持されます。アクティビティBを回転すると、アクティビティBはすぐに再作成され、アクティビティAはただ破棄されます。前とは逆に、ローダーは停止します。

停止されたローダーは、LoaderManagerに見られるように破棄して再作成することができます。これがあなたの状況です。

あなたは良いを取る自分を見て、チェックアウトしたい場合:

  • app/LoaderManagerまたはv4/app/LoaderManager
  • app/FragmentHostCallback
  • ActivityActivityThread
1

をあなたは単に内部のブレークポイントを設定することができます.onLoaderReset()を実行し、アプリケーションをデバッグモードで実行して、somethinを使用したトラブルシューティングのスタックトレースを確認します。以下のようなグラム:

class A extends Activity implements LoaderManager.LoaderCallbacks 
{ 
    @Override 
    public void onLoaderReset(Loader loader) 
    { 
     try 
     { 
      // Constructs a new Exception that includes the current stack trace. 
      throw new Exception(); 
     } 
     catch (Exception e) 
     { 
      Log.d("TAG", Log.getStackTraceString(e)); 
     } 
    } 
} 
3

私はLoaderManagersource codeをチェックしますが、この方法を見つけることができます:

/** 
    * Stops and removes the loader with the given ID. If this loader 
    * had previously reported data to the client through 
    * {@link LoaderCallbacks#onLoadFinished(Loader, Object)}, a call 
    * will be made to {@link LoaderCallbacks#onLoaderReset(Loader)}. 
    */ 
    public abstract void destroyLoader(int id); 

(による構成の変更を)画面を回転させたときに、ローダーが破壊されることを表示されます。 LoaderManagerは、内部でdestroyLoaderメソッドを呼び出すと、onLoaderResetコールバックメソッドが呼び出されます。

関連する問題