1

Android问题:当我给一个视图设置文本时,这个视图什么时候会更新UI?这是我的案例1:

for(int i=0;i< 2000; i++){
    aTextView.setText("a"+i);
}

aTextView 是一个 MyTextView,它从 TextView 扩展而来。我将 onDraw 覆盖为:

public static int counterP = 0;

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    counterP++;
    Log.d("MYButton", "onDraw: " + counterP);
}

从日志中,我可以看到,打印的 counterP 不是结果。在循环中,onDraw 方法只被调用了 2-4 次。

我做了另一个测试,案例2:

boolean notInit = true;
List<String> cmdList = null;
long stSelfRefresh = 0;
String contentStr;
TextView selfTv;

public void onSelfRefreshTv(View v) {
    if (cmdList == null || cmdList.isEmpty()) {
        Log.e(TAG, "empty now, reset");
        notInit = true;
    }
    if (notInit) {
        cmdList = new ArrayList<String>();
        for (int i = 0; i < 2000; i++) {
            cmdList.add("a" + i);
        }
        stSelfRefresh = SystemClock.uptimeMillis();
        notInit = false;
        selfTv = (MyTextView) findViewById(R.id.mytv);
    }
    contentStr = cmdList.remove(0);
    Log.d(TAG, "contentStr = " + contentStr);
    selfTv.setText(contentStr);

    if (!cmdList.isEmpty()) {
        if (!mHandler.sendEmptyMessage(99)) {
            Log.e(TAG, "SKIP my self");
        }
    } else {
        Log.d(TAG, "Cost time: " + (SystemClock.uptimeMillis() - stSelfRefresh));
    }
}

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 99:
                onSelfRefreshTv(null);
                break;
            default:
                break;
        }
    }
};

情况 2 的结果是 counterP 被打印出来。1-2000。

不知道为什么每次都会更新textView?你对此有什么想法吗?

提前致谢。

** * ***添加案例 3 * ** * ** * ****

for(int i=0;i< 2000;i++){ 
   contentStr = cmdList.remove(0);
   mHandler.sendEmptyMessage(100);

}  

private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case 100:
                selfTv.setText(contentStr);
                break;
            default:
                break;
        }
    }
};       

** * ***案例 3 结束* ** * ** * *** 案例 3 的测试结果与案例 1 相似。

4

1 回答 1

1

看起来您正在 UI 上运行代码Thread

这意味着:只要你的代码在运行,绘图代码就不能运行。在您的onDraw()循环完成计数后调用,并且只有最后一个值实际绘制在显示器上。
就这么简单。

如果您想在显示器上进行计数,可以使用 aAsyncTask将计数部分移动到非 UI 中Thread

    new AsyncTask<Void,Integer, Void>() {
        @Override
        protected Void doInBackground(Void... voids) {
            for (int i =0; i<2000; i++) {
                publishProgress(i);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            aTextView.setText("a"+values[0]);
        }
    };

你的第二种情况是这样的:

  1. 您准备了包含所有 2000 个元素的列表。
  2. 将列表的第一个元素设置为TextView并从列表中删除该项目。
  3. Thread只要系统认为合适,就向自己发送一条消息以在 UI 上运行。
  4. 放开 UI Thread 的控制权。
  5. 您的代码实际上已经完成并且系统调用onDraw().
  6. 来自 4 的消息得到处理,您从 2 重新开始。

您会看到系统在Thread循环中间获得了对 UI 的控制权。这就是它明显计数的原因。

案例 3 与案例 2 不同:

您正在循环发送 2000 条消息,而没有让系统处理它。

于 2013-09-12T09:44:52.657 回答