2012-04-30 13 views
2

私はこれに対する解決策を探し求めており、助けが必要です。画面の回転後にAndroidがネストされたAsyncTaskのonPostExecuteからデータを保存します

私はAndroidアプリのアクティビティにネストされたAsyncTaskを持っています。新しいAsyncTaskを開始することなく、処理中に自分の電話機を回転させたいと考えています。私はonRetainNonConfigurationInstance()とgetLastNonConfigurationInstance()を使用しようとしました。

私はタスクを保持することができます。ローテーション後には、onPostExecute()の結果を外側のクラス変数に保存しません。もちろん、私はゲッターとセッターを試しました。変数をonPostExecuteにダンプするとOKです。しかし、onClickリスナーから変数にアクセスしようとするとnullになります。

多分、コードが問題をはっきりさせるでしょう。

public class MainActivity extends BaseActivity { 

    private String possibleResults = null; 
    private Object task = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      this.task = getLastNonConfigurationInstance(); 

      setContentView(R.layout.menu); 

      if ((savedInstanceState != null) 
          && (savedInstanceState.containsKey("possibleResults"))) { 
        this.possibleResults = savedInstanceState 
            .getString("possibleResults"); 
      } 

      if (this.possibleResults == null) { 
        if (this.task != null) { 
          if (this.task instanceof PossibleResultWebService) { 
            ((PossibleResultWebService) this.task).attach(); 
          } 

        } else { 
          this.task = new PossibleResultWebService(); 
          ((PossibleResultWebService) this.task).execute(this.matchToken); 
        } 
      } 

      Button button; 
      button = (Button) findViewById(R.id.menu_resultButton); 
      button.setOnClickListener(resultListener); 
    } 

    @Override 
    protected void onResume() { 
      super.onResume(); 
    } 

    OnClickListener resultListener = new OnClickListener() { 
      @Override 
      public void onClick(View v) { 

        Spinner s = (Spinner) findViewById(R.id.menu_heatSpinner); 
        int heatNo = s.getSelectedItemPosition() + 1; 
        Intent myIntent = new Intent(MainActivity.this, 
            ResultActivity.class); 
        myIntent.putExtra("matchToken", MainActivity.this.matchToken); 
        myIntent.putExtra("heatNo", String.valueOf(heatNo)); 
        myIntent.putExtra("possibleResults", 
            MainActivity.this.possibleResults); 

        MainActivity.this.startActivityForResult(myIntent, ADD_RESULT); 
      } 
    }; 

    private class PossibleResultWebService extends AsyncTask<String, Integer, Integer> { 

      private ProgressDialog pd; 
      private InputStream is; 
      private boolean finished = false; 
      private String possibleResults = null; 

      public boolean isFinished() { 
        return finished; 
      } 

      public String getPossibleResults() { 
        return possibleResults; 
      } 

      @Override 
      protected Integer doInBackground(String... params) { 
       // quite long code 
      } 

      public void attach() { 
        if (this.finished == false) { 
          pd = ProgressDialog.show(MainActivity.this, "Please wait...", 
              "Loading data...", true, false); 
        } 
      } 

      public void detach() { 
        pd.dismiss(); 
      } 

      @Override 
      protected void onPreExecute() { 
        pd = ProgressDialog.show(MainActivity.this, "Please wait...", 
            "Loading data...", true, false); 
      } 

      @Override 
      protected void onPostExecute(Integer result) { 
        possibleResults = convertStreamToString(is); 
        MainActivity.this.possibleResults = possibleResults; 

        pd.dismiss(); 
        this.finished = true; 
      } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 

      super.onSaveInstanceState(outState); 

      if (this.possibleResults != null) { 
        outState.putString("possibleResults", this.possibleResults); 
      } 

    } 

    @Override 
    public Object onRetainNonConfigurationInstance() { 
      if (this.task instanceof PossibleResultWebService) { 
        ((PossibleResultWebService) this.task).detach(); 
      } 
      return (this.task); 
    } 

}

あなたはOnClickListenerあなたが活動をインスタンス化するたびに(そのたびに新鮮な、新しい、OuterClass.this参照を取得している)を作成しているので、それがある
+0

asynctaskを有効にすることを検討してください。アクティビティは、データをフェッチしてメモリに保存するサービスを開始します。アクティビティが同じデータに対してもう一度尋ねると、サービスは格納されたデータを提供することができます。 –

答えて

0

、しかし、あなたはAsyncTaskを保存していますアクティビティのインスタンス化の間に、OuterClass.thisを参照して、インスタンス化されたアクティビティの最初のインスタンスへの参照を保持します。この権利を行う方法の例については

、あなたは彼が添付()およびこの問題を解決するための彼のRotationAwareTaskで()メソッドを切り離した表示されますhttps://github.com/commonsguy/cw-android/tree/master/Rotation/RotationAsync/

を参照してください。

AsyncTask内のOuterClass.this参照が、画面の向きの変更(onRetainNonConfigurationInstanceを使用)の間に維持すると、AsyncTask内の最初のインスタンス化されたアクティビティを常にポイントすることを確認するには、デフォルトで毎回増加する静的カウンタを使用できます。各作成時のカウントに設定されたインスタンスレベルの変数を保持してから、それを印刷します。

+0

ありがとう、私はそれを管理している! – JCZ

関連する問題