Android:CalledFromWrongThreadException即使在使用runOnUIThread时也是如此

时间:2014-02-11 04:48:55

标签: php android mysql android-asynctask

我正在构建一个应用程序,它通过与我的localhost中的php文件进行通信来发送登录数据并进行身份验证(参考本教程http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/)。我尝试了它就像教程所说(在主线程中),但它给出了NetworkOnMainThreadException。但是当我在AsyncTask中尝试以下内容时,即使我正在使用runOnUIThread,它也会产生CalledFromWrongThreadException。

@Override
        protected Void doInBackground(Void... arg0) {

            String username = etUsername.getText().toString();
            String password = etPass.getText().toString();
            UserFunctions userFunctions = new UserFunctions();
            final JSONObject json = userFunctions.loginUser(username, password);

            try {
                if (json.getString(KEY_SUCCESS) != null) {

                    String res = json.getString(KEY_SUCCESS);
                    if (Integer.parseInt(res) == 1) {
                        // user successfully logged in
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                errorTxt.setText("");
                                //if (pDialog.isShowing())
                                    //pDialog.dismiss();
                                Intent intent = new Intent(
                                        getApplicationContext(),
                                        AgentHome.class);
                                startActivity(intent);
                            }
                        });

                    }
                } else if(json.getString(KEY_ERROR) != null) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //if (pDialog.isShowing())
                                //pDialog.dismiss();
                            errorTxt.setText("Invalid username or password");
                        }
                    });

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

编辑:我将errorTxt.setText(“”)放在runOnUIThread中,但仍然会出现以下错误

02-11 10:27:20.397: E/AndroidRuntime(4957): FATAL EXCEPTION: AsyncTask #1
02-11 10:27:20.397: E/AndroidRuntime(4957): Process: collector.lbfinance, PID: 4957
02-11 10:27:20.397: E/AndroidRuntime(4957): java.lang.RuntimeException: An error occured while executing doInBackground()
02-11 10:27:20.397: E/AndroidRuntime(4957):     at android.os.AsyncTask$3.done(AsyncTask.java:300)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.FutureTask.run(FutureTask.java:242)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.lang.Thread.run(Thread.java:841)
02-11 10:27:20.397: E/AndroidRuntime(4957): Caused by: java.lang.NullPointerException
02-11 10:27:20.397: E/AndroidRuntime(4957):     at collector.lbfinance.MainActivity$GetPassword.doInBackground(MainActivity.java:108)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at collector.lbfinance.MainActivity$GetPassword.doInBackground(MainActivity.java:1)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at android.os.AsyncTask$2.call(AsyncTask.java:288)
02-11 10:27:20.397: E/AndroidRuntime(4957):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
02-11 10:27:20.397: E/AndroidRuntime(4957):     ... 4 more

4 个答案:

答案 0 :(得分:1)

errorTxt.setText("");不在ui主题上。您无法从后台线程更新ui。

您也可以点击按钮从edittext获取文本,并将其作为参数直接传递给doInBackground

Asynctask在ui线程上调用onPreExecuteonPostExecute。您应该考虑在这些方法中更新ui。在doInbackground中完成所有背景计算。我认为不需要runOnUiThread

答案 1 :(得分:0)

检查AsyncTask生命周期。您可以在构造函数和以下方法中在UI线程上执行代码:onPreExecute,onProgressUpdate(带有相应的publishProgress调用)和onPostExecute。务必将UI更改代码放在其中一个

答案 2 :(得分:0)

请使用hanlder并将您的回复传递给处理程序,它会起作用。

Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。每个Handler实例都与一个线程和该线程的消息队列相关联。当您创建一个新的Handler时,它被绑定到正在创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并在消息出来时执行它们队列中。

Handler Docs

Handler example

答案 3 :(得分:0)

首先你要在背景中设置文本线程哪个是错的&它给你一个例外,所以先从doInBackground&中删除errorTxt.setText("");。在PreExecute或PostExecute或In Some another UI thread中设置但不在Background中。而且无需使用此

 runOnUiThread(new Runnable() {} 

线程,如果您在后台异步任务中编写代码,那么它也将工作相同。 希望这有帮助。