扩展AsyncTask时如何以及在何处调用我的任务

时间:2012-02-13 11:18:34

标签: android android-asynctask

即使在Developer.Android上阅读了有关它的所有内容之后,我也很难理解AsyncTask。我正在寻找一些有关如何进行的见解。情况就是这样:

我有一个Activity,在onClick事件上调用底层LoginController类的LoginCheck()方法。然后LoginController类继续从UserInfo类或Activity(用户和密码)获取任何信息,并创建一个RestClient实例,然后调用Web服务并尝试登录.RestClient有一个私有扩展AsyncTask的类CallServiceTask。

我在这里遇到一些设计问题,希望你能提供帮助。

  • 我做得对吗?这是确保对Web服务的任何调用都是异步完成的正确方法吗?
  • 如何使用onProgressUpdate或其他任何方式通知用户该应用程序正在登录?
  • 我如何获取DoinBackground()中保存的数据?

您将在下面找到相关项目的片段:

RESTClient实现

// From the constructor...
rtnData = new Object[]{ new JSONObject() , Boolean.TRUE  };

   public void ExecuteCall(RequestMethod method) throws Exception
{
    Object[] parameters = new Object[]{ new HttpGet() , new String("") };
    switch(method) {
        case GET:
        {
            //add parameters
            String combinedParams = "";
            if(!params.isEmpty()){
                combinedParams += "?";
                for(NameValuePair p : params)
                {
                    String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue());
                    if(combinedParams.length() > 1)
                    {
                        combinedParams  +=  "&" + paramString;
                    }
                    else
                    {
                        combinedParams += paramString;
                    }
                }
            }

            HttpGet request = new HttpGet(url + combinedParams);

            //add headers
            for(NameValuePair h : headers)
            {
                request.addHeader(h.getName(), h.getValue());
            }
            parameters[0] = request;
            parameters[1] = url;

            new CallServiceTask().execute(request, url);


            jsonData = ((JSONObject) rtnData[0]).optJSONObject("data");
            connError = (Boolean) rtnData[1];
            break;

        }
        case POST: ....

    }
}

private Object[] executeRequest(HttpUriRequest request, String url)
{
    HttpClient client = new DefaultHttpClient();
    client = getNewHttpClient();

    HttpResponse httpResponse;

    try {
        httpResponse = client.execute(request);
        HttpEntity entity = httpResponse.getEntity();

        if (entity != null) {

            InputStream instream = entity.getContent();
            String response = convertStreamToString(instream);
            try {
                rtnData[0] = new JSONObject(response);
                rtnData[1] = false;

            } catch (JSONException e1) {
                rtnData[1] = true;
                e1.printStackTrace();
            }

            // Closing the input stream will trigger connection release
            instream.close();
        }

    } catch (ClientProtocolException e)  {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    } catch (IOException e) {
        client.getConnectionManager().shutdown();
        e.printStackTrace();
    }
    return rtnData;
}

CallServiceTask

    private class CallServiceTask extends AsyncTask<Object, Void, Object[]>
{

    protected Object[] doInBackground(Object... params) 
    {
        HttpUriRequest req = (HttpUriRequest) params[0];
        String url = (String) params[1];

        return executeRequest(req, url);
    }

    @Override
    protected void onPostExecute(Object[] result) 
    {
             rtnData = result;
    }
}

1 个答案:

答案 0 :(得分:2)

任何可能长时间运行的操作都应该在不同的线程中执行,这是绝对正确的。 AsyncTask是解决此类问题的好方法,因为它还为您提供了一种将任务与UI线程同步的简便方法。这是你第一个问题的答案。

现在,关于UI线程更新,以向您的用户显示您的应用程序未被卡住。由于AsyncTask的{​​{1}}和onPreExecute()方法在UI线程中运行,因此您可以轻松地创建,运行和停止onPostExecute()ProgressDialog 。如果您想显示任务的当前进度,您应该在ProgressBar内调用publishProgress(int)方法,然后在doInBackground()的{​​{1}}方法中使用它。例如,您可以更新AsyncTask

要从AsyncTask中获取结果,您可以调用其onProgressUpdate()方法(这是一个同步调用),或者实现某种回调接口,该接口将告诉活动该任务已完成。

我希望答案很清楚,如果没有 - 随意提出更多问题。希望这会有所帮助。

编辑

使用一种方法[{1}}创建一个名为ProgressDialog的接口。启动get()的活动必须实现此接口。现在在onFetchFinishedListener中创建一个构造函数,该构造函数将void onFetchFinished(String)对象作为参数,并在实例化活动中的AsyncTask时发送对AsyncTask的引用作为参数(因为它实现了OnFetchFinishedListener)。然后,当您在AsyncTask内部完成任务时,请在活动中调用Activity。现在,在OnFetchFinishedListener的{​​{1}}方法中,您可以使用回调带来的doInBackground()(或其他对象)。再一次,希望我足够清楚。