2012-06-10 2 views
43

나는 다음과 같은 클래스가 :AsyncTask에서 문자열을 다시 얻는 방법은 무엇입니까?

public class getURLData extends AsyncTask<String, Integer, String>{ 

@Override 
protected String doInBackground(String... params) { 
    String line; 
    try { 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(params[0]); 

     HttpResponse httpResponse = httpClient.execute(httpPost); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     line = EntityUtils.toString(httpEntity); 

    } catch (UnsupportedEncodingException e) { 
     line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; 
    } catch (MalformedURLException e) { 
     line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; 
    } catch (IOException e) { 
     line = "<results status=\"error\"><msg>Can't connect to server</msg></results>"; 
    } 
    return line; 
} 

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

} 

내가 같이 호출하는 것을 시도하고있다 : 출력 변수가 데이터를 받고 있지 않습니다

String output = null; 
output = new getURLData().execute("http://www.domain.com/call.php?locationSearched=" + locationSearched); 

하지만, 오류가 점점 오전 대신 :

Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String 
+0

어디에서'super.onPostExecute (result);'를해야합니까? 나는 그 라인을 넣지 않았고 여전히 작동합니다! –

답변

101

AynscTask 자체가, 당신은 get를 호출 할 필요가 반환 execute 방법 :

완성 된 새 스레드에서 작업 할 때까지 ( get를 통해) 현재 스레드를 차단하면서
output = 
    new getURLData() 
     .execute("http://www.example.com/call.php?locationSearched=" + locationSearched) 
     .get(); 

이 은 (execute를 통해) 새 스레드를 시작하고 결과가 반환되었습니다.

비동기 작업을 동기화 개로 바꿨습니다.

그러나 get을 사용하면 문제가 발생하기 때문에 차단하기 때문에 작업자 스레드에서 호출해야합니다. 그러나 AsyncTask.execute()은 주 스레드에서 호출해야합니다. 따라서이 코드가 작동 할 수는 있지만 원하지 않는 결과가 발생할 수 있습니다. 나는 또한 get()이 Google에 의해 테스트를 받았다고 의심하며 라인을 따라 어딘가에 버그를 도입했을 가능성이 있습니다.

참조 : AsyncTask.get

+3

내 신이 점점 더 복잡해진다. 내가하고 싶은 것은 사용자가 버튼을 클릭하여 화면을 직선적으로로드 한 다음 완료되면 http에서 콘텐츠를 표시하는 것이다. 어떻게 이뤄지나요? – Paul

+3

@Paul : 실행 후 무엇을해야 할지를'onPostExecute'에서 수행하십시오. _that_은 단순한 ... –

+2

나는 그것이 좋겠지 만, onPostExecute 메소드로 이동하면 더 이상 매개 변수 변수가 없어서 문자열을 반환하는 문제가 발생합니다. 도와 주셔서 감사하지만 시간이 걸렸습니다. 실은 이것이 잃어버린 원인이라고 생각합니다. – Paul

15

차라리 블록 UI 스레드가 아닌 콜백을 만들 것입니다. 데이터가 도착할 때 호출 될 클래스 작성 메소드에서. 예를 들어 :

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

을 그리고 어딘가에 코드에서 바로 작업을 실행 :

private void setData(String data){ 
    mTextView.setText(data); 
} 

그런 다음 AsyncTask를에 onPostExecute을 구현

new getURLData().execute(... 

작업 사항 setData가 호출되고 mTextView가 가득 완료됩니다.

AsyncTask.get()은 UI를 블로킹하므로 AsyncTask를 사용할 이유가 없습니다.

+9

위대한,하지만 해당 메서드가 다른 활동 ('.execute'를 만드는 메서드)에 있으면 AsyncTask에서'setData'를 어떻게 호출 할 수 있습니까? –

+2

그렇지 않습니다. [onPostExecute()]에서 필요한 것을 수행하십시오. (http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute%28Result%29) – Cyrille

4

사용자가 버튼을 클릭 한 다음 콘텐츠를 기다려야 할 때 무엇을합니까?

왜 이렇게하지 :

  1. 사용자가 버튼을 클릭합니다.
  2. 연결 확인. 사용자가 인터넷에 연결되어 있지 않으면 사용자에게 알리십시오.
  3. HTTP 요청을 보내기 위해 Intent를 보내서 IntentService를 시작합니다.
  4. 요청이 완료되면 알림을 게시합니다.
  5. 사용자가 알림을 클릭하면 다음 단계를 수행 할 수있는 활동으로 돌아갑니다.

이렇게하면 요청이 처리되는 동안 사용자가 벗어나 수행 할 수 있습니다.

IntentService는 자체 스레드에서 백그라운드로 실행됩니다. 인 텐트를 수신하면 onHandleIntent()를 실행합니다. 이 메소드가 끝나면 서비스는 캐시됩니다 : 활성 상태가 아니지만 다음 인 텐트가 도착하면 다시 시작할 수 있습니다.

0

다음 코드에서 AsyncTask에서 String (directorName)을 다시 얻습니다.

+4

* get *을 사용하면 동기식이됩니다. 비동기 적으로 수행 할 AsyncTask의 모든 목적을 무력화시킵니다. – mradzinski

0

결과 생성 데이터를 저장할 개체를 참조하는 작업 생성자에 컨텍스트 매개 변수를 추가하십시오.

2
  1. 과 같이 생성자에서 상황에 맞는 가져 오기 :

    void onDataRetrieved(String data);

  2. 이 인터페이스를 구현 :

    public GetDataTask(Context context) {}

  3. 이 방법으로 인터페이스를 만들기를 Task 객체를 만드는 클래스의 클래스 (예 : MainActivity)

  4. 캐스트 인터페이스에 대한 컨텍스트와 onDataRetrieved 방법

+0

메모리 누수가 발생할 수 있습니다. 장기 실행 조작이 활동의 ​​컨텍스트에 액세스 할 수있는 경우, asynctask는 구성 변경 또는 사용자가 어떤 이유로 든 활동에서 뒤로 밀어 넣을 때 활동을 가비지 수집하지 못하게합니다. –

+0

사용하는 것이 필요하다'WeakReference를 actWeak = 새로운 WeakReference를 <> (활동)'는'AsyncTask'가에서'메모리 누수를 방지하고 다시 활동 행위 = actWeak.get()'와 그걸 얻기 위해하는'Activity'를 보낼 때 doInBackground 메소드. – isabsent

0

를 호출이 하나 라이너는 나를 위해 일한 :

String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get(); 
+0

AsycTask 변수를 반환 할 때 어떻게 작동합니까? –

+0

PHP가 로그인 함수를 처리 한 후 작업 결과를 "result"변수에 반환합니다. 나는 이것이 비동기식 작업이 아니라는 것을 읽었지 만, 제 경우에는 괜찮습니다. – francisqueins

+0

나는 asynctask 변수가있어 사용하지는 않았다. –

0

없이 UI에 AsyncTask에서 데이터를 전송하는 유일한 방법 통증은 Otto 또는 Event 버스입니다. 결과를 UI에 @Subscribe 주석으로 처리하고 postmessage으로, 결과는 onPostExecute 방법으로 AsyncTask으로 등록하십시오.

관련 문제