线程池的使用(一)

来源:互联网 发布:淘宝客服遇到无赖顾客 编辑:程序博客网 时间: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
原创粉丝点击