温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

线程通信-----AsynTask

发布时间:2020-07-25 17:12:11 来源:网络 阅读:718 作者:Cindere_liuqiqi 栏目:开发技术

   AsynTask是Handler的轻量级形式,他可以用作专门的处理耗时操作。有时我们会发现,在主线程睡眠的时候,你执行别的操作的时候会出现“卡屏”状态,这样的效果极为不好。但是我们可以通过AsynTask去解决这个问题。

“卡屏”现象

   (1)创建自定义类对象 模拟耗时操作  

public class Mythread {//自定义类
    public static void sleepy(){
        try {
            Thread.sleep(5000);//模拟耗时操作
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

   (2)在主线程中单击start按钮时调用,单击print按钮时输出hello到控制台

public class MainActivity extends Activity implements OnClickListener{
    private Button startBtn,printbtn;//声明按钮
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //查找资源
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        startBtn = (Button) findViewById(R.id.start);
        printbtn  =(Button) findViewById(R.id.printBtn);
        //为按钮添加监听
        startBtn.setOnClickListener(this);
        printbtn.setOnClickListener(this);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
    }
    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        case R.id.start:
            //自定义线程类睡眠方法的调用
            Mythread.sleepy();//这样使用的话会出现卡屏的状态
            break;
        case R.id.printBtn:
            System.out.println("hello");
            break;
        }
    }
}

(3)结果:

若直接单击print方法没问题,后台输出正常

◆但若先单击start按钮,在单击任意次数的print按钮,都不会马上看见效果,而是等待睡眠5秒之后一并输出。

   如何解决“卡屏”现象?先来看看AsynTast吧。

   一:原理

    其实启动AsynTask,就相当于又开辟了一个线程,在这个线程中专门处理耗时操作,从而不会耽误用户主UI的其他操作,提高用户体验。

   二:创建及常用方法

   1:创建

   继承自AsynTask类,但有三个泛型,这里要注意一下,泛型用的全是包装类。

class MyAsynTask extends AsyncTask<泛型1, 泛型2, 泛型3>

   2:常用方法及参数

(1)泛型3 doInBackground(泛型1):核心的处理耗时工作。方法的返回值类型:泛型3;参数类型:泛型1。参数的值来自于主界面启动AsynTask时传递的值。

   (2)onPostExecute(泛型3):异步结束时执行的方法。参数的值来自于doInBackground的返回值,因此参数的类型为:泛型3.

   (3)onPreExecute():在异步开始时就会执行的方法,也就是会在doInBackground方法执行之前执行。

   (4)onProgressUpdate(泛型2):与主线程UI的交互。参数类型:泛型2。参数的值来源于在doInBackground方法中通过publishProgress传递过来的值。

   三:如何解决“卡屏现象”?

   (1)创建继承自AsynTask的类,重写其中的doInBackground方法

   (2)在doInBackground方法中调用耗时操作

public class MyAsynTask extends AsyncTask<Void, Void, String>{
    @Override
    protected String doInVoid...  params) {
        Mythread.sleepy();//专门处理耗时 的操作
        return null;
    }
}

   (3)在主线程start按钮的监听中,不再是直接调用耗时操作,而是创建AsynTask对象,通过execute启动线程

case R.id.start:
                                                                                                                                                                                                                                                                                                                                                                                      
            //MyAsynTask myAsynTask = new MyAsynTask();
            //myAsynTask.execute();//启动AsynTask,这样就不会出现卡屏的状态了
            break;

   (4)结果:这是无论怎样单击,什么顺序单击均不会出现“卡屏”现象。

    四:AsynTask的应用

   实现的功能:仍然是上一篇博文中进度条与TextView控件的同步使用。

   (1)创建类继承自AsynTask,注意泛型类型的添加

   (2)提供成员属性(主界面上要同步的控件),添加构造方法

private TextView tv;//成员变量
    private ProgressBar bar;//成员变量
    public MyAsynTask(TextView tv, ProgressBar bar) {
        super();
        this.tv = tv;
        this.bar = bar;
    }

   (3)重写onPreExecute()方法:让他给出提示“异步开始了”

// 在异步开始时就会执行的方法,也就是会在doInBackground方法执行之前执行
    @Override
    protected void onPreExecute() {
        tv.setText("异步开始了");
        super.onPreExecute();
    }

   (4)重写doInBackground()方法:完成值的更新

/**
     *  核心处理方法,它的参数有主界面的启动时传递进来
     *  返回类型:泛型3
     *  参数类型:泛型1
     */
    @Override
    protected String doInString...  params) {
        int count = 0;//初始化变量
        for (count = 0; count <= 100; count++) {
            try {
                Thread.sleep(100);//每个一秒count加1
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 传给了onProgressUpdate方法
            publishProgress(count);//这个count将会传给onProgressUpdate中参数
        }
        return count+"";//返回值给onPostExecute方法,以便于结束的判断
    }

   (5)重写onPostExecute()方法:结束时给出提示信息

// 异步结束时执行的方法,参数来自于doInBackground的返回值,也就是这里的vcount;
@Override
protected void onPostExecute(String result) {
    if (result != null) {
        tv.setText("异步结束了,当前的I值为:" + result+"");
    }
    super.onPostExecute(result);
}

   (6)重写onProgressUpdate()方法:更新主UI

// 与主线程UI的交互,参数来自于doInBackground方法中的publishProgress的参数值
@Override
protected void onProgressUpdate(Integer... values) {
    bar.setProgress(values[0]);//更新主Ui中的进度条
    tv.setText(values[0] + "");//更新主UI中的文本框
    super.onProgressUpdate(values);
}

   (7)主UI中为按钮添加监听,启动AsynTask

btn.setOnClickListener(new OnClickListener() {
                                                
            @Override
            public void onClick(View v) {
                //实例化AsynTask对象
            MyAsynTask myAsynTask = new MyAsynTask(tv, bar);
            //启动AsynTask
            myAsynTask.execute();
                                                    
            }

   (8)结果

线程通信-----AsynTask


   其中AsynTask的几个方法的返回值与参数类型还得自己继续的研究研究啊。。有点蒙。。线程通信-----AsynTask


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI