0

我在使用 AsyncTask 时遇到了一些问题。如果用户名正确,我试图访问一个应该连接并检查 MySQL 数据库的 php 文件。

我得到的错误如下:

12-01 14:51:25.815: W/dalvikvm(3216): threadid=11: thread exiting with uncaught exception (group=0x40a13300)
12-01 14:51:25.927: E/AndroidRuntime(3216): FATAL EXCEPTION: AsyncTask #1
12-01 14:51:25.927: E/AndroidRuntime(3216): java.lang.RuntimeException: An error occured while executing doInBackground()
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.lang.Thread.run(Thread.java:856)
12-01 14:51:25.927: E/AndroidRuntime(3216): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4607)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:835)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.view.View.requestLayout(View.java:15129)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.widget.TextView.checkForRelayout(TextView.java:6309)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.widget.TextView.setText(TextView.java:3547)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.widget.TextView.setText(TextView.java:3405)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.widget.TextView.setText(TextView.java:3380)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at com.example.obligatorisk.MainActivity$loader.doInBackground(MainActivity.java:101)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at com.example.obligatorisk.MainActivity$loader.doInBackground(MainActivity.java:1)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
12-01 14:51:25.927: E/AndroidRuntime(3216):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-01 14:51:25.927: E/AndroidRuntime(3216):     ... 5 more

(对不起,文字墙,不确定要包括什么)

我正在使用的代码:

protected class loader extends AsyncTask<String, Void, Void> {



    @Override
    protected Void doInBackground(String... params) {



        try {


            httpclient = new DefaultHttpClient();
            httppost = new HttpPost("http://myurl.com/phplogin.php");

            nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair("username_in",username.getText().toString().trim()));
            nameValuePairs.add(new BasicNameValuePair("password_in",password.getText().toString().trim()));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            httppost.getEntity().consumeContent();

            response=httpclient.execute(httppost);

            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            String response = httpclient.execute(httppost, responseHandler);

            //Toast.makeText(MainActivity.this,response, Toast.LENGTH_LONG).show();


            if(response.equalsIgnoreCase("User Found"))
            {

                startActivity(new Intent("com.example.obligatorisk.BROWSER"));

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

        return null;
    }


    // TODO Auto-generated method stub

}

有人可以帮我吗?我被困了好几天了。

4

7 回答 7

1

Xortrox 你得到一个异常,因为你试图从非 UI 线程更新 UI,所以有两种解决方法:首先你可以将你的活动作为参数传递给 AsyncTask 并使用活动的runOnUiThread 方法来更新 UI,但是这种方式缺乏一些优雅。

另一种方式是使用异步交互方式(AsyncTask 是为此创建的=)),AsyncTask 具有在 UI 线程中运行的onPreExecuteonPostExecute方法,因此我建议您将 AsyncTask 的返回类型更改为 HttpResponse 或 String然后在 onPostExecute 中做任何处理和更新 UI,对我来说这种方式是最好的

于 2013-04-18T09:17:34.197 回答
0

日志显示行中的代码com.example.obligatorisk.MainActivity$loader.doInBackground(MainActivity.java:101)尝试修改视图,但在不同的线程中运行。

这个想法AsyncTaskdoInBackgroundrus 在不同的线程中:它不能更改在主线程中创建的视图。这就是为什么你有preExecute并且postExecute

于 2012-12-01T14:15:13.870 回答
0

你得到一个:

android.view.ViewRootImpl$CalledFromWrongThreadException

因为:

只有创建视图层次结构的原始线程才能接触其视图。

我没有解决您的问题的方法,但我可能会为您指明正确的方向。我假设您正在尝试从单独的线程更改视图,但这是行不通的。我相信您必须弄清楚如何从单独的线程中更改 android 视图。我也做了一个快速的谷歌,发现了这个

最佳答案似乎是正确的方法。

于 2012-12-01T14:15:21.560 回答
0

错误是您不能像这样调用 username.gettext().tostring(),password.getText().toString() .. 在调用 AsyncTask 之前尝试获取字符串中的值并使用它..

于 2012-12-01T14:36:52.790 回答
0

你不能把这些行放在 doinbackground

    nameValuePairs.add(new BasicNameValuePair("username_in",**username.getText().toString().trim()**));
    nameValuePairs.add(new BasicNameValuePair("password_in",**password.getText().toString().trim()**));

所以在任务开始之前获取数据并将值传递给异步任务......

于 2012-12-01T14:28:06.657 回答
0

我怀疑在

username.getText().toString().trim())

用户名是 TextView?(至少getText来自那里)

您不能从非 UI 线程访问任何 View 对象。时期。

在启动 AsyncTask 之前将用户名和密码存储在一个字段中,或者在 loader 类中创建一个构造函数来接受用户名和密码,并将它们存储在 loader 类的字段中(首选方案)。

于 2013-04-18T19:37:59.453 回答
0

作为例外:

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

因此,我们可以知道代码有什么问题。

nameValuePairs.add(new BasicNameValuePair("username_in",username.getText().toString().trim()));
nameValuePairs.add(new BasicNameValuePair("password_in",password.getText().toString().trim()));

请确保 doInBackground 中没有 ui 代码。只要您需要访问 UI,请将代码放入 onPostExecute 方法中

于 2015-05-15T07:39:28.760 回答