2010-07-20 4 views
37

예를 들어 AsyncTask으로 확장되는 클래스 A에 대해 공통된 클래스가 있으며 모든 메소드가 구현되어 있습니다 (예 : onPreExecute, doinbackgroundonPostExecute).Android에서 AsyncTask의 공통 클래스는 무엇입니까?

이제 클래스 A 개체를 사용하려는 다른 클래스가 있습니다.

말 클래스 B는 그때 GET 메소드의 결과를 가져 오는 방식 아래

A a = new A(context) 
a.execute(url) 

클래스 A를 사용한다. 그러나 get 메소드는 AsyncTask를 사용하는 적절한 방법이 아닙니다. 결과는 onPostExecute입니다. 이를 위해 나는 onpostexecute에서만 true가 될 부울 매개 변수를 사용해 보았습니다. 클래스 B는 그것이 참이 될 때까지 검사 할 것이고 그것이 사실이되면 결과를 가져올 것입니다.

그러나 이는 어쨌든 응용 프로그램을 차단합니다.

아래에 asynctask 코드를 넣었습니다.

'

import java.io.IOException; 

import org.apache.http.client.ClientProtocolException; 

import org.apache.http.client.HttpClient; 

import org.apache.http.client.ResponseHandler; 

import org.apache.http.client.methods.HttpGet; 

import org.apache.http.impl.client.BasicResponseHandler; 

import org.apache.http.impl.client.DefaultHttpClient; 


import android.app.ProgressDialog; 
import android.content.Context; 
import android.os.AsyncTask; 

public class A extends AsyncTask<String, Void, String> 
{ 
private Context context = null; 

private final HttpClient httpClient = new DefaultHttpClient(); 

private String content = null; 
//private String error = null; 
private String finalResult = null; 
private static boolean isResult = false; 

private ProgressDialog progressDialog = null; 

public BabbleVilleSyncTask(Context context) 
{ 
    this.context = context; 
    progressDialog = new ProgressDialog(this.context); 
} 

protected void onPreExecute() 
{ 
    progressDialog.setMessage("Please Wait...."); 
    progressDialog.show(); 
} 

protected String doInBackground(String... urls) 
{ 
    try 
    { 
     //urls[0] = URLEncoder.encode(urls[0], "UTF-8"); 

     HttpGet httpget = new HttpGet(urls[0]); 
     ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
     content = httpClient.execute(httpget, responseHandler); 
    } 
    /*catch(UnsupportedEncodingException ue) 
    { 
     error = ue.getMessage(); 
    }*/ 
    catch (ClientProtocolException e) 
    { 
     //error = e.getMessage(); 
     cancel(true); 
    } 
    catch (IOException e) 
    { 
     //error = e.getMessage(); 
     cancel(true); 
    } 

    httpClient.getConnectionManager().shutdown(); 

    return content; 
} 

protected void onPostExecute(String result) 
{ 
    finalResult = result; 
    progressDialog.dismiss(); 
    System.out.println("on Post execute called"); 
    isResult = true; 
} 

public boolean getIsResult() 
{ 
    return isResult; 
} 

public void setIsResult(boolean flag) 
{ 
    isResult = flag; 
} 

public String getResult() 
{ 
    return finalResult; 
} 
} 

'

누군가가 나에게 문제가있을 수 있습니다 알려 수 있습니까?

감사

선일이

답변

128

AsyncTask를 사용하여 결과를 얻는 명확한 방법은 콜백 인터페이스를 사용하는 것입니다. 당신의 B 클래스의 다음

interface AsyncTaskCompleteListener<T> { 
    public void onTaskComplete(T result); 
} 

:

class B implements AsyncTaskCompleteListener<String> { 

    public void onTaskComplete(String result) { 
     // do whatever you need 
    } 

    public void launchTask(String url) { 
     A a = new A(context, this); 
     a.execute(url); 
    } 
} 

당신은 지금 당신의 클래스에 다음 코드를 추가해야합니다 : 여기

이 개념의 간단한 예입니다

class A extends AsyncTask<String, Void, String> { 
    private AsyncTaskCompleteListener<String> callback; 

    public A(Context context, AsyncTaskCompleteListener<String> cb) { 
     this.context = context; 
     this.callback = cb; 
    } 

    protected void onPostExecute(String result) { 
     finalResult = result; 
     progressDialog.dismiss(); 
     System.out.println("on Post execute called"); 
     callback.onTaskComplete(result); 
    } 
} 

이 방법을 사용하면 작업을 완료 할 때까지 기다릴 필요없이 기본 코드 (아마 th e 메인 UI 쓰레드)는 일반적인 안드로이드 이벤트 루프에서 기다리고 있으며, onTaskComplete 메소드가 자동으로 호출되어 태스크 결과를 처리 할 수 ​​있습니다.

+0

고맙습니다. 하지만 하나의 실행 메소드에서 3 개의 URL을 호출하려면 어떻게해야합니까? 그런 다음 어떻게 응답을 가져올 수 있습니까? 모든 아이디어 – sunil

+1

각 URL에 대해 작업에서 publishProgress를 호출하면 잘 수행해야하는 onProgressMethod 메서드가 있습니다. – SirDarius

+0

좀 더 자세히 설명해 주시겠습니까? 현재이 메서드를 변환하려고합니다 : public static int invokeWebServiceRequest (String uri, String username, String password, String targetKey); AsyncTask를 확장하는 클래스 내부. 어떻게 내 paramaters (내 이전 메서드에서) doInBackground (Params ...) 전달할 것이라고? 감사합니다. – Cole

1

I 클래스의 부모 클래스에 포함 된 개인 클래스를 만들 것, 그리고이 작업으로 이루어집니다 일단은 상위 클래스의 속성을 업데이트해야합니다, 그것은 가능 onPostExecute입니다.

+0

예, 가능합니다. 하지만 15-20 개의 활동이 있으며 각각은 http 연결이 있습니다. 그래서, 이것 때문에 내가 별도의 클래스를 만들었습니다. 하지만 지금은 문제에 직면 해 있습니다. 그래서 다른 클래스에있는 onPostExecute의 결과를 얻는 방법이 있습니까? – sunil

+0

http 액티비티를 모두 사용하는 15 가지 이상의 액티비티를 가지고 있다면, 상속 한 슈퍼 클래스에서 정의 된 것과 같은 기능을 서브 클래 싱해야합니다. – Pentium10

+0

계속하십시오 - 모든 HTTP 요청에 대한 클래스/싱글 톤을 만들려고하는데 메인/UI 스레드를 방해하지 마십시오. – Cole

4
public abstract class BaseTask<T> extends AsyncTask<Object, Void, T> { 

    public Context context; 
    public ProgressDialog dialog; 
    public Exception exception; 

    protected BaseTask() { 
    } 

    public BaseTask(Context context) { 
     this.context = context; 
     this.dialog = new ProgressDialog(context); 
    } 

    @Override 
    protected void onPreExecute() { 
     this.dialog.setMessage(context.getResources().getString(R.string.loading)); 
     this.dialog.show(); 
    } 

    @Override 
    protected T doInBackground(Object... objects) { 
     try { 
      return doWork(objects); 
     } catch (Exception e) { 
      exception = e; 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(T result) { 
     if (dialog.isShowing()) dialog.dismiss(); 
     if (exception == null) { 
      onResult(result); 
     } else { 
      onError(); 
     } 
    } 



    public abstract T doWork(Object... objects) throws Exception; 
    public abstract void onResult(T result); 
    public abstract void onError(); 



}