• AsyncTask应用


    **AsyncTask子类的泛型参数:

    AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承.继承AsyncTask需要指定如下三个泛型参数:

    Params:启动任务时输入的参数类型.

    Progress:后台任务执行中返回进度值的类型.

    Result:后台任务执行完成后返回结果的类型.

    **AsyncTask子类的回调方法:

    doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成.

    onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作.

    onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新.

    onProgressUpdate:当在doInBackground方法中调用publishProgress()方法更新任务执行进度后,将调用此方法.通过此方法我们可以知晓任务的完成进度.

    **使用AsyncTask的注意事项

    ① 必须在UI线程(create()中)中创建AsyncTask的实例.

    ② 只能在UI线程中调用AsyncTask的execute方法.

    ③ AsyncTask被重写的四个方法是系统自动调用的,不应手动调用.

    ④ 每个AsyncTask只能被执行(execute方法)一次,多次执行将会引发异常.

    ⑤ AsyncTask的四个方法,只有doInBackground方法是运行在其他线程中,其他三个方法都运行在UI线程中,也就说其他三个方法都可以进行UI的更新操作.

    例子:

    activity_main.xml:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context=".MainActivity" >
    10 
    11     <Button
    12         android:id="@+id/btn_progress"
    13         android:layout_width="match_parent"
    14         android:layout_height="wrap_content"
    15         android:text="进度条加载" />
    16 
    17 </RelativeLayout>

    progress.xml文件:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3               android:orientation="vertical"
     4               android:layout_width="match_parent"
     5               android:gravity="center"
     6               android:layout_height="match_parent">
     7     <ProgressBar
     8         style="?android:attr/progressBarStyleHorizontal"
     9         android:id="@+id/progress"
    10         android:layout_width="match_parent"
    11         android:layout_height="wrap_content"/>
    12 </LinearLayout>

    Java代码:

     1 package com.example.caobotao.learnasynctask;
     2 
     3 import android.app.Activity;
     4 import android.os.AsyncTask;
     5 import android.os.AsyncTask.Status;
     6 import android.os.Bundle;
     7 import android.widget.ProgressBar;
     8 
     9 import java.util.Scanner;
    10 
    11 /**
    12  * Created by caobotao on 15/12/2.
    13  */
    14 public class ProgressActivity extends Activity{
    15     private ProgressBar progressBar;
    16     private MyAsyncTask myAsyncTask;
    17     @Override
    18     protected void onCreate(Bundle savedInstanceState) {
    19         super.onCreate(savedInstanceState);
    20         setContentView(R.layout.progress);
    21         progressBar = (ProgressBar) findViewById(R.id.progress);
    22         myAsyncTask = new MyAsyncTask();
    23         //启动异步任务的处理
    24         myAsyncTask.execute();
    25     }
    26 
    27     //AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是不能执行的.
    28     @Override
    29     protected void onPause() {
    30         super.onPause();
    31         if (myAsyncTask != null && myAsyncTask.getStatus() == Status.RUNNING) {
    32             //cancel方法只是将对应的AsyncTask标记为cancelt状态,并不是真正的取消线程的执行.
    33             myAsyncTask.cancel(true);
    34         }
    35     }
    36 
    37     class MyAsyncTask extends AsyncTask<Void,Integer,Void>{
    38         @Override
    39         protected void onProgressUpdate(Integer... values) {
    40             super.onProgressUpdate(values);
    41             //通过publishProgress方法传过来的值进行进度条的更新.
    42             progressBar.setProgress(values[0]);
    43         }
    44 
    45         @Override
    46         protected Void doInBackground(Void... params) {
    47             //使用for循环来模拟进度条的进度.
    48             for (int i = 0;i < 100; i ++){
    49                 //如果task是cancel状态,则终止for循环,以进行下个task的执行.
    50                 if (isCancelled()){
    51                     break;
    52                 }
    53                 //调用publishProgress方法将自动触发onProgressUpdate方法来进行进度条的更新.
    54                 publishProgress(i);
    55                 try {
    56                     //通过线程休眠模拟耗时操作
    57                     Thread.sleep(300);
    58                 } catch (InterruptedException e) {
    59                     e.printStackTrace();
    60                 }
    61             }
    62             return null;
    63         }
    64     }
    65 }

    存在问题:

    AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是不能执行的.所以必须等到第一个task的for循环结束后,才能执行第二个task.我们知道,当点击BACK键时会调用Activity的onPause()方法.为了解决这个问题,我们需要在Activity的onPause()方法中将正在执行的task标记为cancel状态,在doInBackground方法中进行异步处理时判断是否是cancel状态来决定是否取消之前的task.

  • 相关阅读:
    Python学习之路【第三篇】--集合
    Python学习之路【第二篇】-pyc简介、Python常用的数据类型及其用法和常用运算符
    Python学习之路【第一篇】-Python简介和基础入门
    NotePad++ 配置Python工作环境
    码农跳槽指南:如何在新公司建立自己的“支配地位”?
    python实现简单的聊天小程序
    真正努力的人,从来不焦虑
    我在公司待了6年,清退我却只花了6分钟
    只有潮水退去后,才知道谁在裸泳
    什么是rpc
  • 原文地址:https://www.cnblogs.com/solar-sys/p/6004943.html
Copyright © 2020-2023  润新知