• android报错android.view.ViewRootImpl$CalledFromWrongThreadException【本文转载】


    报错信息:android.view.ViewRootImpl$CalledFromWrongThreadException

    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6648)
    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:976)
    at android.view.ViewGroup.invalidateChild(ViewGroup.java:5084)
    at android.view.View.invalidateInternal(View.java:12743)
    at android.view.View.invalidate(View.java:12707)
    at android.view.View.invalidate(View.java:12691)
    at android.widget.TextView.checkForRelayout(TextView.java:7168)
    at android.widget.TextView.setText(TextView.java:4357)
    at android.widget.TextView.setText(TextView.java:4214)
    at android.widget.TextView.setText(TextView.java:4189)
    at org.lujx.MainActivity$2.run(MainActivity.java:148)
    at java.lang.Thread.run(Thread.java:818)

    报错原因:操作UI时报错,先贴上完整的异常信息栈。简单翻译一下就是,线程调用异常:只有创建了视图层级的原始线程才可以修改这个视图

    解决方法:

    1.使用handler接收单独立的网络请求线程的返回结果,并处理UI。

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
           super.handleMessage(msg);
           if (msg.what == 1) {
             Bundle data = msg.getData();
             String val = data.getString("value");
             //设置UI
             tvCode.setText(val);
             Log.i(TAG, "请求结果:" + val);
           } else if (msg.what ==0) {
             Toast.makeText(getApplicationContext(),"请求资源不成功",Toast.LENGTH_LONG).show();
           }
      }
    };
     
    /**
     * 处理网络请求的线程
     */
    private class RequestThread extends Thread {
      @Override
      public void run() {
         
         //网络请求
         String string = 请求结果
         Message msg = new Message();
         Bundle data = new Bundle();
     
        //将获取到的String装载到msg中
         data.putString("value", string);
         msg.setData(data);
         msg.what = 1;
         //发消息到主线程
         handler.sendMessage(msg);           
        }
    }
     
    //点击事件启动新线程
    public void test(View v){
       new RequestThread().start();
    }

    2.使用 runOnUiThread API接口,先看一下官方文档的解释,使用这个API可直接在其他线程中处理UI事件,不必担心线程安全问题。因为sdk已经帮我们想好了办法。

        /**
         * Runs the specified action on the UI thread. If the current thread is the UI
         * thread, then the action is executed immediately. If the current thread is
         * not the UI thread, the action is posted to the event queue of the UI thread.
         *
         * 执行特定的UI线程上的操作,如果当前线程就是UI线程,此操作会立即执行。
         * 如果不是,该操作会被发送到UI线程中的事件消息队列中
         * @param action the action to run on the UI thread
         */
        public final void runOnUiThread(Runnable action) {
            if (Thread.currentThread() != mUiThread) {
                mHandler.post(action);
            } else {
                action.run();
            }
        }

    3、如果是初次使用线程的新手先确认一下是否必须使用线程,之前遇到过在主线程中没有任何程序,却在里面建立一个子线程,进行跑程序

    ————————————————
    版权声明:本文为CSDN博主「lujx_1024」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/LJX_ahut/article/details/89432576

  • 相关阅读:
    手动去除迅雷7广告
    MIPS学习笔记
    龙芯中断系统
    《ecos增值包》之FAT文件系统篇
    MIPS架构学习笔记
    【3D数学】之向量
    【温故Delphi】之窗口ShowModal
    【Manage It】之项目规划
    【3D数学】之坐标系
    【Manage It】之启动项目
  • 原文地址:https://www.cnblogs.com/hahayixiao/p/12132428.html
Copyright © 2020-2023  润新知