2016-05-25 3 views
0

Activityクラス内にAsyncTaskクラスを記述しても問題ありませんか?それとも別のファイルを作成する必要がありますか?しかし、この場合、UIを操作したり、AsyncTaskからUIを更新することはできませんでした。ですからAsyncTask用に別のファイルを作成する場合、どのようにしてActivityクラスのUIを更新できますか?前もって感謝します!Activityクラスの中にAsyncTaskクラスを置いても構いませんか?

+0

これは問題ありません。 –

+2

これは、タスクが完了したときにのみ収集されるそのアクティビティへの参照を保持するため、メモリリークの可能性を生み出します – tyczj

+0

2:55 mark https://www.youtube.com/watch? v = jtlRNNhane0&list = PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index = 4 – tyczj

答えて

1

Activityクラス内にAsyncTaskクラスを記述してもよろしいですか?

はい、問題はありません。それは、ビューコントローラから分離する、きれいなコーディングの問題です。また、メモリリークの問題を引き起こす可能性があります。 ActivityのリファレンスをAsyncTaskに渡すことはできますが、弱い参照のみにする必要があります。

UIを操作したり、AsyncTaskから更新できませんでした。ですから、 AsyncTaskの別のファイルを作成する場合は、 アクティビティクラスでUIを更新するにはどうすればよいですか?

この場合、UIを更新する方法はたくさんあります。 BroadcastReceiver,HandlerまたはInterfaceを使用できます。

私はあなたがInterfaceを使用することをお勧めします。なぜなら、それは最も簡単で、最も適切だと思います。ここで

はサンプルです:

あなたはAsyncTaskのために新しいファイルを作成します。 AsyncTaskをサブクラス化する新しいクラスを作成します。

public class DownloadTask extends AsyncTask<String, Float, Long> 
{ 
    public DownloadTaskListener mListener; 

    public interface DownloadTaskListener 
    { 
     public void onDownloadFinish(); 
     public void onDownloadProgress(float progress); 
    } 

    @Override 
    protected Long doInBackground(String... arg0) 
    { 
     //start downloading 

     return 0L; //return download size 
    } 

    protected void onProgressUpdate(Float... progress) 
    { 
     if(mListener != null) 
     { 
      mListener.onDownloadProgress(progress[0]); 
     } 
    } 

    protected void onPostExecute(Long result) 
    { 
     if(mListener != null) 
     { 
      mListener.onDownloadFinish(); 
     } 
    } 
} 

ここからわかるように、インターフェイスのこれらのメソッドを使用してUIの更新を通知できます。あなただけの参照を渡す

download.mListener = this; 

public class MainActivity extends Activity implements DownloadTaskListener 
{ 
    DownloadTask download = new DownloadTask(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     download.mListener = this; 
     download.execute("Download URL"); 
    } 

    @Override 
    public void onDownloadFinish() 
    { 
     MainActivity.this.runOnUiThread(new Runnable() 
     { 
      public void run() 
      { 
       //updates to UI here. 
      } 
     }); 
    } 

    @Override 
    public void onDownloadProgress(float progress) 
    { 
     MainActivity.this.runOnUiThread(new Runnable() 
     { 
      public void run() 
      { 
       //updates to UI here. 
      } 
     }); 
    } 
} 

は、この行を見てみましょう:あなたのMainActivityで

public interface DownloadTaskListener 
{ 
    public void onDownloadFinish(); 
    public void onDownloadProgress(float progress); 
} 

あなたは、コールバックがうまくいくように、そのインターフェイスに実装する必要がありますAsyncTaskがアクティビティのインターフェイスメソッドを呼び出してアクティビティを更新できるように、アクティビティの(インターフェイスの実装)を行います。

また、AsyncTaskはスレッドであることに注意してください。 UIのいくつかの変更を更新するときは、常にMain ThreadまたはUI Threadで行う必要があります。この部分をチェック:

MainActivity.this.runOnUiThread(new Runnable() 
      { 
       public void run() 
       { 

       } 
      }); 

申し訳ありませんが、ないプロ説明する人を私は、私はあなたのために、これは明らかにしたいと考えています。 :)

+0

私は思う、私はうんざりしています。どうもありがとうございました! –

+0

ようこそ。 :) –

0

はい、問題はありませんが、私の場合は別のファイルを使用しています。あなたはUIとインターキャットできonPostExecute方法で

  1. あなたはAsyncTaskに活動/フラグメントを渡し、onPostExecuteであなたの」UIを更新することができます。

  2. あなたは結果を得るためにインタフェース(コールバック)を使用することができます - Android - Jsoup: How to get RESULT from Jsoup.connect("url").get() from AsyncTask

私はあなたがそれをいずれかの方法を行うことができます第二オプション

0

を好みます。アクティビティそのものにAsyncTask Classを置くと、問題は発生しません。

私も別のファイルに私のAsyncTaskのクラスを維持することを好む、と私はUIと対話する方法は、このようなものです:

  • ポストに
  • onPostExecute
  • で適切なイベントをEventBusライブラリを使用しますあなたのアクティビティでそのイベントをキャッチし、実行する必要があるものは何でも実行してください。

これは、私が思うにははるかに明確な方法です。 EventBusを一度使用すれば、それは大好きです。

0

一般的に、ソフトウェア開発では は可能な限りカップリングを避けてください。 Androidフレームワーク、imho、UIをUIとバックグラウンドと考えている プロセス、サービスは別のものです。
私はカップリングが好きではないので、個人的には私はこのアプローチを使用しません。ユニットテストはお尻の痛みになります。しかし、このアプローチを選択する場合は、正確に何が求められるのかを考えなければなりません。
Q1:どのクラスを使いたいですか?
内部クラスまたは静的ネストされたクラス

- 内部クラス - 内部クラスの場合、クラスはその外側のクラスのメンバーであるためには、あなたは親インスタンスの変数とメンバーにアクセスすることができます。ここでは、ローテーション(アクティビティ)中にアクティビティ内のいくつかの変数が変更される可能性があるという問題があります。

- 静的ネストされたクラス - 静的ネストされたクラスは、外側のクラスのように振る舞うため、その囲みのクラスメンバ変数にアクセスすることはできません。それが使用できる唯一の方法は、オブジェクト参照によるものです。この方法は、基本的に、別のクラスと静的なネストされたクラスの間に違いがないことを伝えます。


EDIT - により上記の条件と1が実際にAndroidの中の回転に対処すべきであるという事実に回転

のためのいくつかの出発点、私は、次の概念を使用します。

//changed from activity to fragment if rotation is considered. 
public CustomFragment extends Fragment{ 

    @Override 
    void onCreate(Bundle saveInstance){ 
     super.onCreate(saveInstance); 
     //for avoiding rotation problems 
     setRetainInstance(true); 
     new CustomAsyncTask(this, callback).execute(); 
    } 

    public Callback callback = new Callback{ 
     @Override 
     public void onSuccess(){ 
      //do something 
     } 

     @Override 
     public void onFail(){ 
      //do something 
     } 

     @Override 
     public void onTaskStarted(){ 
      //start showing the progress dialog 
     } 

     @Override 
     public void onTaskInProgress(Integer value){ 
      //progress dialog has some method set progress, check it out 
     } 

    } 

    public interface Callback { 
     void onSuccess(); 
     void onFail(); 
     void onTaskStarted(); 
     void onTaskInProgress(Integer progress); 
    } 
} 


//asynctask class 

public class CustomAsyncTask extends AsyncTask<Void, Void, Void> { 

     private CustomFragment callback; 
     public AsyncCallerTickets(CustomFragment _callback){ 
      this.callback = _callback; 
     } 

     @Override 
     protected void onPreExecute() { 
     super.onPreExecute(); 
     callback.onTaskStarted(); 
     } 

     @Override 

    @Override 
    protected void onProgressUpdate(Integer...progress) { 
     callback.onTaskInProgress(progress[0]);  
    }  

    protected Void doInBackground(Void... params) { 
      //long process 
      return null; 
    } 


    @Override 
    protected void onPostExecute(Void result) { 
      super.onPostExecute(result); 
      //dialog.dismiss();? 
      if(result!=null){ 
       callback.onSucces(); 
      } 
      else{ 
       callback.onFail(); 
      } 
    } 
    } 


できるだけデカップリングされたものを持つことで、Androidの回転の痛みを和らげることができます。

+0

intsanceの場合、AsyncTaskは進行状況をコールバックで渡す必要がありますが、プログレスバーを更新する必要がありますか?私は間違いない? –

+0

各ステップでコールバックを使用します。たとえば、callback.onPreExecute、callback.onProgressなど –

+0

私はそのプログレスバーを使って例を表示できますか?アドバイスありがとう! –

関連する問題