多线程
特点:
1.本质上它是一个线程类,继承Thread类、分装Handler类。
2.有自己的内部Looper对象,可以进行Looper循环。
3.通过Looper对象传递给Handler对象,在handleMessage方法中执行异步任务。
4.创建完HandlerThread后,必须调用HandlerThread.start()方法,Thread会调用run方法,然后创建Looper对象。
5.开启一个线程起到多个线程的作用,处理任务是串行执行,安排消息的发送顺序进行处理
作用:
1.实现多线程,在工作线程中执行任务,如耗时任务。
2.异步通信、消息传递,把工作线程的执行结果传递给主线程,然后主线程执行相关的UI操作。
工作原理:
1.通过继承Thread类,快速创建一个带有Looper对象的新工作线程。
2.通过封装Handler类,快速创建Handler,与其他线程进行通信。
使用步骤:
1.创建HandlerThread实例对象
//传入参数 = 线程名字,作用 = 标记该线程 HandlerThread thread = new HandlerThread("handlerThread");
2.启动线程
thread.start();
3.创建工程线程Handler,复写handleMessage()
Handler wordHandler = new Handler(thread.getLooper()){ @Override public void handleMessage(@NonNull Message msg) { //消息处理 } };
4.使用工作线程Handler向工作线程的消息队列发送消息
//int型参数(what)
workHandler.sendEmptyMessage(0);
5.结束线程,即停止线程的消息循环(实际上是调用Looper的quit方法而最终执行的则是MessageQueue中的removeAllMessageLocked方法,该方法主要是把MessageQueue消息池中所有的消息全部清空,无论是延时还是非延时消息)
//释放资源 thread.quit();
AsyncTask是一个抽象类,需要创建一个子类去继承它。AsyncTask可以获取异步任务的进度,可以通过Cancel()方法取消执行未完的异步任务,还可以多个线程执行等等,它指定三个参数:Params、Progress、Result,用途:
- Params: 执行时发送任务给参数的类型。
- Progress: 后台任务执行时发布的进度。
- Result: 任务执行结束,返回的结果。
开始执行异步任务时,需要经过四个步骤:
1.onPreExecute(): //执行任务前的准备操作
2.doInBackground()://接收输入参数,执行任务中的耗时操作,返回线程任务执行的结果
3.onProgressUpadte(): //在主线程显示线程任务执行的进度
4.onPostExecute(): //接收线程任务执行结果,将执行结果显示到UI组件
停止线程执行方式(代码后面再附上):
1.使用停止线程方法task.cancel(true),它虽然调用了onCancelled()方法,但打印的进度没有停止。
2. 调用停止方法,让它后面的进度也停止,在InterruptedException的异常里面加break。
@Override protected String doInBackground(String... strings) { int count = 0; int length = 1; while (count < 100) { count += length; publishProgress(count); try { Thread.sleep(50); Log.d("TEST", "进度:" + count + "%"); } catch (InterruptedException e) { e.printStackTrace(); // 点击取消(true),停止加载 Log.d("TEST","进入异常处理"); break; } } return null; }
3.效果如下(已经停止了进度操作):
AsncyTask的并行执行(new出两个子类,分别为task1,task2),同时点击开始按钮(task1.execut()/task2.execut()),它会执行完一个再执行另一个,效果图如下:
AsncyTask的串行执行(把task1.execut()和task2.execut()分别改成task1.executeOnExecuteor()、task2.executeOnExecuteor()),效果如下:
附上代码,代码中有HandlerThread(计时器)和AsyncTask(加载进度)的案例(小白一只,代码写不好的地方希望指点,谢谢)(点击我获取,提取码:7vij)