2017-08-01 18 views
-1

我正在與團隊合作項目,我正在做Android應用程序的服務器部分。我使用AsyncTask創建新的線程來連接服務器。問題是我不知道如何在UI線程中等待從AsyncTask獲得的變量。如何在UI中等待來自AsyncTask的變量

這裏是擴展類的類應該從服務器獲得一個字符串。

package com.example.mdundic.test; 

import android.os.AsyncTask; 
import android.util.Log; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import static android.content.ContentValues.TAG; 

public class GetJSONTask extends AsyncTask<String, Void, String> { 
public interface AsyncResponse { 
    void processFinish(String output); 
} 
public AsyncResponse delegate = null; 
public GetJSONTask(AsyncResponse delegate){ 
    this.delegate = delegate; 
} 
@Override 
protected void onPreExecute() { 
// super.onPreExecute(); 
    Log.d(TAG, "AsyncClic PreExecute ! "); 
} 

@Override 
protected String doInBackground(String... params) { 
// Log.d(TAG, "AsyncClic"); 
    return get(params[0]); 
} 
@Override 
protected void onPostExecute(String result) { 
    //super.onPostExecute(result); 
    delegate.processFinish(result); 
    Log.d(TAG, "AsyncClic PostExecute ! "); 
} 

public String get(String Url) { 
    String json=""; 
    try { 
     URL url = new URL(Url); 

     HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
     conn.setRequestMethod("GET"); 
     conn.setRequestProperty("Accept", "application/json"); 

     if (conn.getResponseCode() != 200) { 
      throw new RuntimeException("Failed : HTTP error code : " 
        + conn.getResponseCode()); 
     } 

     BufferedReader br = new BufferedReader(new InputStreamReader(
       (conn.getInputStream()))); 

     String output; 

     while ((output = br.readLine()) != null) { 
      json += output; 
     } 

     conn.disconnect(); 

    } catch (MalformedURLException e) { 

     e.printStackTrace(); 

    } catch (IOException e) { 

     e.printStackTrace(); 

    } 
    return json; 
} 

在UI的主要活動我創建這個類的一個實例,並調用它的執行,並在processFinish功能設置我的輸出字符串的值是我的全局字符串名爲「退役」。

這是它的外觀:

public String ret; 
public String recieveServer(String URL) { 
      //receive 
      GetJSONTask getJSONTask = new GetJSONTask(new GetJSONTask.AsyncResponse() { 
       @Override 
       public void processFinish(String output) { 
        ret = output; 
       } 
      }); 
      getJSONTask.execute(URL); 
      return ret; 
     } 

此功能使用誰願意來解析字符串,牽起我的隊友。這個函數返回null,我知道這是因爲UI線程不會等待AsyncTask線程完成,但我不知道如何解決這個問題。有沒有人對我有任何建議?

+0

異步交付結果:通過回調或監聽器,通過RxJava/RxAndroid,通過事件總線等。 或者,將所有**代碼移動到其他後臺線程上,包括執行網絡I/O *的代碼*和隊友,這樣你的'recieveServer()'將不再需要'AsyncTask'。 – CommonsWare

+0

CommonsWare是的,謝謝你,我在互聯網上發現了一些其他的方法,如通過RxJava我只是想看看我是否缺少這裏的東西。 –

回答

0

正如你已經實施了回調即AsyncResponse的接口,因此而不是返回從receiverServer()函數值,只需要在執行你的任務「processFinish()」函數

public void recieveServer(String URL) { 
     //receive 
     GetJSONTask getJSONTask = new GetJSONTask(new GetJSONTask.AsyncResponse() { 
      @Override 
      public void processFinish(String output) { 
       // perform you task here 
       //for ex : call your function or display the output here 
       // 
      } 
     }); 
     getJSONTask.execute(URL); 
    } 
+0

是的,但這意味着我必須每次都做同樣的事情(相同的功能),我想要的是不同的網址,因爲不同的字符串輸出以不同的方式解析它們。我想保存某個字符串輸出的地方,以便我可以以不同的方式使用它。 –