2012-03-06 13 views
2

私はいつかAsyncTaskを使用していました。私が直面する最大の問題は、アプリケーションのクラッシュが多く、レンダリングが何度も起こることです。たとえば、特定のレイアウトにデータを設定してレンダリングしてから画面を回転させると、レイアウト全体が別のGETリクエストとともにサーバーに送信され、データがレンダリングされます。それについてはあまり気にしなかったし、ツイッターでも同じ問題があったと思った。彼らはそれを修正したようだ。サービスでAsyncTaskを使用中に状態を保存する方法は?

このように、AsyncTaskはサービスでどのように使用されるのですか、参照できるinstancestateもあり、画面が回転したときやアプリがクラッシュしたときも確認できます。

答えて

3

私はアクティビティでasynctaskと同様の問題がありました。画面の回転でアクティビティが破棄され、再作成されてasynctaskが再作成されました。簡単ですが、エレガントではない

  • :あなたの活動のためのあなたのマニフェストでconfigChangesは=「方向」:アンドロイドで破壊されてからの活動を防ぐこの問題を解決するには

  • ビットコンプレックス:現在のアクティビティコントロールを格納するクラスを作成し、onRetainNonConfigurationInstanceに保存してonCreateに復元します。 asynctaskが開始されると、アクティビティに直接話すのではなく、このクラスと交信して循環します。あなたが望むなら、私はいくつかのコードを提供することができます(それは少しです)。

編集:ここにいくつかのコードがあります。

 package com.ybi; 

     import android.app.Activity; 
     import android.os.AsyncTask; 
     import android.os.Bundle; 
     import android.widget.TextView; 

     public class EmptyShellActivity extends Activity { 

      private ActivityControl activityControl; 
      private EmptyShellTask emptyShellTask; 

      private TextView textView; 


      @Override 
      protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       setContentView(R.layout.main); 
       textView = (TextView)findViewById(R.id.textView1); 
       restoreFromObject(); 
      } 

      @Override 
      public Object onRetainNonConfigurationInstance() { 
       activityControl.textView = null; 
       return activityControl; 
      } 

      private void restoreFromObject() { 
       activityControl = (ActivityControl) getLastNonConfigurationInstance(); 
       if (activityControl == null) { 
        activityControl = new ActivityControl(); 
        activityControl.textView = textView; 
        activityControl.textView.setText("Doing"); 
        emptyShellTask = new EmptyShellTask(); 
        emptyShellTask.execute((Void[])null); 
       } else { 
        activityControl.textView = textView; 
        if (activityControl.isInProgress) 
         activityControl.textView.setText("Doing"); 
        else 
         activityControl.textView.setText("Done"); 
       } 
      } 

      protected class ActivityControl { 
       protected boolean isInProgress; 
       protected TextView textView; 
      } 

      private class EmptyShellTask extends 
      AsyncTask<Void, Void, Void> { 

       @Override 
       protected Void doInBackground(Void... params) { 
        activityControl.isInProgress = true; 
        try { 
          Thread.sleep(3000); 
        } catch (InterruptedException e) { 
         // say something 
        } 
        return null; 
       } 

       @Override 
       protected void onPostExecute(Void result) { 
        super.onPostExecute(result); 
        activityControl.isInProgress = false; 
        activityControl.textView.setText("Done"); 
       } 
      } 
     } 

私のクラスからいくつか削除しました。私は通常、postExecuteにコードを記述するのではなく、インタフェースを使用します。 Done Doingの表示を繰り返すなど、どこでもUIを行うコードが存在しないようにするのに役立ちます。

さらに進んで(進捗管理、タスクのキャンセル、エラー管理など)したい場合は、面白いコードがあります。唯一の問題は、それが急速に非常に非常に複雑になることです。

+0

コードを入力してください。それは本当に役に立ちます。 – Hick

+1

これは優れたコード例です。 – Hick

+0

ここでは、前のビューの日付はどこに保存されていますか?私はこれを実装して実装しました:activityControl.textView.setText(user.firstName + "" + user.lastName);しかし、テキストは最初のインスタンスでのみ設定されます。それから私は電話を回すたびに、「完了」に設定されます。 – Hick

関連する問題