2012-04-30 3 views
2

나는 이것을 해결하기 위해 많은 시간을 보냈으며 도움이 필요합니다. 안드로이드는 화면 회전 후 중첩 된 AsyncTask onPostExecute에서 데이터를 저장합니다.

나는 내 안드로이드 앱 활동에 중첩 된 AsyncTask를이 있고 나는 그것을 처리가 새로운 AsyncTask를 시작하지 않고있어하는 동안 사용자가 자신의 휴대 전화를 회전 할 수 있도록하고 싶습니다. onRetainNonConfigurationInstance() 및 getLastNonConfigurationInstance()를 사용하려고했습니다.

작업을 유지할 수 있습니다. 그러나 회전 후에는 onPostExecute()의 결과를 외부 클래스 변수에 저장하지 않습니다. 물론, 나는 getters와 setters를 시도했다. onPostExecute에 변수를 덤프하면 정상입니다. 하지만 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를 참조하여 인스턴스화 된 첫 번째 활동에 대한 참조를 유지합니다.

이 권리를 수행하는 방법의 예를 들어

, https://github.com/commonsguy/cw-android/tree/master/Rotation/RotationAsync/

를 참조하십시오 당신은 그가 첨부()이 문제를 해결하기 위해 자신의 RotationAwareTask() 메서드를 분리가 표시됩니다.

화면 방향 변경 (onRetainNonConfigurationInstance 사용) 사이에 유지하면 AsyncTask 내의 OuterClass.this 참조가 항상 첫 번째 인스턴스화 된 Activity를 가리키는 지 확인하려면 기본값으로 매번 증가하는 정적 카운터를 사용할 수 있습니다 생성자의 카운트로 설정된 인스턴스 수준의 변수를 유지 한 다음 인쇄하십시오.

+0

감사합니다. 많이 관리했습니다. – JCZ

관련 문제