2013-10-22 2 views
3

DoInBackground에서 asynctask 값을 반환하려고하는데 get() 메서드를 호출하면 UI가 멈 춥니 다. 코드를 콜백 메소드에 다시 쓰려면 어떻게해야합니까? : response = new GetUrlDataTask().execute("site").get;get() 메서드가없는 AsyncTask의 반환 값

+0

. 콜백을 사용해야합니다. – SLaks

+0

당신은 broadcastreceiver 또는 어쩌면 이벤트 버스와 함께 intent를 사용할 수 있습니다. 콜백도 좋습니다 –

+1

내부 클래스로 만들고'onPostExecute()'또는 [이 답변보기] (http : //)에서 직접'Activity' 메소드를 호출 할 수 있습니다. /stackoverflow.com/questions/18517400/inner-class-can-access-but-not-update-values-asynctask/18517648#18517648)'AsyncTask'와 함께'interface' 사용에 대해 – codeMagic

답변

10

은 [업데이트] 지금은 주석을 사용하는 것이 좋습니다 나의 활동에

public class GetUrlDataTask extends AsyncTask<String, Integer, String> { 
String response; 
HttpUtils util; 
@Override 
protected String doInBackground(String... params) { 
    try { 
     util = new HttpUtils(params[0]); 
     response = util.getContent(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return response; 
} 

@Override 
protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
} 

나는 결과를 얻을. 주석을 사용하여보기를 삽입 할 수 있으며 컴파일 단계에서 비동기 적 프로세스로 기능을 몇 글자만으로 만들 수 있습니다. github에 버터 나이프 라이브러리를 확인하십시오.

ButterKnife

당신은 인터페이스를 생성 (생성자) AsyncTask를에 전달하고 예를 들어

onPostExecute

에서 메서드를 호출 할 수 있습니다 :

사용자 인터페이스 :

public interface OnTaskCompleted{ 
    void onTaskCompleted(); 
} 

내 활동 :

10 그리고 당신의 AsyncTask를이 : 비동기 작업이 (이것은 일반적으로) 시간의 상당한 금액을 걸릴 것입니다 경우

public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type 
    private OnTaskCompleted listener; 

    public YourTask(OnTaskCompleted listener){ 
     this.listener=listener; 
    } 

    //required methods 

    protected void onPostExecute(Object o){ 
     //your stuff 
     listener.onTaskCompleted(); 
    } 
} 
+0

콜백에 null expirience가 있습니다. YourTask는 내 활동에 포함 된 변수를 어떻게 알 수 있습니까? – Sunstrike

+0

@Flextra Iam이 onPostExecute에 객체를 가져 오는 방법 autoText로 객체를 설정하고 다른 AsynchronusTask를 실행하는 방법을 알려주세요. – Harsha

6

당신은() 갔지 사용할 수 없습니다.

대신 message/handler/service/etc를 사용하거나 onPostExecute (Result) 메소드를 사용할 수 있습니다.

편집 : 새 코드. 설명을 바탕으로 인터페이스를 사용해야 할 것 같습니다.

다른 클래스에서 Asynctask를 사용해야하는 경우 인터페이스가 가장 좋은 옵션 일 수 있습니다.

TestTask.java (별도의 AsyncTask를)

import android.os.AsyncTask; 

// Remember to change object type <> to what you need 
public class TestTask extends AsyncTask<Object,Object,Object> { 

    public interface OnTaskCompleted{ 
     void onTaskCompleted(); 
    } 

    private OnTaskCompleted listener; 

    public TestTask(OnTaskCompleted listener){ 
     this.listener = listener; 
    } 

    protected void onPostExecute(Object o){ 
     // Call the interface method 
     if (listener != null) 
      listener.onTaskCompleted(); 
    } 

    @Override 
    protected Object doInBackground(Object... params) { 
     // The sleep() is just to simulate activity and delay 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

MainActivity.java (또는 다른 활동) :

public class MainActivity extends Activity { 

private boolean status = false; 

private OnTaskCompleted listener = new OnTaskCompleted() { 
    public void onTaskCompleted() { 
     status = true; 
     Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show(); 
    } 
}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show(); 
    new TestTask(listener).execute("Testing"); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} 
+0

동일한 문제가있는 asynctask와 함께 다른 클래스가 있지만 매우 크고 내 활동 클래스에 포함시킬 수 있습니다. – Sunstrike

+0

필요한 것을 반영하도록 원본을 업데이트했습니다. 위의 코드는 테스트를 거쳐 작동합니다. 인터페이스를 변경하여 필요한 것을 수행 할 수 있습니다. 인터페이스에 대한 아이디어는 Asynctask에 의해 호출 된 메소드를 가질 수 있으며, 따라서 콜백 개념 내에서 실행됩니다. –

+0

하지만 여전히 가치를 반환하는 방법을 이해하지 못합니다. onTaskCompleted();에서 "return String"으로 무언가를 써야합니다. – Sunstrike

0

당신은 이런 식으로 뭔가를 할 수 :

public class MyActivity extends Activity 
{ 
    public void someMethod() 
    { 
    // Here you could put up a ProgressDialog 

    GetUrlDataTask myTask = new GetUrlDataTask(); 
    myTask.execute(); 
    } 

    public class GetUrlDataTask extends AsyncTask<String, Integer, String> 
    { 
    @Override 
    protected String doInBackground(String... params) 
    { 
     String response = null; 
     HttpUtils util; 

     try 
     { 
     util = new HttpUtils(params[0]); 
     response = util.getContent(); 
     } 
     catch (Exception e) 
     { 
     e.printStackTrace(); 
     response = e.getMessage(); 
     } 
     return response; 
    } 

    @Override 
    protected void onPostExecute(String result) 
    { 
     // Here you can dismiss the ProgressDialog and display the result 
    } 
    } 
} 
1

나는 특히 응답을 사용해야하는 경우 별도의 클래스에서 AsycTask 작업을 수행하는 것을 좋아합니다. 내부 클래스로 구현 될 때 얼마나 쉬운지를 고려하여 응답 및 로컬 변수와 상호 작용하는 것을 지나치게 어렵게 만듭니다.

당신이 그것을 재사용 할 수 있도록 자신의 클래스에 넣어 같은데요. AsycTask를 내부 클래스로 유지하고 doInBackground()에서 재사용 가능한 외부 객체/메소드를 호출하는 것을 고려할 것입니다. 이렇게하면 DRY 코드가 유지되며 응답을 통해 필요한 작업을 수행 할 수 있습니다. 비동기의 정반대의

public class MyActivity extends Activity { 
    TextView textview; 

    //... 

    private class GetUrlTask extends AsyncTask<String, Integer, String> { 

     protected String doInBackground(String... params) { 
      return new GetHttpResponse().get(params[0]); 
     } 

     protected void onPostExecute(String response) { 
      //Do UI updates... 
      textview.setText(response); 
     } 
    } 
} 


public class GetHttpResponse { 

    public String get(String url) { 
     try { 
      util = new HttpUtils(url); 
      response = util.getContent(); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    return response; 
    } 
} 
+0

그리고이 작업을 사용하는 활동이 세 개 더 있다면 어떻게해야합니까? – Sunstrike