📜  android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能接触其视图. (1)

📅  最后修改于: 2023-12-03 15:13:22.307000             🧑  作者: Mango

Android视图层次结构线程异常:android.view.ViewRootImpl$CalledFromWrongThreadException

介绍

在Android应用程序开发中,当在非UI线程中访问UI元素时,可能会抛出android.view.ViewRootImpl$CalledFromWrongThreadException异常。这是因为 Android UI 组件只能在 UI 线程中更新。如果您将 UI 操作放在子线程中执行,则应用程序将抛出此异常。

原因

Android 的 UI 组件不是线程安全的。这意味着当一个线程试图更新 UI 元素时,在更新过程中访问该元素的其他线程可能会导致异常。为了避免此类异常,Android 强制线程安全措施,要求所有 UI 更新都必须在 UI 线程中完成。

解决方案

为了解决此异常,您需要确保在 UI 线程中更新 UI 元素。以下是几种常见的解决方案:

使用runOnUiThread方法

runOnUiThread 方法可用于在 UI 线程上运行代码。要在 UI 线程上运行代码,请在 Activity 或 Fragment 中调用此方法。例如:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // 更新UI元素
    }
});
使用Handler

Handler 可以用于在 UI 线程上运行代码。在当前线程中创建一个 Handler 对象,然后使用该 Handler 对象将代码发送到 UI 线程。例如:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        // 更新UI元素
    }
});
使用AsyncTask

AsyncTask 可以在后台线程中执行代码,并在 UI 线程中更新 UI 元素。在 AsyncTask 的 doInBackground 方法中执行后台工作,在 onPostExecute 方法中更新 UI 元素。例如:

public class MyTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... params) {
        // 在后台线程中执行工作
        return null;
    }

    protected void onPostExecute(Void result) {
        // 更新UI元素
    }
}

MyTask task = new MyTask();
task.execute();
总结

android.view.ViewRootImpl$CalledFromWrongThreadException 异常是因为尝试在非 UI 线程上更新 UI 元素所造成的。为了避免此类异常,您需要确保在 UI 线程中更新 UI 元素。可以使用runOnUiThread 方法、Handler 或 AsyncTask 来实现此目的。