android新建进程操作UI进程中的view报错android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original

报错:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views。

下面提供一种解决方式:thread+Handle,其中Handle使用静态内部类的方式实现更新主进程中的view.

 

问题:

Runnable runnable = new Runnable() {
     @Override
    public void run() {
        try {
            sleep(3000);
            TextView2.setText("123");
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
    }
};
new Thread(runnable).start();

TextView2.setText("123");是在新进程中访问UI(主)进程的控件。错误存在的原因。

我们使用handle,在handle写更新控件的操作,然后在新开启的进程new thread中发送handle消息,通知更新即可。

代码如下:

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                sleep(3000);
                Message message = myHandle.obtainMessage();
                myHandle.sendMessage(message);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
};
new Thread(runnable).start();

其中 Message message = myHandle.obtainMessage();
        myHandle.sendMessage(message);是自定义的handle,在里面实现更新view

代码如下:

public class MainActivity extends Activity {

    public static ImageView imageView1;
    MyHandle myHandle = new MyHandle(MainActivity.this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView1=findViewById(R.id.textVeiw);
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
        try {
               sleep(3000);
                Message message = myHandle.obtainMessage();
                myHandle.sendMessage(message);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
            }
     };
     new Thread(runnable).start();
    }
    private static class MyHandle extends Handler {
        private WeakReference activityWeakReference;

        public MyHandle(MainActivity activity) {
            super();
            this.activityWeakReference = new WeakReference(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (activityWeakReference == null) {
                return;
            }
            activity.imageView1.setText("12345");//实现更新view
        }
    }
}

这里使用了静态内部类+弱引用的方式实现handle,可能比一般的实现方式稍微复杂,,原因是直接在MainActivity中使用handle会有内存泄漏的危险,可以看一下:https://blog.csdn.net/qq_25066049/article/details/83345692

 

 

你可能感兴趣的:(android)