Android开发经验谈Android技术知识Android开发

Android开发艺术之线程

2019-05-09  本文已影响11人  Android高级开发

本篇的主要内容是Android的线程和线程池:

一.概述

1.含义:线程是CPU调度的最小单元。

2.特点:线程是一种受限的系统资源。即线程不可无限制的产生且线程的创建和销毁都有一定的开销。

Q:如何避免频繁创建和销毁线程所带来的系统开销?

A:采用线程池,池中会缓存一定数量的线程,进而达到效果。

3.分类:

Picture

二.线程形态

对于主线程和子线程相信已经非常熟悉了,现在主要学习以下三种形态的线程:

1.AsyncTask

a.AsyncTask:一种轻量级的异步任务类。

在Android中实现异步任务机制有两种方式:(https://www.jianshu.com/p/1c79fb5296b6" target="_blank">Handler]和AsyncTask。

b.AsyncTask是抽象的泛型类,其组成成员有:

//含义:在执行AsyncTask时不需要传入参数给后台任务、使用整型数据来作为进度显示单位,最后使用布尔型数据来反馈执行结果
public abstract class AsyncTask<Void, Integer, Boolean>

比如自定义一个AsyncTask,来模拟一个下载任务:

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {  

    @Override//初始化一个ProgressDialog  
    protected void onPreExecute() {  
        progressDialog.show();  
    }  

    @Override//具体的下载逻辑
    protected Boolean doInBackground(Void... params) {  
        try {  
while (true) {  
    int downloadPercent = doDownload();  
    publishProgress(downloadPercent);  
    if (downloadPercent >= 100) {  
        break;  
    }  
}  
        } catch (Exception e) {  
return false;  
        }  
        return true;  
    }  

    @Override//显示当前的下载进度
    protected void onProgressUpdate(Integer... values) {  
        progressDialog.setMessage("当前下载进度:" + values[0] + "%");  
    }  

    @Override//提示任务的执行结果  
    protected void onPostExecute(Boolean result) {  
        progressDialog.dismiss();  
        if (result) {  
Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();  
        } else {  
Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();  
        }  
    }  
}  

任务的启动和停止只需要以下几行代码:

// 开始任务  
DownloadTask mDownloadTask  = new DownloadTask();  
mDownloadTask .execute();  

// 停止任务  
mDownloadTask .cancel(true);  

c.工作原理

注意:AsyncTask不适用于进行特别耗时的后台任务,而是建议用线程池。

2.HandlerThread

a.HandlerThread是一个线程类,它继承自Thread

与普通Thread的区别:具有消息循环的效果。原理:

b实现方法

private HandlerThread myHandlerThread ;  
private Handler handler ;  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
   //实例化HandlerThread
   myHandlerThread = new HandlerThread("myHandler") ;  
   //开启HandlerThread
   myHandlerThread.start();  
   //将Handler对象与HandlerThread线程绑定
   handler =new Handler(myHandlerThread.getLooper()){  
       @Override  
        publicvoid handleMessage(Message msg) {  
           super.handleMessage(msg);  
// 这里接收Handler发来的消息,运行在handler_thread线程中  
//TODO...  
        }  
    };  

   //在主线程给Handler发送消息  
   handler.sendEmptyMessage(1) ;  
   new Thread(new Runnable() {  
       @Override  
        publicvoid run() {  
           //在子线程给Handler发送数据  
           handler.sendEmptyMessage(2) ;  
        }  
    }).start();  
}  
@Override  
protected void onDestroy() {  
   super.onDestroy();  
   //终止HandlerThread运行
   myHandlerThread.quit() ;  
}  

c.用途:

在之前学习浅析HandlerThread时知道在子线程使用Handler的方法,其实HandlerThread的出现使得这一过程变得更加简便,更多解析见浅析HandlerThread

3.IntentService

a.IntentService是一个继承自Service的抽象类

b.优点:

c.IntentService内部封装了HandlerThread和Handler,工作原理:

Picture

d.使用方法:

Intent intent = new Intent(this, MyService.class);
intent.putExtra("xxx",xxx);  
startService(intent);//启动服务

注意:无需手动停止服务,onHandleIntent()执行结束之后,IntentService会自动停止。

三.线程池

1.优点

//构造参数
public ThreadPoolExecutor(int corePoolSize,
      int maximumPoolSize,
      long keepAliveTime,
      TimeUnit unit,
      BlockingQueue<Runnable> workQueue,
      ThreadFactory threadFactory,
      RejectedExecutionHandler handler) {

3.ThreadPoolExecutor的默认工作策略

4.ThreadPoolExecutor线程池的分类:

我自己是一名从事了5年Android的老程序员,辞职目前在做讲师,今年年初我花了一个月整理了一份最适合2019年学习的Android学习干货,各个方面都有整理,送给每一位Android开发的小伙伴,这里是开发者聚集地,欢迎初学和进阶中的小伙伴。

加QQ群:457848807(招募中)

image
上一篇下一篇

猜你喜欢

热点阅读