doInBackround()和AsyncTask(Android)的execute()方法之间的关系

时间:2017-02-02 09:30:25

标签: android android-asynctask

我最近开始学习android,但是Asynctask概念让我很烦。

我的问题是doInBackground(Param ...params)execute(Params... params)如何相互关联。 execute()方法如何将其争论传递给doInBackground()方法。

我真的很感激一些帮助!

3 个答案:

答案 0 :(得分:0)

我认为您对与varargs相关联的genericsAsyncTask感到困惑。为了解释它,我将举一个简单的例子:

    class AddStringTask extends AsyncTask<Void, String, Void> {
    @Override
    protected Void doInBackground(Void... unused) {
      for (String item : items) {
        if (isCancelled())
          break;

        publishProgress(item);
        SystemClock.sleep(400);
      }

      return(null);
    }

    @Override
    protected void onProgressUpdate(String... item) {
      if (!isCancelled()) {
        adapter.add(item[0]);
      }
    }

    @Override
    protected void onPostExecute(Void unused) {
      Toast.makeText(getActivity(), R.string.done, Toast.LENGTH_SHORT)
           .show();

      task=null;
    }
  }

4通常会AsyncTask种方法:

  • onPreExecute() [可选] - 在启动后台线程之前在UI线程上运行任务,例如:显示进度条。
  • doInBackground() [必须] - 从后台线程执行代码的方法。
  • onProgressUpdate() [可选]在后台线程执行操作时传递数据,例如:在执行下载操作时将下载百分比传递给用户。这是在主线程上执行的。
  • onPostExecute() [可选]此方法在doInBackground()方法完成执行后立即执行。例如:您可以在下载完成时关闭进度条。

现在进入仿制药:<Void, String, Void> [在这种情况下]

  • doInBackground()收到三种数据类型中的第一种,即Void。您可以更改数据类型。如果您有要下载的URL的列表,则可以将其更改为String数组的变量。在这种情况下,由于我们没有任何信息要传递给doInBackground()方法,因此我们将其设置为Void
  • 现在onProgressUpdate()方法将收到第二种数据类型的变量。即<Void, String, Void> - &gt; String。这将是从doInBackground()方法传递的数据的形式。
  • 现在doInBackground()将第3种数据类型返回到onPostExecute(),在本例中为Void,如果您需要传递其他数据类型,您也可以自由执行。所以:<Void, String, Void> - &gt;在这种情况下Void

execute()方法只是启动AsyncTask()来完成工作:

AddStringTask task=new AddStringTask();
task.execute();

答案 1 :(得分:0)

基本上每当子类扩展AsyncTask&lt; Params1 Progress2 Result3 &GT; 3种通用类型:

  • Params:调用execute
  • 时传入或传递的值
  • 进度:执行进度的值
  • 结果:您从后台执行中获得的产品/结果/值

和4个步骤:

  • onPreExecute:在执行任何执行之前,将调用此方法 首先,您可以设置进度条或任何需要设置的内容 在你做任何事情之前,如LongOperation()。执行(SOMETHING)
  • doInBackground:顾名思义,这是使用Params1进行实际后台任务的地方
  • onProgressUpdate:顾名思义,这就是其中之处 进度更新通知使用Progress2
  • 进行
  • onPostExecute:顾名思义,这就是之后的地方 执行任务并返回结果Result3

示例1:

private class LongOperation extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText(result); // txt.setText(result);
            // might want to change "executed" for the returned string passed
            // into onPostExecute() but that is upto you
            if (progressDialog.isShowing()) {
                progressDialog.dismiss();

            }
        }

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(context);
            progressDialog.setMessage("Processing...");
            progressDialog.show();
        }
    }
}

启动后台任务1:

new LongOperation().execute();

示例2:

private class GetXMLTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            String output = null;
            for (String url : urls) {
                output = getOutputFromUrl(url);
            }
            return output;
        }

        private String getOutputFromUrl(String url) {
            StringBuffer output = new StringBuffer("");
            try {
                InputStream stream = getHttpConnection(url);
                BufferedReader buffer = new BufferedReader(
                        new InputStreamReader(stream));
                String s = "";
                while ((s = buffer.readLine()) != null)
                    output.append(s);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return output.toString();
        }
// Makes HttpURLConnection and returns InputStream
        private InputStream getHttpConnection(String urlString)
                throws IOException {
            InputStream stream = null;
            URL url = new URL(urlString);
            URLConnection connection = url.openConnection();

            try {
                HttpURLConnection httpConnection = (HttpURLConnection) connection;
                httpConnection.setRequestMethod("GET");
                httpConnection.connect();

                if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    stream = httpConnection.getInputStream();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return stream;
        }

        @Override
        protected void onPostExecute(String output) {
            outputText.setText(output);
        }
    }
}

启动后台任务2:

// URL = "http://alkathirikhalid.com/message.html"
GetXMLTask task = new GetXMLTask();
        task.execute(new String[] { URL });

示例3:

public class PostAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
    private Context context;

    @Override
    protected String doInBackground(Pair<Context, String>... params) {
        context = params[0].first;
        String name = params[0].second;

        HttpClient httpClient = new DefaultHttpClient();
        // http://10.0.2.2:8080/hello
HttpPost httpPost = new HttpPost("http://mail-portal.appspot.com/hello"); // 10.0.2.2 is localhost's IP address in Android emulator
        try {
            // Add name data to request
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("name", name));
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity());
            }
            return "Error: " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase();

        } catch (ClientProtocolException e) {
            return e.getMessage();
        } catch (IOException e) {
            return e.getMessage();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(context, result, Toast.LENGTH_LONG).show();
    }
}

启动后台任务3:

 new PostAsyncTask().execute(new Pair<Context, String>(this, "Some String"));

进一步资源:

ctypes doc

答案 2 :(得分:0)

这是来自AsyncTask.java here

public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }

它需要变量参数,因此当你调用execute方法时,它实际上调用了这个方法。

从这里它所做的全部是`exec.execute(mFuture) enter image description here

mFuture已在AsyncTask构造函数中设置如下图所示。 enter image description here

因此在mWorker call()方法内部,您实际上可以看到正在调用的doInBackground()。希望它能回答你的疑问:)