`

AsyncTask的学习与总结

阅读更多
AsyncTask的介绍:
AsyncTask的实现的原理:
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作
提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新)
最后反馈执行的结果给UI主线程.

 

 

使用的优点:

 

l  简单,快捷

 

l  过程可控

l  结构清晰,功能定义明确

 

l  对于多个后台任务时,简单,清晰

 

使用的缺点:

 

l  在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

 

2 )Handler异步实现的原理和适用的优缺点

 

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message-àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

l  在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

 

 

AsyncTask定义了三种泛型类型 ParamsProgressResult

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

使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:

  • doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
  • onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

有必要的话你还得重写以下这三个方法,但不是必须的:

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute()        这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()             用户调用取消时,要做的操作

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

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

 

下面提供例子来理解

package com.deltalab.urecommend.ui;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;

import com.deltalab.urecommend.dbhelper.IntegralOpenHelper;
import com.deltalab.urecommend.domin.IntegralMall;
import com.deltalab.urecommend.service.IMService;
import com.orhanobut.logger.Logger;
import com.wang.avi.AVLoadingIndicatorView;

import java.util.List;

import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;

/**
 * Created by asus on 2016/10/10.
 * 异步执行动画
 * 生成该类对象,并调用execute方法之后
 * 首先执行的是onProExecute方法
 * 其次执行doInBackgroup方法
 *
 * @author Administrator
 * @time 2016/10/10 22:21
 */
public class AnimAsyncTask extends AsyncTask<Integer, Integer, String> {

    private AVLoadingIndicatorView mAvi;
    private Context context;
    private int integralSize = 0;
    IntegralOpenHelper mHelper;



    public AnimAsyncTask(AVLoadingIndicatorView mAvi, Context context) {
        super();
        this.mAvi = mAvi;
        this.context = context;
    }

    /**
     * 这里的Integer参数对应AsyncTask中的第一个参数
     * 这里的String参数对应AsyncTask中的第三个参数
     * 该方法并不运行在UI线程中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
     * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作
     *
     * @param params
     * @return
     */
    @Override
    protected String doInBackground(Integer... params) {
        // 先判断有没有网络,如果没有网络则不从服务器中获取直接使用本地的数据
        boolean avaliable = isAvaliable(context);
        if (avaliable) {  // 表示有网络,则需要加载数据
            BmobQuery<IntegralMall> query = new BmobQuery<IntegralMall>();
            query.findObjects(new FindListener<IntegralMall>() {
                @Override
                public void done(List<IntegralMall> list, BmobException e) {
                    if (e == null) {
                        integralSize = list.size();
                        // 将数据保存到本地
                        for (int i = 0; i < list.size(); i++) {
                            IMService.getInstance().saveOrUpdateIntegralPrizes(list.get(i));
                        }
                        publishProgress(list.size());   // 用于将动画暂停                      
                    } else {
                        Logger.e(e.getErrorCode() + ":" + e.getMessage());
                    }
                }
            });
        }

        return "";
    }

    /**
     * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
     * 在doInBackground方法执行结束之后再运行,并且运行在UI线程中,可以对UI空间进行设置
     *
     * @param result
     */
    @Override
    protected void onPostExecute(String result) {

    }

    /**
     * 该方法运行在UI线程中,并且运行在UI当中可以对UI空间进行设置
     */
    @Override
    protected void onPreExecute() {
        mAvi.setIndicator("LineSpinFadeLoaderIndicator");
        // 进行加载数据操作
        startAnim();
    }

    /**
     * 这里的Integer参数对应AsyncTask中的第二个参数
     * 在doInBackground方法当中,每次调用publishProgress方法都会触发onProgressUpdate执行
     * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
     *
     * @param values
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        int value = values[0];
        if(value == integralSize){
            stopAnim();     // 将动画暂停
        }
    }

    /**
     * 获取活动网络信息
     *
     * @param context
     * @return
     */
    private static NetworkInfo getActiveNetworkInfo(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context
                .CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * 判断网络是否可用
     * 需要权限:<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
     * return true 表示可用     return false 表示不可用
     *
     * @param context
     * @return
     */
    public static boolean isAvaliable(Context context) {
        NetworkInfo info = getActiveNetworkInfo(context);
        return info != null && info.isAvailable();
    }

    /**
     * 开启加载动画
     */
    public void startAnim() {
        mAvi.show();
    }

    /**
     * 暂停动画
     */
    public void stopAnim() {
        mAvi.hide();
    }

}

 


 AnimAsyncTask asyncTask = new AnimAsyncTask(mAvi,LoadingDataActivity.this);
        asyncTask.execute(1000);

 

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载中"
            android:textSize="30dp"/>

               <com.wang.avi.AVLoadingIndicatorView
            android:id="@+id/avi"
            style="@style/AVLoadingIndicatorView.Large"
            android:layout_width="wrap_content"
            app:indicatorColor="@color/red"
            android:layout_marginTop="20dp"
            android:layout_height="wrap_content"/>

    </LinearLayout>

 

 

 

分享到:
评论

相关推荐

    开源中国源码学习数据篇(一)之android-async-http框架和AsyncTask

    总结起来,这份学习资料是关于如何在Android应用中利用`android-async-http`框架进行高效网络请求,并结合`AsyncTask`实现UI的流畅交互。通过对`TestUI`的实践,开发者可以加深对这两者理解,提高Android应用开发的...

    9Handler&AsyncTask实验报告

    - 理解AsyncTask:学习如何使用AsyncTask来启动后台任务,以及如何在任务完成后或进度更新时更新UI。 - 应用场景:实验通过周期性改变Activity的界面控件属性,模拟了实时数据更新或者定时任务的场景,这在很多...

    安卓拍照上传录像监控录屏相关-android录音上传到服务器上传使用AsyncTask异步任务.rar

    7. **学习与实践**: 这些功能的实现涉及到Android多媒体处理、网络编程等多个领域,对于初学者来说,理解并实践这些代码有助于提升技能。同时,理解AsyncTask的工作原理,以及如何在Android中正确地处理网络请求和...

    Otto_AsyncTask_Fragment_Test Demo

    总结来说,"Otto_AsyncTask_Fragment_Test Demo"展示了如何在Android应用中利用Otto进行组件通信,结合AsyncTask处理后台任务,以及Fragment构建可复用的界面模块。这个Demo对于理解和实践Android组件间通信和异步...

    Android应用源码之AsyncTask_Download2_应用.zip

    此外,由于Android系统的内存管理特性,AsyncTask并不是永久运行的,当Activity销毁时,与之相关的AsyncTask也会被取消。因此,在Activity的生命周期方法中,需要正确管理AsyncTask的生命周期。 总结起来,这个项目...

    Android中AsyncTask的用法实例[收集].pdf

    总结来说,AsyncTask为Android开发者提供了一种简便的方式来处理异步任务,特别是那些需要与UI线程交互的任务。通过正确实现AsyncTask的方法,可以有效地避免阻塞UI线程,并确保应用界面的流畅和响应性。随着Android...

    安卓学习实践总结

    "安卓学习实践总结"这一标题揭示了作者在深入探索安卓开发时所做的各种实验和项目,旨在通过实践经验来巩固理论知识。描述中的重复强调了实验的重要性,暗示了这些小实验在理解安卓开发工作原理上的价值。 在安卓...

    Android知识系统总结

    在Android知识系统总结中,我们可以探索一系列关于Android应用开发的重要概念和实践经验。这个压缩包包含的资源非常丰富,包括7个完整的Android应用程序源代码、学习笔记、开发入门指南以及一些入门书籍,为初学者和...

    Android学习笔记总结初学者必看.rar_Android java_android

    在Android学习之旅中,初学者会遇到各种概念和实践技巧,这份"Android学习笔记总结初学者必看"的文档正是为了帮助他们系统性地掌握这一领域。以下是对这份压缩包内容的详细解读。 首先,Android是由Google开发的一...

    基于Android的在线学习平台。graduationAndroidAPP.zip

    总结来说,基于Android的在线学习平台是一个综合性的项目,涵盖了Android开发的多个方面,包括但不限于语言选择(如Kotlin)、界面设计、网络编程、本地存储、多媒体处理、通知服务、权限管理和测试优化。...

    Android 学习资料批量下

    学习笔记是个人对学习过程的理解和总结,往往包含了重点难点的提炼、常见问题的解决方案以及实践经验的分享。这些笔记可能是其他开发者的心得体会,对于巩固知识、解决实际问题具有很高的参考价值。笔记可能涵盖各种...

    Android学习路线探讨.pdf

    任玉刚老师总结的学习路线为Android开发者提供了一个全面的学习蓝图,从基础知识点到深入技术细节,从系统核心机制到实战技能,再到学习方法和态度,都给出了明确的指导。通过这样的学习路线,开发者可以循序渐进地...

    Android学习路线和职业规划探讨.pdf

    深入的知识点则涉及到Activity的启动模式和标记位、AsyncTask的版本演变、Service的启动与绑定状态、AIDL和Binder通信、多进程设计、事件分发机制、View系列的绘制流程、消息队列的运作、动画的实现细节以及性能优化...

    Android 系统知识总结+培训课程+笔记

    这个“Android系统知识总结+培训课程+笔记”包含了一系列深入学习Android开发的重要资料,涵盖了从基础到高级的各种主题,适合Android开发者或者对Android系统有兴趣的学习者使用。这份资料可能与在青岛巴黎春天广场...

    ChuckNorrisApi-AsyncTask-Example:示范uma api usando异步消费任务

    在Android应用中,更新UI或与用户进行交互必须在主线程中进行,因此对于网络调用等后台任务,我们需要使用AsyncTask或其他异步解决方案。 在这个例子中,首先,开发者会创建一个继承自AsyncTask的类,通常命名为`...

    android面试与总结

    以下是对"android面试与总结"这一主题的深入探讨: 首先,让我们关注四大组件,这是Android应用的基础构造块。它们包括: 1. **Activity**:应用程序中的一个可视化用户界面,负责处理用户交互。理解Activity的...

    android总结

    一个AsyncTask实例通常与一个UI组件关联,执行过程分为三个步骤:`onPreExecute()`(在主线程运行,准备任务),`doInBackground(Params... params)`(在后台线程运行,执行任务),`onPostExecute(Result result)`...

    Android代码-Android开发总结资料

    2. **基础语法与布局设计**:学习Java语言基础,理解Android应用程序的四大组件(Activity、Service、BroadcastReceiver、ContentProvider)的用法。同时,掌握XML布局文件的编写,了解各种视图组件(TextView、...

    SimpleMessenger:SimpleMessenger - Android(Java 套接字和 AsyncTask - 开始分布式系统)

    总结,SimpleMessenger项目是学习Android中Java套接字和AsyncTask的实践案例,它演示了如何在Android设备上构建分布式通信系统。理解并掌握这些技术对于Android开发者来说至关重要,因为它们为实现更复杂的网络应用...

    安卓实训课程设计总结.zip

    这是一段充满挑战与创新的学习旅程,旨在帮助学员掌握安卓应用的全生命周期管理,包括设计、开发、调试和发布。以下是对整个实训过程的详细总结: 一、Android环境搭建 在开始Android开发之前,首先需要安装Android...

Global site tag (gtag.js) - Google Analytics