线程池的使用(一)
来源:互联网 发布:淘宝客服遇到无赖顾客 编辑:程序博客网 时间:2024/05/23 14:21
一.概述
从今天开始,我们介绍一下线程中的一些知识点,我会通过具体的一些案例来告诉大家如何在实际开发中使用多线程。先看一张效果图
二.实现
我们先看看布局文件,这里只讲一下进度条以及两个控制按钮的样式是如何实现的
<ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="3dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_marginBottom="15dp" android:progressDrawable="@drawable/progressbar_selector"/>
这里我们用了一个android:progressDrawable属性,这是重点,我们看看
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <gradient android:endColor="#EEEEEE" android:startColor="#EEEEEE"/> </shape> </item> <item android:id="@android:id/progress"> <clip> <shape> <gradient android:endColor="#ff5555" android:startColor="#ff5555"/> </shape> </clip> </item></layer-list>
这里使用了layer-list标签,layer-list通常用在要显示层叠样式的布局文件中,我们这里的进度条刚好有两层,下面是背景,上面是进度,注意,下面这个item我们使用了clip标签,代表的意思是进行裁剪,如果不写的话是不会出来进度条变化的效果。
下面给出完整代码:
public class MainActivity extends AppCompatActivity { private CheckBox cbCancel; private ProgressBar progressBar; private TextView tv_info1; private TextView tv_info2; private TextView tvCancel; private TextView tvStart; private int num; private FutureTask futureTask; private final int TYPE_MSG_RUN = 1001; private final int TYPE_MSG_DONE = 1002; private android.os.Handler handler = new android.os.Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case TYPE_MSG_RUN: progressBar.setProgress(msg.arg1);//设置进度显示 tv_info1.setText("线程计数:"+msg.arg1); break; case TYPE_MSG_DONE: tv_info1.setText("计数完成"); showStatus(); break; } } }; private Thread thread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); addListener(); } public void initView(){ cbCancel = (CheckBox) findViewById(R.id.cb_cancel); progressBar = (ProgressBar) findViewById(R.id.progressBar); tv_info1 = (TextView) findViewById(R.id.tv_info1); tv_info2 = (TextView) findViewById(R.id.tv_info2); tvCancel = (TextView) findViewById(R.id.tv_cancel); tvStart = (TextView) findViewById(R.id.tv_start); } public void initData(){ progressBar.setProgress(0); progressBar.setMax(100); } public void addListener(){ cbCancel.setOnClickListener(onClickListener); tvStart.setOnClickListener(onClickListener); tvCancel.setOnClickListener(onClickListener); } View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()){ case R.id.tv_start: if(thread == null||futureTask == null||futureTask.isDone()){ //达到最大进度后重新开始 if(progressBar.getProgress() == progressBar.getMax()){ num = 0; } startThread();//当调用cancle(false)时,当前任务并不会中断,如果再次点击启动线程,将会加速任务执行速度 showStatus(); } break; case R.id.tv_cancel: if(futureTask!=null){ //试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消, // 则此尝试将失败。当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。 // 如果任务已经启动,则 mayInterruptIfRunning 参数,true,取消任务,中断线程,任务停止, false,取消任务,不中断线程,也就是说当此参数设置为false时,即使点击了取消按钮,进度条还是会走 // 执行此任务的线程。此方法返回后,对 isDone() 的后续调用将始终返回 true。 // 如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true。 futureTask.cancel(cbCancel.isChecked());//只能取消一次 showStatus(); } break; } } }; public void sendMsg(int num,int what){ Message msg = Message.obtain(); msg.what = what; msg.arg1 = num; handler.sendMessage(msg); } public void startThread(){ Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { while (num<100) { num++; sendMsg(num,TYPE_MSG_RUN); Thread.sleep(100); } sendMsg(num,TYPE_MSG_DONE);//完成 return "Done" ; } }; futureTask = new FutureTask(callable); thread = new Thread(futureTask); thread.start(); } public void showStatus(){ if(thread == null|| futureTask == null){ return ; } StringBuilder sb = new StringBuilder(); sb.append("状态: "); sb.append("\nFutureTask isCancelled(): " + futureTask.isCancelled()); sb.append("\nFutureTask isDone(): " + futureTask.isDone());//当调用cancell方法后,isDone始终返回true sb.append("\n\nThread isAlive(): " + thread.isAlive()); sb.append("\nThread isInterrupted(): " + thread.isInterrupted()); tv_info2.setText(sb.toString()); } @Override protected void onDestroy() { super.onDestroy(); if (futureTask != null && !futureTask.isDone()) { futureTask.cancel(true); } }}
0 0
- 线程池的使用(一)
- 线程池(java.util.concurrent.ThreadPoolExecutor)的使用(一)
- 线程池(java.util.concurrent.ThreadPoolExecutor)的使用(一)
- 线程池(java.util.concurrent.ThreadPoolExecutor)的使用(一)
- Java 并发编程之线程池的使用(一)
- JAVA并发编程(一)JAVA线程池的使用
- 线程池(java.util.concurrent.ThreadPoolExecutor)的使用(一)
- 基础篇:线程的创建与线程池的使用(一)
- Android的线程和线程池(一)
- Python多线程学习(一、线程的使用)
- Python多线程学习(一、线程的使用)
- java线程池(一) 简述线程池的几种使用方式
- Java并发编程——线程池的使用(一) 简单创建线程池
- Android线程池(一)简单使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 项目经验应如何管理和控制项目风险?
- mysql操作语法
- 【C/C++】计时函数比较
- C++静态成员函数小结
- Java学习·基础回顾
- 线程池的使用(一)
- UIImage和Base64转化
- github 删除代码仓库
- Spring之AOP
- mysql性能优化-慢查询分析、优化索引和配置
- 在centos7搜狗拼音输入法安装
- dup和dup2文件描述符相关函数
- 种树畜养,日见其大而不觉而
- 使用事件驱动模型实现高效稳定的网络服务器程序