我正在阅读有关AsyncTask的文章,并尝试了下面的简单程序。但这似乎并不奏效。我该怎么做呢?

public class AsyncTaskActivity extends Activity {

    Button btn;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener((OnClickListener) this);
    }

    public void onClick(View view){
        new LongOperation().execute("");
    }

    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();
                }
            }
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }
}

我只是试图在后台进程中5秒后更改标签。

这是我的main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="10"
        android:padding="10dip">
    </ProgressBar>
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Progress" >
    </Button>
    <TextView android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Replace"/>
</LinearLayout>

当前回答

更改代码如下所示:

@Override
protected void onPostExecute(String result) {

    runOnUiThread(new Runnable() {
        public void run() {
            TextView txt = (TextView) findViewById(R.id.output);
            txt.setText("Executed");
        }
    });
}

其他回答

简单:

LongOperation MyTask = new LongOperation();
MyTask.execute();

我相信它是正确执行,但你试图改变UI元素在后台线程,这不会做。

修改你的调用和AsyncTask如下:

调用类

注意:我个人建议在任何执行AsyncTask线程的地方使用onPostExecute(),而不是在扩展AsyncTask本身的类中。我认为这使代码更容易阅读,特别是如果你需要AsyncTask在多个地方处理略有不同的结果。

new LongThread() {
    @Override public void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText(result);
    }
}.execute("");

LongThread类(extends AsyncTask):

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

    return "Executed";
}      

在使用AsyncTask时,有必要创建一个类继任者,并在其中注册我们所需的方法的实现。本节课我们将学习三种方法:

doInBackground -将在一个新线程中执行,在这里我们解决了所有困难的任务。因为非主线程不能访问UI。

onPreExecute -在doInBackground之前执行,并可以访问UI

onPostExecute -在doInBackground之后执行(如果AsyncTask被取消就不工作-关于这个在下一课中),并可以访问UI。

这是MyAsyncTask类:

class MyAsyncTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected void onPreExecute() {
    super.onPreExecute();
    tvInfo.setText("Start");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Your background method
    return null;
  }

  @Override
  protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    tvInfo.setText("Finish");
  }
}

这是如何调用你的Activity或Fragment:

MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();

背景/理论

AsyncTask允许你在后台线程上运行一个任务,同时将结果发布到UI线程。

用户应该始终能够与应用程序进行交互,所以这很重要 以避免阻塞主(UI)线程的任务,如 从网上下载内容。 这就是我们使用AsyncTask的原因。 它通过包装UI线程消息队列和处理程序提供了一个简单的接口,允许您发送和处理来自其他线程的可运行对象和消息。

实现

AsyncTask是一个泛型类。(它在构造函数中接受参数化类型。)

它使用以下三种泛型类型:

Params -执行时发送给任务的参数类型。

进度-在后台计算期间发布的进度单元的类型。

结果——后台计算结果的类型。

异步任务并不总是使用所有类型。要将一个类型标记为未使用的,只需使用类型Void: 私有类MyTask扩展AsyncTask<Void, Void, Void>{…}

这三个参数对应三个你可以在AsyncTask中覆盖的主要函数:

doInBackground (Params…) onProgressUpdate(进步…) onPostExecute(结果)

执行AsyncTask

调用execute(),并将参数发送给后台任务。

会发生什么

On main/UI thread, onPreExecute() is called. To initialize something in this thread. (E.g. show a progress bar on the user interface.) On a background thread, doInBackground(Params...) is called. (Params were passed via execute.) Where the long-running task should happen. Must override at least doInBackground() to use AsyncTask. Call publishProgress(Progress...) to update the user interface with a display of progress (e.g. UI animation or log text printed) while the background computation is still executing. Causes onProgressUpdate() to be called. On the background thread a result is returned from doInBackground(). (This triggers the next step.) On main/UI thread, onPostExecute() is called with the returned result.

例子

在这两个例子中,“阻塞任务”都是从网上下载的。

示例A下载图像并在ImageView中显示它,而 例B下载一些文件。

一个例子

doInBackground()方法下载图像并将其存储在BitMap类型的对象中。onPostExecute()方法获取位图并将其放置在ImageView中。

class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bitImage;

    public DownloadImageTask(ImageView bitImage) {
        this.bitImage = bitImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mBmp = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mBmp = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mBmp;
    }

    protected void onPostExecute(Bitmap result) {
        bitImage.setImageBitmap(result);
    }
}

例B

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

例B执行

new DownloadFilesTask().execute(url1, url2, url3);

异步任务POST请求示例:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();

class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
    String URL;
    List<NameValuePair> parameters;

    private ProgressDialog pDialog;

    public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
    {
        this.URL = url;
        this.parameters = params;
    }

    @Override
    protected void onPreExecute()
    {
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Processing Request...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params)
    {
        try
        {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            HttpPost httpPost = new HttpPost(URL);

            if (parameters != null)
            {
                httpPost.setEntity(new UrlEncodedFormEntity(parameters));
            }
            httpResponse = httpClient.execute(httpPost);

            httpEntity = httpResponse.getEntity();
            return EntityUtils.toString(httpEntity);

        }  catch (Exception e)
        {

        }
        return "";
    }

    @Override
    protected void onPostExecute(String result)
    {
        pDialog.dismiss();

        try
        {

        }
        catch (Exception e)
        {

        }
        super.onPostExecute(result);
    }
}