【问题标题】:No error calling textView.setText from non UI-Thread. Why?从非 UI 线程调用 textView.setText 没有错误。为什么?
【发布时间】:2013-04-10 14:22:28
【问题描述】:

我编写了以下代码,它基本上启动了一个线程,从中更改了 TextView 的文本。

我期待一个错误,因为我从另一个线程而不是主线程访问 TextTiew(UI 元素)。

但它工作正常。据我所知,认为这不应该是可能的。
我不明白,我错过了什么?

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = (TextView) findViewById(R.id.view1);
        tv.setText(Thread.currentThread().getName());

        Thread theThread = new Thread(new aRunnable(tv));
        theThread.start();      
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

public class ARunnable implements Runnable{     
    TextView tv;    
    public ARunnable(TextView tv){
        this.tv = tv;
    }   
    @Override
    public void run() {
        tv.setText(tv.getText()+"----" + Thread.currentThread().getName()); 
    }

}

【问题讨论】:

  • 我假设aThread 真的是ARunnable
  • @Bob 如果您检查这段格式不正确的代码stackoverflow.com/questions/6049882/…,您会发现他所做的与您所做的类似,并且对他来说它崩溃了。这让我更加困惑。
  • 我也是^^ 谁能运行我的代码来测试它是否崩溃?我在三星 Note 10.1 上运行它的输出是 main---Thread-1205
  • @Simon Bob 正如我在下面指出的,Android 不一定会始终如一地执行此检查。尽管如此,即使没有抛出跨线程 UI 调用,这也是一个坏主意。文档(链接如下)明确指出 UI 类不是线程安全的。他们并没有说如果你做错了 Android 总是会抓住你的。很可能在不同版本的 Android 中实现更改,甚至 - 天堂禁止 - 不同的设备已经改变了 UI 方法将抛出的内容。
  • @j__m 谢谢你的解释。我知道这不是它应该做的方式。我想和处理程序一起玩,只是很困惑为什么它不会在没有...的情况下崩溃。

标签: android


【解决方案1】:

docsDo not access the Android UI toolkit from outside the UI thread. 他们并没有说 Android 本身包含任何代码来阻止您这样做。这只是一个坏主意,可能会产生意想不到的副作用。

您应该调用Activity.runOnUiThread() 从其他线程更新 UI。

【讨论】:

  • 其实,如果你试图在主线程之外修改一个View,它会抛出一个异常。
  • 当我尝试访问 AsyncTask 中的 ImageView 时,出现运行时错误,提示我不允许访问。我认为这会发生在所有 UI 元素上。
  • 应该使用handler来设置文本。
  • 据我所知,只有内部类 ViewRootImpl 包含这样的检查。任何不接触 ViewRootImpl 的 UI 代码都不会抛出异常,但它仍然不是线程安全的。
  • 查看 j__m 对该问题的评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多