【问题标题】:how can i Fix this CalledFromWrongThreadException?我该如何修复这个 CalledFromWrongThreadException?
【发布时间】:2017-06-11 11:16:46
【问题描述】:

所以我正在尝试学习 android 网络服务,当我运行我的 代码我得到这个异常你能:

FATAL EXCEPTION: Thread-4
                                                                                      Process: com.example.abdallahmurad.webservices_test, PID: 7328
                                                                                      android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                                          at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6855)
                                                                                          at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1040)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:884)
                                                                                          at android.view.View.requestLayout(View.java:19654)
                                                                                          at android.widget.TextView.checkForRelayout(TextView.java:7363)
                                                                                          at android.widget.TextView.setText(TextView.java:4475)
                                                                                          at android.widget.TextView.setText(TextView.java:4332)
                                                                                          at android.widget.TextView.setText(TextView.java:4307)
                                                                                          at com.example.abdallahmurad.webservices_test.MainActivity$1$1.run(MainActivity.java:52)
                                                                                          at java.lang.Thread.run(Thread.java:761)

这里是 MainActivity 代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ButterKnife.bind(this);


    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
                        HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
                        InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
                        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                        String data = bufferedReader.readLine();
                        textView.setText(data);
                        System.out.println(data);
                        Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            Thread thread = new Thread(runnable);
            thread.start();
        }
    });
}

myfirst_echo_test.php 是一个简单的 php 文件,带有一个 echo""

我的问题是这个异常是什么,我该如何解决?

【问题讨论】:

    标签: android web-services android-webservice


    【解决方案1】:

    你只能从主线程更新 ui

    MainActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
         textView.setText(data);
            }
        });
    

    【讨论】:

      【解决方案2】:

      textView.setText(data); 导致此问题是因为您试图在非 ui 线程中设置 UI 元素的文本。您应该更改代码并通过调用 RunOnUiThread 在 ui 线程中执行此操作:

        runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
                              textView.setText(data);
                               Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
                          }
                      });
      

      如果您尝试在非 ui 线程(如您的 Runnable)内操作任何 UI 元素(不仅是 textView),这种情况总会发生。作为 Runnable 的替代方案,您还可以尝试 AsyncTask 执行您的操作并操作 onPostExecute() 中的 UI 元素。

       new AsyncTask<Void,Void,Void>(){
      
                   String data="";
                          @Override
                          protected Void doInBackground(Void... params) {
      
                              URL dataPath = new URL("http://abdallahmurad.hostkda.com/myfirst_echo_test.php");
                          HttpURLConnection myFirstConnection = (HttpURLConnection) dataPath.openConnection();
                          InputStreamReader inputStreamReader = new InputStreamReader(myFirstConnection.getInputStream());
                          BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                          data = bufferedReader.readLine();
      
                              return null;
                          }
      
                          @Override
                          protected void onPreExecute() {
                              super.onPreExecute();
                          }
      
                          @Override
                          protected void onPostExecute(Void aVoid) {
                              super.onPostExecute(aVoid);
                                textView.setText(data);
                                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
                          }
                      }.execute();
      

      请记住,toast 也必须在 OnPostExecute 中调用。

      【讨论】:

      • 我会将此解决方案与 EventBus 之类的东西结合起来。如果您的活动已死,在 onPostExecute 中您将遇到问题。
      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2020-11-13
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 2016-02-24
      • 2023-02-16
      相关资源
      最近更新 更多