如何从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
Paul asked 2020-01-11T02:11:12Z
8个解决方案
111 votes

方法get自身返回AsyncTask.execute(),您需要调用get()

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

这将启动一个新线程(通过get),同时阻止当前线程(通过AsyncTask.execute()),直到完成新线程的工作并返回结果为止。

如果执行此操作,则将异步任务变成了同步任务。

但是,使用2697289389188842842496的问题在于,由于其阻塞,因此需要在辅助线程上调用它。 但是,需要在主线程上调用AsyncTask.execute()。 因此,尽管此代码可以工作,但您可能会得到一些不良结果。 我还怀疑get()已被Google测试不足,并且很可能他们沿线某个地方引入了错误。

参考:AsyncTask.get

K-ballo answered 2020-01-11T02:11:39Z
18 votes

我宁愿创建回调,也不愿阻止UI线程。在您的类中,当数据到达时将调用create方法。 例如:

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

然后在AsyncTask中实现onPostExecute:

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

然后在代码中的某个地方执行任务:

new getURLData().execute(...

任务完成后,将调用setData并填充mTextView。

AsyncTask.get()将阻塞您的UI,因此没有理由使用AsyncTask。

pawelzieba answered 2020-01-11T02:12:16Z
4 votes

如果用户单击按钮,则必须等待内容,他们同时又做什么?

为什么不这样做:

  1. 用户单击按钮。
  2. 您检查连接。 如果用户未连接到Internet,请告诉他们。
  3. 您可以通过发送一个Intent发送HTTP请求来启动IntentService。
  4. 请求完成后,您将发布通知。
  5. 用户单击通知,这将返回到可以执行下一步的活动。

这使用户可以在处理请求的同时执行任何操作。

IntentService在其自己的线程中在后台运行。 当它收到一个Intent时,它将运行onHandleIntent()。 该方法完成后,将缓存服务:该服务不处于活动状态,但可以在下一个Intent到达时快速重新启动。

Joe Malin answered 2020-01-11T02:13:12Z
2 votes
  1. 像这样在构造函数中获取上下文:

    MainActivity

  2. 使用以下方法创建接口:

    MainActivity

  3. 在要创建Task对象的位置的类中实现Interface(例如MainActivity

  4. 将上下文强制转换为接口并调用onDataRetrieved方法

Matthias Herrmann answered 2020-01-11T02:13:53Z
0 votes

在以下代码中,我从AsyncTask获得了一个String(directorName)。

public class GetDirector {
    String id;
    private String baseURL = "http://www.omdbapi.com/?i=";
    private String finalURL = "";
    String theDirector;

    public GetDirector(String imdbID) throws ExecutionException, InterruptedException {
        id= imdbID;
        finalURL = baseURL + id + "&plot=full&r=json";
        System.out.println("GetDirector. finalURL= " + finalURL);
        theDirector = new GetDirectorInfo().execute().get();
    }

    public String getDirector (){
        return theDirector;
    }

    private class GetDirectorInfo extends AsyncTask<Void, Void,String> {
        @Override
        protected String doInBackground(Void... params) {
            String directorName = null;

            ServiceHandler sh = new ServiceHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(finalURL, ServiceHandler.GET);
            System.out.println("Act_DetailsPage. jsonStr= " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject everything = new JSONObject(jsonStr);

                    directorName = everything.getString(JSON_Tags.TAG_DIRECTOR);
                    System.out.println("directorName= "+ directorName);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Inside GetDirector. Couldn't get any data from the url");
            }
            return directorName;
        }
    }
}
Gene answered 2020-01-11T02:14:13Z
0 votes

在任务的构造函数中添加一个上下文参数,该参数将引用存储结果数据的对象。

class PopulateArray extends AsyncTask<Integer, Integer, ArrayList<String>>
{
    Context _context; // context may be what ever activity or object you want to store result in
    PopulateArray(Context context)
    {
        _context = context;
    }
    @Override
    protected ArrayList<String> doInBackground(Integer... integers)
    {
        ArrayList<String> data = new ArrayList<String>();
        //manipulate
        return data;
    }

    @Override
    protected void onPostExecute(ArrayList<String> strings)
    {
        _context.setData(strings);
    }
}
Dragas answered 2020-01-11T02:14:33Z
0 votes

这个一线帮我忙:

String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get();
francisqueins answered 2020-01-11T02:14:53Z
0 votes

将数据从AsyncTask传输到UI的唯一方法是无痛苦(Otto)或事件总线。 在您的onPostExecuteonPostExecute方法中注册一个将在UI中的@Subscribe注释下处理结果的方法,以及在post message中处理结果的方法。

isabsent answered 2020-01-11T02:15:13Z
translate from https://stackoverflow.com:/questions/10972114/how-to-get-a-string-back-from-asynctask