题目:页面上现有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,也就是这只是一个壳,英文理解就是被委派的意思,被托管的意思。