AsyncTask的使用方法和理解

在Android中实现异步任务机制有两种方式,Handler和AsyncTask。

Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。

为了简化操作,Android1.5提供了工具类android.os.AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。

-------------------------------------------
AsyncTask<Params,Progress,Result>
三种泛型类型分别代表“Params启动任务执行的输入参数”、“Progress后台任务执行的进度”、“Result后台计算结果的类型”。
----------------------------------------

1、对于耗时的操作,我们的一般方法是开启“子线程”。如果需要更新UI,则需要使用handler

2、如果耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。在这种情况下我们就可以考虑使用类AsyncTask来异步执行任务,不需要子线程和handler,就可以完成异步操作和刷新UI。

3、AsyncTask:对线程间的通讯做了包装,是后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。

4、使用方法:共分为两步,自定义AsyncTask,在耗时的地方调用自定义的AsyncTask。可以参照以下代码示例。

step1:继承AsyncTask<Params,Progress,Result>

           Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。

           Progress:子线程执行的百分比

           Result:返回值类型。和doInBackground()方法的返回值类型保持一致。

step2:实现以下几个方法:执行时机和作用看示例代码,以下对返回值类型和参数进行说明

          onPreExecute():无返回值类型。不传参数

          doInBackground(Params... params):返回值类型和Result保持一致。参数:若无就传递Void;若有,就可用Params

          publishProgress(Params... params):在执行此方法的时候会直接调用onProgressUpdate(Params... values)

          onProgressUpdate(Params... values):无返回值类型。参数:若无就传递Void;若有,就可用Progress

          onPostExecute(Result  result) :无返回值类型。参数:和Result保持一致。

step3:在调用自定义的AsyncTask类中生成对象;

          执行  :对象.excute(Params... params);

小注:

   1) Task的实例必须在UI thread中创建

 

    2) execute方法必须在UI thread中调用

 

    3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground=\'#\'" onProgressUpdate(Progress...)这几个方法

 

    4) 该task只能被执行一次,否则多次调用时将会出现异常
DownloadTask
package test.ban.com.asynctask;/**
 * Created by apple on 16/8/25.
 */

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import static android.R.string.cancel;
import static android.content.ContentValues.TAG;

/**
 * 作者:ban on 16/8/25 15:52
 */
public class DownloadTask extends AsyncTask<Integer, Integer, String> {

    private Context mContext = null;
    private ProgressBar mProgressBar = null;
    private TextView mTextView = null;

    public DownloadTask(Context context, ProgressBar pb, TextView tv) {
        this.mContext = context;
        this.mProgressBar = pb;
        this.mTextView = tv;
    }

    /**
     * 第一个执行的方法
     * 执行时机:在执行实际的后台操作前,被UI 线程调用
     * 作用:可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
     *
     * @see android.os.AsyncTask#onPreExecute()
     */
    @Override
    protected void onPreExecute() {
        mProgressBar.setVisibility(View.VISIBLE);
        Log.e("onPreExecute", "========onPreExecute========");
        super.onPreExecute();
    }

    /**
     * 执行时机:在onPreExecute 方法执行后马上执行,该方法运行在后台线程中
     * 作用:主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
     */
    @Override
    protected String doInBackground(Integer... params) {
        Log.e("doInBackground", "========doInBackground========");
        for (int i = 0; i <= 100; i++) {
            mProgressBar.setProgress(i);
            publishProgress(i);
            try {
                Thread.sleep(params[0]);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return "执行完毕";
    }

    /**
     * 执行时机:这个函数在doInBackground调用publishProgress时被调用后,UI 线程将调用这个方法.虽然此方法只有一个参数,
     * 但此参数是一个数组,可以用values[i]来调用
     * 作用:在界面上展示任务的进展情况,例如通过一个进度条进行展示。此实例中,该方法会被执行100次
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.e("onProgressUpdate", "========onProgressUpdate========"+values[0]);
        mTextView.setText(values[0] + "%");
        super.onProgressUpdate(values);
    }

    /**
     * 执行时机:在doInBackground 执行完成后,将被UI 线程调用
     * 作用:后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户
     * result:上面doInBackground执行后的返回值,所以这里是"执行完毕"
     *
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(String s) {
        Log.e("onPostExecute", "========onPostExecute========");
        Toast.makeText(mContext, "执行完成", Toast.LENGTH_SHORT).show();
        mProgressBar.setVisibility(View.INVISIBLE);
        super.onPostExecute(s);
    }

    /**
     * //取消一个正在执行的任务,onCancelled方法将会被调用
     * @param s
     */
    @Override
    protected void onCancelled(String s) {
        Log.i(TAG, "onCancelled() called");
        mTextView.setText("cancelled");
        mProgressBar.setProgress(0);
    }
}
AsyncTaskDemoActivity
package test.ban.com.asynctask;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskDemoActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    private Button download;
    private TextView tv;
    private ProgressBar pb;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        tv = (TextView) findViewById(R.id.tv);
        pb = (ProgressBar) findViewById(R.id.pb);
        download = (Button) findViewById(R.id.download);
        download.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                DownloadTask dt = new DownloadTask(AsyncTaskDemoActivity.this, pb, tv);
                dt.execute(100);
            }
        });
    }
}

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
    >
    <Button
        android:id="@+id/download"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Download"/>
    <TextView
        android:id="@+id/tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="当前进度显示"/>
    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"/>
</LinearLayout>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值