2013-07-01 4 views
1

현재 Android 애플리케이션을 개발하기 시작했으며 모든 것이 매우 간단하고 직관적이라고 나와 있습니다.알림이 포함 된 Android AsyncTask

AsyncTask에 대한 질문이 있습니다. 어쩌면 내가 잘못한 것을했을 수도 있지만 여기 상황이 있습니다.

웹에서 목록의 콘텐츠를로드해야하는 작은 앱이 있습니다. 가짜 요청을 기반으로 모든 것을 개발했으며 모두 훌륭했습니다. 그런 다음 실제 요청으로 코드를 업데이트하고 'Network on main thread error'를 받았습니다. 그래서 AsyncTask로 전환하기로 결정했습니다.

AsyncTask에 비동기 작업을시키고 다른 곳에서 결과를 처리 할 수 ​​있는지 궁금합니다. (실제로 GUI 연결과 모든 것이 있습니다). 가독성과 논리면에서 Activity의 인터페이스를 처리하는 모든 코드를 보유하는 것이 더 합리적이라고 생각했지만 작업 완료 시점을 어떻게 알 수 있습니까?

나는이 간단한 클래스와 인터페이스를 작성했지만 작동하는 데 좋은 방법인지 또는 더 좋은 방법이 있는지 알고 싶었습니다.

public interface AsyncDelegate { 

    public void executionFinished(LazyLoaderWithDelegate lazyLoaderWithDelegate); 
} 

이 간단한 인터페이스 :

그래서, 여기에 코드입니다. 그 목적은 Activity가 이것을 구현하고 'executionFinished'메소드를 처리하는 것입니다. 청취자와 같은 것.

import android.os.AsyncTask; 

public class LazyLoaderWithDelegate<Params, Progress, Result> extends AsyncTask<Params, Progress, Result>{ 
    AsyncDelegate delegate; 

    Result result; 

    public LazyLoaderWithDelegate(AsyncDelegate delegate){ 
     this.delegate = delegate; 
    } 

    @Override 
    protected Result doInBackground(Object... params) { 
     //This will be Overridden again from the subclasses anyway. 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Result r){ 
     this.result = r; 
     delegate.executionFinished(this); 
    } 

    public Result getResult(){ 
     return result; 
    } 

} 

이 클래스는 기본적으로 작업이 완료되면 대리인에게 알리기 위해 스켈레톤 구조를 제공합니다.

그게 전부입니다. 다음은이 클래스를 사용하는 예는 다음과 같습니다 당신이 onPostExecute에서 실행

public class LazyVideoLoader extends LazyLoaderWithDelegate<Void, Void, List<List<Video>>>{ 

    public LazyVideoLoader(AsyncDelegate delegate) { 
     super(delegate); 
    } 

    @Override 
    protected List<Video> doInBackground(Void ...params) { 
     return ServerInterface.getVideos(); 
    } 

} 

public class MainActivity extends Activity implements AsyncDelegate { 
    private LazyVideoLoader videoLoader; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     /* 
     * Set up the lazy loaders 
     */ 
     videoLoader = new LazyVideoLoader(this); 
     videoLoader.execute(); 
    } 

    @Override 
    public void executionFinished(LazyLoaderWithDelegate task) { 
     if(task == videoLoader){ 
      List<Video> result = videoLoader.getResult(); 
      //Do whatever you need... 
     } 

} 
+0

'onPostExecute'에서 실행되는 모든 것은 UI 스레드에 있습니다. – Cornholio

+0

UI 변경을 위해 publishProgress 또는 onProgressUpdate (AsyncTask의 메소드)를 사용할 수도 있습니다. http://developer.android.com/reference/android/os/AsyncTask.html –

답변

3

모두가 UI 스레드입니다. 또한 onProgressUpdate에서 publishProgressdoInBackground으로 호출하여 특정 부분의 작업이 완료되면 UI 스레드에서 코드를 실행할 수 있습니다.

자세한 내용은 this을 참조하십시오. 그것은 당신이 AsyncTask에 대해 알 필요가있는 모든 것을 가지고 있습니다.

+0

내 댓글과 댓글을 복사했습니다. Cornholio .... –

+0

아니요. 나는 당신의 의견을보기 전에 나의 대답을 게시했다. – Dulanga

+0

어쩌면 당신 말이 맞아요 .. 2 분 시간 차이 ... 죄송합니다 ... –

1

이 부분을 올바르게 이해했다면 AsyncTask를 실행하는 별도의 클래스가 있습니다. 작업이 완료되면 as 콜백 사용 인터페이스가 활동을 알립니다. 구성 요소에서 코드를 모듈화하는 것이 좋다고 생각하면 좋습니다.

가장 일반적인 방법은 Activity에서 내부 클래스로 AsyncTask를 사용하는 것입니다. 상대적으로 작은 크기의 그림이나 비슷한 것을 다운로드하고 싶다면 이것이 선호됩니다. 내부 클래스의 모든 필드에 액세스 할 수 있기 때문에 생성자/인터페이스에서 전달하는 것보다 쉽게 ​​처리 할 수 ​​있습니다.

가독성을 위해 추가 클래스에서 AsyncTask를 사용하지 마십시오. 다른 방법으로 결과에 대해 공정한 계산/수정을 수행해야한다면 귀하의 방법은 괜찮습니다.

+0

가독성을 위해서 다른 클래스에서 AsyncTask를 갖는 것은 실제로 모든 것의 목적입니다. 더 많은 모듈 식 코드를위한 별도의 클래스가 있습니다. 이건 나쁜거야? 왜? – XelharK