AsyncTask的使用方法和理解_async_task_sleep-程序员宅基地

技术标签: Android  

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只能被执行一次,否则多次调用时将会出现异常

 

示例代码:

 

复制代码
<?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"
    >
<TextView    
       android:layout_width="fill_parent"   
       android:layout_height="wrap_content"   
       android:text="Hello , Welcome to Andy's Blog!"/>  
    <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>
复制代码

 

复制代码
package sn.demo;

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

public class DownloadTask extends AsyncTask<Integer, Integer, String> {
    //后面尖括号内分别是参数(线程休息时间),进度(publishProgress用到),返回值 类型  
    
    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() {
        // TODO Auto-generated method stub
        Log.d("sn", "00000");
        super.onPreExecute();
    }
    
    /*
     * 执行时机:在onPreExecute 方法执行后马上执行,该方法运行在后台线程中
     * 作用:主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected String doInBackground(Integer... params) {
        // TODO Auto-generated method stub
        Log.d("sn", "1111111");
        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次
     * @see android.os.AsyncTask#onProgressUpdate(Progress[])
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        Log.d("sn", "2222222222");
        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 result) {
        // TODO Auto-generated method stub
        Log.d("sn", "3333333333");
        
        super.onPostExecute(result);
    }




}
复制代码
复制代码
package sn.demo;

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.main);
        
        initView();
    }
    private void initView() {
        // TODO Auto-generated method stub
        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) {
                // TODO Auto-generated method stub
                DownloadTask dt=new DownloadTask(AsyncTaskDemoActivity.this,pb,tv);
                dt.execute(100);
            }
        });
    }
}
复制代码

 

 

参照连接

http://blog.csdn.net/cjjky/article/details/6684959

http://blog.csdn.net/zhenyongyuan123/article/details/5850389

http://www.eoeandroid.com/thread-102664-1-1.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shuitawuhen/article/details/49584295

智能推荐

SpringBoot中普通类与注入容器的类获取容器其他bean的方法-程序员宅基地

一、普通类获取Spring容器中bean的方法在Spring框架中,是无法在普通类中通过注解方式获取容器中的实例bean的。如果我们需要在普通类中获取Spring容器中的实例,就需要一些其他手段了。SpringBoot工程在普通类中获取Sping容器实例的方法,其原理和传统方法其实都是一样的,都是通过获取上下文环境,从上下文环境中拿到Spring容器管理的实例springUtil类package com.umetrip.utils;import org.springframework.beans.

LPC11U3x存储器映射_lpc11u3线路图-程序员宅基地

1、MCU不同变量的存储位置 局部变量:栈区(Stack)—— 由编译器自动分配和释放 局部静态变量:静态区 —— 程序结束后由系统释放 全局变量:静态区的常量区 全局静态变量:静态区 堆区(Heap)—— 一般由程序员自行分配和释放,分配malloc和new申请的区域关于malloc和new的区别见链接:https://blog.cs..._lpc11u3线路图

我的程序员之路(二) 分类: 程序人生 201...-程序员宅基地

生活也许是美好的,但是现实也是残酷的。就像我们现在这些无忧无虑的大学生,谁知道,两年后毕业,会是一个什么样子。都说居安思危,但是那个同学回去为自己的将来要走的路好好的思考过。也许,是的,是想过,但是想是想过了,谁有是在自己想过以后真实的去付出行动了。也许现在我的感触很深,我有想过自己的路怎么走。我算是在一所还算不错的二本学校的计算机学院,学习软件工程(.NET)专业。其实我们这个专业除...

零基础怎么入门web前端,前端开发需要学什么?一文带你高效快速入门前端_web前端开发_牛仔码农@的博客-程序员宅基地

最近几年Web前端的火热,不仅仅是因为招聘市场需求量大,还有一个重要的原因就是,入行门槛低,入门简单。但是真的是这样吗?有些0基础的小白也能转行吗?很多同学都有这样的疑虑,个人认为没那么简单。下面我总结了一些关于web前端入门的东西,希望对大家有所帮助。之所以说Web门槛低,主要体现在两个方面:1. Web前端入门门槛低体现在HTML和CSS上,前者只是结构标签,后者是样式配置,入门是非常简单的,大家可以到网上找一些相关视频学习,推荐动力节点老杜讲的web前端三剑客(html+css+Jav_web前端开发

python3爬取笔趣阁全站小说,分类保存到本地,多线程控制一次爬多少本_59.68.177.203:8080/self_插一个眼的博客-程序员宅基地

十年老书虫,极爱看小说;话不多说,先上效果这个是2021-6-21的爬笔趣阁代码的,不保证笔趣阁更新了还能用。所有小说分类(笔趣阁上共8个小说分类)下面是爬取1-10页的500本小说,一页50本,使用了多线程一个线程下载一本小说,500本小说一共2.8G,一次爬取多少页,多少本小说只需要改变页码和书名列表下标参数即可,代码中都有注释,简单易懂。下多少本小说就要开多少个线程,一次下载完,我的cpu i58300 开1500个线程就很卡了;还有这边多线程有点bug,每次运行代码时,在所有线程启动之前可_59.68.177.203:8080/self

TabHost和TabWidget写出微信下面选项卡的界面-程序员宅基地

xml界面代码:<?xml version="1.0" encoding="UTF-8"?><TabHost   android:id="@android:id/tabhost"   android:background="@android:color/black"   android:layout_width="fill_parent"   android:..._安卓tabwidget微信界面

随便推点

k8s 启动命令cmd_kubernetes命令(一)-程序员宅基地

版权声明:本文为博主原创文章,支持原创,转载请附上原文出处链接和本声明。1、查看pod格式:kubectl get pod2、查看node格式:kubectl get node3、查看pod详细信息格式:kubectl describe pod pod名[root@chushi ~]#kubectl describe pod redisName: redisNamespace: ..._k8s 启动命令

消息队列-功能、性能、运维对比_消息队列在运维系统中的应用-程序员宅基地

消息延迟投递,当消息产生送达消息队列时,有些业务场景并不希望消费者立刻收到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。延迟队列一般分为两种,基于消息的延迟和基于队列的延迟:基于消息的延迟:为每条消息设置不同的延迟时间,当队列有新消息进入的时候根据延迟时间排序,当然这样会对性能造成较大影响。基于队列的延迟:设置不同延迟级别的队列,队列中每个消息的延迟时间都是相同的,这样免去了基于延迟时间排序对性能带来的损耗,通过一定的扫描策略即可投递超时的消息。延迟消息的使用场景比如异常检测重试,订单超时取_消息队列在运维系统中的应用

推荐一个基于 SpringBoot2 + MybatisPlus 的商城管理系统-程序员宅基地

点击▲关注 “爪哇笔记” 给公众号标星置顶更多摄影技巧第一时间直达项目简介SpringBoot2+MybatisPlus+SpringSecurity+jwt+redis+Vue ...

谷歌邮箱lmap服务器填什么_邮箱帐号测试-程序员宅基地

排查邮箱故障:通过“测试帐号”排查邮箱使用中存在的问题?一、进入测试1.1、收信测试(Imap/Pop3)" 测试IMAP服务器成功":表明该帐号可正常收信。1.2、发信测试(Smtp)" 测试SMTP服务器成功":表明该帐号可正常发信。二、问题排查2.1、连接到IMAP服务器/连接到POP3服务器连接到IMAP服务器 失败!连接到POP3服务器 失败!2.1.1.配置填写有误问题描述未按官网要求..._谷歌邮件注册imap怎么填

3D转换详解_关于三维旋转,以下说法正确的是?-程序员宅基地

1.3D转换简述及坐标轴解析`3D`的特点近大远小 物体和面遮挡不可见三维坐标系x 轴:水平向右--**注意:x 轴右边是正值,左边是负值** y 轴:垂直向下--**注意:y 轴下面是正值,上面是负值** z 轴:垂直屏幕--**注意:往外边的是正值,往里面的是负值**2.3D转换`3D`转换知识要点`3D`位移:`translate3d(x..._关于三维旋转,以下说法正确的是?

Oracle数据库及在DOS命令下面的简单操作_dos查看oracle数据库-程序员宅基地

在Oracle数据库注释用--表明为注释,但以下用//或--代表解释;数据库不怎么区分大小写;先说说一些简单Oracle数据库操作的语句:使用语句创建普通用户:Create user username identified by password; //创建普通用户Grant resource,connect,dba to username; // 赋予权限Alter user user..._dos查看oracle数据库