2017-08-01 21 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

是的,但这意味着我必须每次都做同样的事情(相同的功能),我想要的是不同的网址,因为不同的字符串输出以不同的方式解析它们。我想保存某个字符串输出的地方,以便我可以以不同的方式使用它。 –