根据一个笔试题引出的思考

题目:页面上现有ProgressBar控件progressBar,请用书写线程以10秒的的时间完成其进度显示工作

效果如下

布局文件和简单 就是一个Progressbar
Activity的代码如下(其实我一直不知道改把activity叫什么好 窗口?或者活动?)

public class ProgressTest extends Activity {
    private ProgressBar prs1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progressbar);
        prs1 = (ProgressBar) findViewById(R.id.progressBar1);
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                int progressBarMax =prs1.getMax();
                while(prs1.getProgress()!=progressBarMax){
                    int progressBarnew=progressBarMax/10;

                    prs1.setProgress(prs1.getProgress()+progressBarnew);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    //注释的代码可以让他一直跑
                    /*if((prs1.getProgress()+progressBarnew)==progressBarMax){
                        prs1.setProgress(progressBarnew);   
                    }*/
                }



            }


        }) 
        ;
        thread.start();
    }
}

这是第一种方式 在oncreat方法中新启一个线程来给进度条加进度
讲道理 这是在子线程中更新ui吧。

那我们就来看另一种方法


public class ProgressTest extends Activity {
    private ProgressBar prs1;
    private Handler handler = new Handler();
    private Runnable myRunnable = new Runnable() {
        public void run() {
            handler.postDelayed(this, 1000);
            int progressBarMax = prs1.getMax();
            if (prs1.getProgress() <= progressBarMax) {
                int progressBarnew = progressBarMax / 10;
                prs1.setProgress(prs1.getProgress() + progressBarnew);
            }

        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progressbar);
        prs1 = (ProgressBar) findViewById(R.id.progressBar1);
         handler.post(myRunnable);

    }


}

这是另一种方法 post(runnable)与handler绑定的线程上执行,不需要另外新建线程。
看post源码

   public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

其实也是sendMessage方法的一种 。。。
讲道理还是sendmessage。。。

利用Timer类和Timertask来实现

public class ProgressTest extends Activity {
    private ProgressBar prs1;
    Timer time = new Timer();
    Button btn1;
    private Handler handler = new Handler() {

        public void handleMessage(Message msg) {

            if (msg.what == 1) {

                int progressmax = prs1.getMax();
                if (prs1.getProgress() != progressmax) {
                    int progressnew = progressmax / 10;
                    prs1.setProgress(prs1.getProgress() + progressnew);
                }

            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progressbar);
        prs1 = (ProgressBar) findViewById(R.id.progressBar1);
        time.schedule(new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                Message msg = new Message();
                msg.what = 1;
                handler.sendMessage(msg);
            }

        }, 0, 1000);

    }

}

TimerTask的run方法并不是多线程的run方法,虽然实现了Runnable,但是仅仅是为了表示它是可执行的,并不代表它必须通过线程的方式来执行的。
Timer和TimerTask的简单组合是多线程的嘛?不是,一个Timer内部包装了“一个Thread”和“一个Task”队列,这个队列按照一定的方式将任务排队处理,包含的线程在Timer的构造方法调用时被启动,这个Thread的run方法无限循环这个Task队列,若队列为空且没发生cancel操作,此时会一直等待,如果等待完成后,队列还是为空,则认为发生了cancel从而跳出死循环,结束任务;循环中如果发现任务需要执行的时间小于系统时间,则需要执行,那么根据任务的时间片从新计算下次执行时间,若时间片为0代表只执行一次,则直接移除队列即可。

但是是否能实现多线程呢?可以,任何东西是否是多线程完全看个人意愿,多个Timer自然就是多线程的,每个Timer都有自己的线程处理逻辑,当然Timer从这里来看并不是很适合很多任务在短时间内的快速调度,至少不是很适合同一个timer上挂很多任务,在多线程的领域中我们更多是使用多线程中的:

Executors.newScheduledThreadPool

来完成对调度队列中的线程池的处理,内部通过new ScheduledThreadPoolExecutor来创建线程池的Executor的创建,当然也可以调用:

Executors.unconfigurableScheduledExecutorService

方法来创建一个DelegatedScheduledExecutorService其实这个类就是包装了下下scheduleExecutor,也就是这只是一个壳,英文理解就是被委派的意思,被托管的意思。

posted @ 2016-04-21 19:09  Tesi1a  阅读(114)  评论(0编辑  收藏  举报