从另一个线程访问主线程视图

时间:2016-07-19 08:15:25

标签: android

我认为无法在新线程中访问主线程视图!

但为什么下面的代码运行没有任何问题?!

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = (TextView) findViewById(R.id.textView);

    new Thread(new Runnable() {
        @Override
        public void run() {

            try {
                textView.append(InetAddress.getByName("192.168.1.252").getHostName() + "\n\n");
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

3 个答案:

答案 0 :(得分:1)

目前here

  

例如,下面是下载一个点击监听器的一些代码   来自单独线程的图像并将其显示在ImageView中:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            Bitmap b = loadImageFromNetwork("http://example.com/image.png");
            mImageView.setImageBitmap(b);
        }
    }).start();
}
     

首先,这似乎工作正常,因为它创建了一个新的线程   处理网络操作。但是,它违反了第二条规则   单线程模型:不要从中访问Android UI工具包   在UI线程之外 - 此示例修改了ImageView   工作线程而不是UI线程。这可能导致未定义   和意外的行为,这可能是困难和耗时的   追查。

所以它有效,但不推荐。 有一些推荐的方法可以做到这一点:

  

要解决此问题,Android提供了几种访问UI的方法   来自其他线程的线程。以下列出了可以提供帮助的方法:

Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)

答案 1 :(得分:0)

试试这个:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.append(InetAddress.getByName("192.168.1.252").getHostName() + "\n\n");
                        }
                    });                 
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

runOnUiThread - 来自活动的方法。如果你在片段内工作,你可以调用getActivity()。runOnUiThread

答案 2 :(得分:0)

解决方案是在新线程内运行UI线程。 这是使用anko的示例。

btn_login.text = "LOGING IN"
doAsync {
   authenticate(email, password)
   uiThread { btn_login.text = "LOGIN" }
}