54

我有以下课程:

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
4

8 回答 8

113

该方法execute返回AynscTask自身,您需要调用get

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

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

如果你这样做,你只是把你的异步任务变成了同步任务。

但是,使用的问题get在于,因为它是阻塞的,所以需要在工作线程上调用它。但是,AsyncTask.execute()需要在主线程上调用。因此,尽管此代码可以工作,但您可能会得到一些不希望的结果。我还怀疑get()谷歌对它的测试不足,他们可能在某个地方引入了一个错误。

参考:AsyncTask.get

于 2012-06-10T20:30:42.530 回答
18

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

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。

于 2012-06-10T20:45:39.353 回答
4

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

为什么不这样做:

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

这允许用户在处理请求时离开并做任何事情。

IntentService 在自己的线程上在后台运行。当它接收到一个 Intent 时,它运行 onHandleIntent()。当该方法完成时,Service 被缓存:它不是活动的,但它可以在下一个 Intent 到达时快速重新启动。

于 2012-06-10T21:13:25.560 回答
2
  1. 像这样在构造函数中获取上下文:

    public GetDataTask(Context context) {}

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

    void onDataRetrieved(String data);

  3. 在创建任务对象的类中实现接口(例如MainActivity

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

于 2016-09-03T19:40:56.110 回答
0

在下面的代码中,我从 AsyncTask 返回一个字符串(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;
        }
    }
}
于 2015-10-17T04:23:11.747 回答
0

这个 ONE LINER 为我工作:

String result = MyasyncTask.execute(type, usrPhoneA, usrPWDA).get();
于 2017-09-24T02:53:14.717 回答
0

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

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);
    }
}
于 2016-07-22T08:36:39.253 回答
0

AsyncTask将数据从 UI 发送到 UI的唯一方法是Otto事件总线。注册一个方法,该方法将@Subscribe在 UI 中post的注释下处理结果message,并在onPostExecute您的AsyncTask.

于 2017-12-01T04:40:36.510 回答