一个Demo快速上手AsyncTask

正所谓说不如做,今天我们通过一个Demo快速上手AsyncTask。

为了解决新线程不能更新UI组件的问题,Android提供了许多解决方案,这里我们使用更轻量级的AsyncTask,适用于简单的异步处理,不需借助线程和Handler即可实现。


AsyncTask是一个抽象类,继承时需指定如下三个泛型参数:

  • Params 启动任务执行的输入参数的类型,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比类型,比如Integer
  • Result 后台执行任务最终返回的结果,比如String。

public abstract class AsyncTask<Params, Progress, Result> {


使用AsyncTask通过如下三步:

1.继承AsyncTask并为三个泛型参数指定类型,不需要则指定为void。

2.根据需要实现他的方法:

  • doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。可以调用publishProgress(Progress…)来更新任务的进度。
  • onProgressUpdate(Progress…)可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。doInBackground调用publishProgress时触发此方法。
  • onPreExecute()当任务执行之前开始调用此方法,完成一些初始化准备工作,可以在这里显示进度对话框。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回。

3.调用AsyncTask子类的实例execute执行任务。


使用AsyncTask类,以下是几条必须遵守的准则:

  • Task的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,应该由Android系统调用。
  • 该task只能被执行一次,否则多次调用时将会出现异常;

下面看一个下载的小Demo,快速上手。

我们先写布局文件,一个线性布局LinearLayout里面有一个Button触发下载操作,一个ScrollView里面包着一个TextView用于显示内容。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="startTask"
        android:text="AsyncTask" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/show_tv_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World!" />

    </ScrollView>

</LinearLayout>

然后我们开始核心代码的编写:

1.继承AsyncTask并为三个泛型参数指定类型,不需要则指定为void:

    class DownTask extends AsyncTask<URL,Integer,String>{


2.根据需要实现他的方法:

在onPreExecute中进行预处理操作,设置ProgressDialog:

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(mContext);
            progressDialog.setTitle("任务正在执行中···");
            progressDialog.setMessage("惟楚有才,权兴权意.");
            progressDialog.setCancelable(false);
            progressDialog.setMax(200);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.show();
        }

在doInBackground中进行耗时网络访问操作:

        @Override
        protected String doInBackground(URL... urls) {
            StringBuilder stringBuilder = new StringBuilder();
            try {
                URLConnection urlConnection = urls[0].openConnection();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"utf-8"));
                String line = null;
                while((line = bufferedReader.readLine()) != null){
                    stringBuilder.append(line + "\n");
                    hasRead++;
                    publishProgress(hasRead);
                }
                return stringBuilder.toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

doInBackground调用publishProgress时触发此方法,在onProgressUpdate中进行进度更新:

        @Override
        protected void onProgressUpdate(Integer... values) {
            showContent.setText("已读:" + values[0] + "行.");
            progressDialog.setProgress(values[0]);
        }

在onPostExecute中进行收尾操作,设置内容,隐藏ProgressDialog:

        @Override
        protected void onPostExecute(String result) {
            showContent.setText(result);
            progressDialog.dismiss();
        }

3.在Button的响应方法中调用AsyncTask子类的实例execute执行任务:

    public void startTask(View view) throws MalformedURLException{
        DownTask downTask = new DownTask(this);
        downTask.execute(new URL("https://www.uc123.com/"));
    }


最后,因为我们涉及到了对网络的访问,别忘了添加相应权限:

    <uses-permission android:name="android.permission.INTERNET"/>


效果如图:





完整源代码如下:

package com.quan.car.asynctask;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * 权兴权意-2016.11.23
 * 一个Demo快速上手AsyncTask
 */

public class MainActivity extends Activity {

    private TextView showContent;

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

        showContent = (TextView) findViewById(R.id.show_tv_main);
    }

    public void startTask(View view) throws MalformedURLException{
        DownTask downTask = new DownTask(this);
        downTask.execute(new URL("https://www.uc123.com/"));
    }

    class DownTask extends AsyncTask<URL,Integer,String>{

        ProgressDialog progressDialog;
        int hasRead = 0;
        Context mContext;

        public DownTask(Context context){
            mContext = context;
        }

        @Override
        protected String doInBackground(URL... urls) {
            StringBuilder stringBuilder = new StringBuilder();
            try {
                URLConnection urlConnection = urls[0].openConnection();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),"utf-8"));
                String line = null;
                while((line = bufferedReader.readLine()) != null){
                    stringBuilder.append(line + "\n");
                    hasRead++;
                    publishProgress(hasRead);
                }
                return stringBuilder.toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            showContent.setText("已读:" + values[0] + "行.");
            progressDialog.setProgress(values[0]);
        }

        @Override
        protected void onPostExecute(String result) {
            showContent.setText(result);
            progressDialog.dismiss();
        }

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(mContext);
            progressDialog.setTitle("任务正在执行中···");
            progressDialog.setMessage("惟楚有才,权兴权意.");
            progressDialog.setCancelable(false);
            progressDialog.setMax(200);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.show();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值