【问题标题】:Android : is it safe to create a View and a Handler in a worker threadAndroid:在工作线程中创建视图和处理程序是否安全
【发布时间】:2014-04-25 12:41:47
【问题描述】:

android 文档指出:

Andoid UI 工具包不是线程安全的。因此,您不得从工作线程操作您的 UI — 您必须从 UI 线程对您的用户界面进行所有操作。

我的第一个问题是:通过在工作线程中创建视图,然后使用处理程序将其附加到窗户。 (请参阅下面的代码来说明我的意思)。

看起来没问题,因为我看不到任何2个线程同时修改视图的情况。我错过了什么吗?

public class DemoActivity extends Activity {

    RelativeLayout rootLayout;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = new Handler(Looper.getMainLooper());
        setContentView(R.layout.activity_main);
        rootLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
        myThread.start();
    }

    private Thread myThread = new Thread(){
        @Override
        public void run() {
            final TextView textView = new TextView(DemoActivity.this);
            textView.setText("I'm a TextView created in a worker Thread");
            handler.post(new Runnable() {
                @Override
                public void run() {
                        rootLayout.addView(textView);
                }
            });
        }
    };

我的第二个问题更多的是关于创建 Handler 的线程:

在工作线程本身创建Handler可以吗? (见下面的代码)

有内存泄漏的风险吗?

   private Thread myOtherThread = new Thread(){
        @Override
        public void run() {
            final TextView textView = new TextView(DemoActivity.this);
            textView.setText("I'm a TextView created in a worker Thread");
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                        rootLayout.addView(textView);
                }
            });

            //just to illustrate that the thread don't terminate immediately
            //but it don't touch the textView anymore.
            while(true){  
                doStuff();
            }
        }
    };
}

【问题讨论】:

  • 2.没关系,因为您在 Handler 构造函数中隐式指定了 Looper。默认情况下,它会尝试为线程获取默认 Looper,并且由于您的线程没有,它会崩溃。
  • 1.它可能是安全的,取决于 View 的实现。如果 View 使用默认构造函数创建处理程序,那么它将是不安全的。

标签: java android multithreading thread-safety


【解决方案1】:
  1. 不,如上所述,它不安全。

由于不安全,Android 公开了一个单线程模型,以确保 UI 不会同时被不同的线程修改。这样做是为了避免此类问题。

  1. 是的,我认为没关系,因为它是另一个线程:)

也可以看看runOnUiThread()

【讨论】:

  • 您能详细说明第 1 点吗?有没有看到 UI 线程和工作线程同时修改 textView 的情况。 (对 textView 的所有修改都是在将其附加到窗口之前完成的)
  • 我刚刚尝试了测试代码,它没有崩溃。我敢打赌它是安全的。虽然 View 刚刚创建,没有附加到父级,但没有人会同时修改它。
  • 但它仍然感觉像是一个糟糕的设计,并且可能会根据特定的 View 实现而崩溃。
  • @shkschneider 我在一个单独的线程中创建了一个 TextView,为其分配了一个文本,然后通过 Handler 将其添加到一个 Activity 中。
  • 如果你在工作线程中创建一个 View,那么发布到它的事件将在工作线程而不是 UI 线程中传递,因此 View 将无法可靠地自我更新。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多