2012-05-26 12 views
17

私はAsyncTaskについて学び、サブクラスではなく別のクラスとして使いたいと思っています。例えばAndroid、AsyncTaskを別のクラスに配置してコールバックできますか?

class inetloader extends AsyncTask<String, Void, String> { 


    @Override 
    protected String doInBackground(String... urls) { 

     String response = ""; 

      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(urls[0]); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       InputStream content = execute.getEntity().getContent(); 

       BufferedReader buffer = new BufferedReader(
         new InputStreamReader(content)); 
       String s = ""; 
       while ((s = buffer.readLine()) != null) { 
        response += s; 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     return response; 
    } 


    @Override 
    protected void onPostExecute(String result) { 
     Log.e("xx",result); 
     // how do I pass this result back to the thread, that created me? 
    } 


} 

とメイン(UI)スレッド:

inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 
//il.onResult() 
//{ 
    ///do something... 
//} 

ありがとう!

+1

はい、あなたは別のクラスに入れることができますが、ほとんどの人はそのpurpo seは通常、内部クラスの場合はもっとはっきりしています。あなたが多くの活動でそれを再利用しようとしているなら、先に進んでください。 – keyser

+0

私は別の目的のために使用する予定です、ここから呼び出すと結果が得られるはずですが、そこから呼び出すと、結果には何か他のことが起きるはずです...そのため、同じクラスの中で、そのクラスの結果を関数から呼び出すようにするには、結果として得られるすべてのアクションに対して新しいAsyncTaskを作成する必要があります。 –

+0

インターフェイスを使用して、 AsynクラスのonPostExcute()でmContext.implementedMethod()を呼び出します。 –

答えて

32

インターフェイスを使用します。ような何か:inetloaderで

inetloader il = new inetloader(); 
li.setListener(this); 
il.execute("http://www.google.com"); 

、追加:

CallBackListener mListener; 

    public void setListener(CallBackListener listener){ 
    mListener = listener; 
    } 

その後、postExecuteで()、実行します。

mListener.callback(); 

interface CallBackListener{ 
    public void callback(); 
} 

は、その後、あなたのUIスレッドでこれを行います

+0

おかげさまで、それは正しい方向ですね。特に、inetloader il = new inetloader()を使用してCallBackListenerを作成できる場合は、それをilオブジェクトに渡します。 –

+0

うーん...奇妙なことに、私はアンドロイドv3で "CallBackListener"を持っていない、別の名前で行くのだろうか? –

+3

@RogerTravisはい、自分でCallBackListenerインターフェイスを作成する必要があります。メインUIクラスに「CallBackLisnterを実装する」を追加することを忘れないでください。 –

1
inetloader il = new inetloader(); 
il.execute("http://www.google.com"); 

String result = il.get();//put it in try-catch 
       ^^^^^^^^ 

here you get result which is in onPostExecute(String result)

+0

さて、実際には、いくつかのサーバーのクエリに時間がかかることがあるので、AsyncTaskが完了した後にトリガーするような、ある種のonResultリスナーが必要です。一方、il.get()をwhile(true)ループあまりにも原始的に聞こえるかもしれませんが、それはありませんか?:)もっと良い選択肢はありますか? –

+2

@Samir:これは本当に悪い考えです。 'AsyncTask'から結果を取得することができますが、' get() 'メソッドを使用するとUIスレッドがブロックされ、非同期プロシージャであるべきものを同期スレッドに効果的に変換します。 'get()'メソッドの唯一の有効な使い方は、2つの 'AsyncTasks'を '連鎖'することです。 – Squonk

3

あなたは
使用インタフェースと同じように...コンストラクタとそこから活動関数を呼び出すアクティビティのインスタンスを渡すことができます。

public interface ResultUpdatable { 

    public void setResult(Object obj); 
    } 

アクティビティでこれを実装して渡しますAsyncタスクのコンストラクタを呼び出し、onPostExecuteの結果をsetResult関数を使用して更新します。

関連する問題