2013-02-15 3 views
3

API과 통신하는 앱을 만들고 있습니다. 모든 API 통신 코드와 데이터 처리를 하나의 API class에 넣어서 API를 사용할 때마다 모든 논리가있는 중앙 지점을 갖도록했습니다.안드로이드 - AsyncTasks 클래스로 작업하는 방법

HTTPRequests의 경우에는 AsyncTasks을 사용하는 것이 좋습니다. 예제에 표시된대로 전체 클래스를 파생하여 AsyncTask을 만듭니다.

내 클래스는 HTTP 호출로 인해 비동기가되어야하는 함수로 구성됩니다. 다른 사람은하지 않습니다.

내 질문 : AsyncTask에서 전체 API 클래스를 파생 시켰습니까? 아니면 API 클래스를 정상 및 비동기 부분으로 더 분할해야합니까?

답변

2

두 가지 방법으로 인터페이스를 만듭니다. 하나는 다른 스레드에서 실행되지 않는 인터페이스이고 다른 하나는 다른 스레드에서 실행되지 않는 인터페이스입니다. 비동기 메소드가 완료 될 때 통지되도록 콜백 객체를 허용합니다. 예 :

public interface MyAPI { 
//--this method runs an AsyncTask and calls supplied Callback object's methods when done 
public void fetchRemoteData(String input, Callback c); 

//--this method just processes input string locally and returns it 
public String doStuff(String input); 
} 

public interface Callback{ 
    public void onDone(int doneWhatCode, String result); 
} 

구현 :

public class MyWebAPI implements MyAPI{ 
    @Override 
    public void fetchRemoteData(String input, final Callback c){ 
     AsyncTask<String,Void,String> task = new AsyncTask<String,Void,String>(){ 

      @Override 
      protected String doInBackground(String... strings) { 
       String i = strings[0]; 

       //---connect, fetch data ---- 
       String result = "result"; 

       return result; 
      } 

      @Override 
      protected void onPostExecute(String s) { 
       super.onPostExecute(s); 
       c.onDone(1,s); 
      } 
     }; 

     task.execute("new Input url"); 
    } 

    @Override 
    public String doStuff(String input){ 
    return input.replace("i","o"); 
    } 
} 

당신의 API는 이러한 인터페이스에 의해 노출 될 보자. 이렇게하면 모든 것을 함께 유지하고 향후 변경 사항에 따라 실제 구현을 분리 할 수 ​​있습니다.

+0

하지만 어떻게'fetchRemoteData()'를 async라고하고 싶을까? 귀하의 예제는 기본적으로 내가 한 일이지만'NetworkOnMainThreadException'을 피하기 위해'http : // new Thread()'에 http 로직을 넣었다. – Ron

+0

@Ron 당신은 그렇게 구현한다. 업데이트 된 답변. –

+0

감사합니다! 나는 그것에게 시도를 줄 것이고, 나의 진도에 당신을 최신이라고 유지할 것이다 :) – Ron

0

요점은 "이 클래스 양식을 UI 스레드로 사용할 수 없다"는 점입니다. 그런 다음 AsyncTask를 만듭니다. 서비스를 받고 거기에서 API 메소드를 호출하고 싶다면 어떻게해야할까요? AsyncTask는 서비스 스레드에서 호출 할 수 없습니다.
나는이 클래스를 그대로두고 UI에서 호출하려고 할 때 AsyncTask에 래핑합니다.

편집 : 당신은 AsyncTask를 호출하고 결과가 준비되면 콜백을 얻을 수 있습니다, 지금

private class GetAuthorisationUrlTask extends AsyncTask<String, Void, String> 
{ 
    private OAuthBuilder oAuthBuilder; 
    private GetAuthorisationUrlTaskCallback callback; 

    public GetAuthorisationUrlTask(Context context, OAuthBuilder oAuthBuilder, GetAuthorisationUrlTaskCallback callback) 
    { 
     this.oAuthBuilder = oAuthBuilder; 
     this.callback = callback; 
    } 

    @Override 
    protected String doInBackground(String... params) 
    { 
     try 
     { 
      Log.i(TAG, "Getting authorization url..."); 
      return oAuthBuilder.getAuthorizationUrl(); 
     } 
     catch (Exception e) 
     { 
      Log.e(TAG, "Unable to get OAuth authorization url: " + e, e); 
      return null; 
     } 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     Log.i(TAG, "Authorisation url: " + result); 
     if (result == null) 
      Toast.makeText(getApplicationContext(), "Error getting authorization url.", Toast.LENGTH_SHORT).show(); 
     else 
      callback.urlCreated(result); 
    } 

    static interface GetAuthorisationUrlTaskCallback 
    { 
     void urlCreated(String url); 
    } 
} 

: 이것은 AsyncTask를로 기존의 기능을 포장의 예입니다.

GetAuthorisationUrlTask getAuthorisationUrlTask = new GetAuthorisationUrlTask(this, 
     new GetAuthorisationUrlTaskCallback() 
     { 
      @Override 
      public void urlCreated(String url) 
      { 
       webview.loadUrl(url); 
      } 
     }); 
getAuthorisationUrlTask.execute(); 

내가 너무 보일러 플레이트 코드가 알고 있지만, 그것은 당신의 비즈니스 클래스의 논리에서 완전히 UI를 분리합니다. 여기서는 단 하나의 작업 만 수행하지만 새로운 클래스를 추가하지 않고 더 일반적으로 확장하고 더 많은 작업을 수행하는 것은 쉽습니다.

+0

@ User117과 동일한 질문 : 비동기 작업에 함수를 래핑하려면 어떻게합니까? 네가 수업 전체를 파생해야한다고 생각 했지, 그렇지? – Ron

+0

내 편집 된 답변보기 – n0rm1e

+0

나는 고마워 할 것이다! – Ron

0

글쎄 그건 당신에게 달려 있습니다. 당신은 1 AsyncTask을 다 처리하고 포스트 업데이트 등을 할 수 있습니다. 그러나 그것이 직접적으로 관련이없는 다른 요청이 많다면 그것들을 분리 할 수 ​​있습니다. 좋은 접근 방식은 유스 케이스에 대해 생각하고이를 바탕으로 다른 AsyncTasks으로 분리하는 것일 수 있습니다.

  • 홈페이지 Activity 초기화 먼저 AsyncTask을 시작합니다

    은 사용 사례 기반 접근 방식의 예를 제공합니다.
  • 사용자가 로그인을 클릭하거나 다른 장기 실행 작업 시작 -> 두 번째로 시작합니다 AsyncTask.

그렇다면 기존 클래스를 사용했지만 AsyncTasks은 이전 클래스에 구현 된 API를 호출합니다.

관련 문제