非UI线程可以去刷新UI吗(timertask调用progressbar的setProgress的特例)

今天我里面的大漠同学问了这样一个问题,先看看他粘贴的源代码如下:

TimerTask task = new TimerTask() {
			public void run()
				{
					if (timeFlag)
					{
						if (timeRemain > 0)
						{
							timeRemain -= 1;
							timeProgress.setProgress(timeRemain);
							
						}
						else
						{
							if (!bDialogShow)
							{
								bDialogShow = true;
								gameView.isgameover = true;
								mHandler.sendEmptyMessage(MSG_RESULT_DIALOG_SHOW);
							}
						}
					}
				}
		};
		
timer = new Timer();
timer.schedule(task, 0, 1000);

他的问题和疑惑是:

这个为什么没报错啊 ?
timeProgress.setProgress(timeRemain);------不是说不能在非UI线程里更新View吗?

ok,下面我们来具体分析一个这个问题:

我知道我们都有一个这样的准则就是在android里面非ui线程是不能去修改ui线程里面的ui控件的

但问题的事实在这里,却和我们想象的有一定差异,那么问题的具体原因在哪里呢?或者更多的朋友把问题都归结为timertask就运行在主线程里面或者其它,而忽略了一个很重要的东西:在timertask的run方法里面的setprogress(int)方法,为了更好的有助于我们分析,在查看源代码之后我们可以知道这个方法会调用到private synchronized void refreshProgress(int id, int progress, boolean fromTouch) 方法,下面我附上源代码:

private synchronized void refreshProgress(int id, int progress, boolean fromTouch) {
        if (mUiThreadId == Thread.currentThread().getId()) {
            doRefreshProgress(id, progress, fromTouch);
        } else {
            RefreshProgressRunnable r;
            if (mRefreshProgressRunnable != null) {
                // Use cached RefreshProgressRunnable if available
                r = mRefreshProgressRunnable;
                // Uncache it
                mRefreshProgressRunnable = null;
                r.setup(id, progress, fromTouch);
            } else {
                // Make a new one
                r = new RefreshProgressRunnable(id, progress, fromTouch);
            }
            post(r);
        }
    }

从源代码里面我们可以看到当当前刷新的线程不是主线程的时候,ProgressBar会去自动new一个刷新的线程,所以这和刷新的时候在不在主线程里面调用setProgress方法关系不大,从表面上看似乎是在非UI线程里面去修改了主线程的控件,而实际上并非这样。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值