今天我qq群里面的大漠同学问了这样一个问题,先看看他粘贴的源代码如下:
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);
他的问题和疑惑是:
我知道我们都有一个这样的准则就是在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); } }