0

在我将登录代码实现到异步任务 doInBackground 方法后,我的应用程序崩溃了。我需要这个帮助,因为如果我不为登录实现异步任务,我在真实设备中的应用程序将由于策略问题而崩溃。我能知道我的错误在哪里吗?

下面是我的 doInBackground 任务:

// Checking login in background
    protected String doInBackground(String... params) {
        String email = inputEmail.getText().toString();
        String password = inputPassword.getText().toString();
        UserFunctions userFunction = new UserFunctions();
        JSONObject json = userFunction.loginUser(email, password);

        // check for login response
        try {
            if (json.getString(KEY_SUCCESS) != null) {
                loginErrorMsg.setText("");
                String res = json.getString(KEY_SUCCESS);
                if (Integer.parseInt(res) == 1) {
                    // user successfully logged in
                    // Store user details in SQLite Database
                    DatabaseHandler db = new DatabaseHandler(getApplicationContext());
                    JSONObject json_user = json.getJSONObject("user");

                    // Clear all previous data in database
                    userFunction.logoutUser(getApplicationContext());
                    db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));

                    // Launch HomePage Screen
                    Intent homepage = new Intent(getApplicationContext(), HomepageActivity.class);

                    // Close all views before launching HomePage
                    homepage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(homepage);

                    // Close Login Screen
                    finish();
                } else {
                    // Error in login
                    loginErrorMsg.setText("Incorrect username/password");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

这是我的日志:

08-18 22:34:59.088: E/JSON(382): {"tag":"login","success":1,"error":0,"uid":"502cfeb2e60004.54904838","user":{"name":"user1","email":"user1@gmail.com","created_at":"2012-08-16 22:07:46","updated_at":null}}
08-18 22:34:59.137: E/AndroidRuntime(382): FATAL EXCEPTION: AsyncTask #1
08-18 22:34:59.137: E/AndroidRuntime(382): java.lang.RuntimeException: An error occured while executing doInBackground()
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.lang.Thread.run(Thread.java:1096)
08-18 22:34:59.137: E/AndroidRuntime(382): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.view.View.invalidate(View.java:5139)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.widget.TextView.checkForRelayout(TextView.java:5364)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.widget.TextView.setText(TextView.java:2688)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.widget.TextView.setText(TextView.java:2556)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.widget.TextView.setText(TextView.java:2531)
08-18 22:34:59.137: E/AndroidRuntime(382):  at com.stts.sparetimetradingsystem.LoginActivity$Login.doInBackground(LoginActivity.java:119)
08-18 22:34:59.137: E/AndroidRuntime(382):  at com.stts.sparetimetradingsystem.LoginActivity$Login.doInBackground(LoginActivity.java:1)
08-18 22:34:59.137: E/AndroidRuntime(382):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-18 22:34:59.137: E/AndroidRuntime(382):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-18 22:34:59.137: E/AndroidRuntime(382):  ... 4 more
08-18 22:35:01.867: E/WindowManager(382): Activity com.stts.sparetimetradingsystem.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f0a510 that was originally added here
08-18 22:35:01.867: E/WindowManager(382): android.view.WindowLeaked: Activity com.stts.sparetimetradingsystem.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f0a510 that was originally added here
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewRoot.<init>(ViewRoot.java:247)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.Window$LocalWindowManager.addView(Window.java:424)
08-18 22:35:01.867: E/WindowManager(382):   at android.app.Dialog.show(Dialog.java:241)
08-18 22:35:01.867: E/WindowManager(382):   at com.stts.sparetimetradingsystem.LoginActivity$Login.onPreExecute(LoginActivity.java:106)
08-18 22:35:01.867: E/WindowManager(382):   at android.os.AsyncTask.execute(AsyncTask.java:391)
08-18 22:35:01.867: E/WindowManager(382):   at com.stts.sparetimetradingsystem.LoginActivity$1.onClick(LoginActivity.java:60)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.View.performClick(View.java:2408)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.View.onKeyUp(View.java:4121)
08-18 22:35:01.867: E/WindowManager(382):   at android.widget.TextView.onKeyUp(TextView.java:4431)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.KeyEvent.dispatch(KeyEvent.java:1061)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.View.dispatchKeyEvent(View.java:3740)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
08-18 22:35:01.867: E/WindowManager(382):   at android.widget.ScrollView.dispatchKeyEvent(ScrollView.java:318)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
08-18 22:35:01.867: E/WindowManager(382):   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1667)
08-18 22:35:01.867: E/WindowManager(382):   at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1102)
08-18 22:35:01.867: E/WindowManager(382):   at android.app.Activity.dispatchKeyEvent(Activity.java:2063)
08-18 22:35:01.867: E/WindowManager(382):   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
08-18 22:35:01.867: E/WindowManager(382):   at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
08-18 22:35:01.867: E/WindowManager(382):   at android.os.Handler.dispatchMessage(Handler.java:99)
08-18 22:35:01.867: E/WindowManager(382):   at android.os.Looper.loop(Looper.java:123)
08-18 22:35:01.867: E/WindowManager(382):   at android.app.ActivityThread.main(ActivityThread.java:4627)
08-18 22:35:01.867: E/WindowManager(382):   at java.lang.reflect.Method.invokeNative(Native Method)
08-18 22:35:01.867: E/WindowManager(382):   at java.lang.reflect.Method.invoke(Method.java:521)
08-18 22:35:01.867: E/WindowManager(382):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-18 22:35:01.867: E/WindowManager(382):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-18 22:35:01.867: E/WindowManager(382):   at dalvik.system.NativeStart.main(Native Method)
4

3 回答 3

2

您正在更新后台线程中发生的 doInBackground 函数中的视图。视图应始终在 UI 线程中更新。为了解决这个问题,您可以从 doInBackground 函数中返回 JSONObject 并在 onPostExecute 方法中进行处理。

将 try 块userFunction.loginUser(email, password);移到 onPostExecute 之后。

protected String doInBackground(String... params) {
    String email = inputEmail.getText().toString();
    String password = inputPassword.getText().toString();
    UserFunctions userFunction = new UserFunctions();
    JSONObject json = userFunction.loginUser(email, password);

    return json;
}

protected void onPostExecute(JSONObject json) {

    // check for login response
    try {
        if (json.getString(KEY_SUCCESS) != null) {
            loginErrorMsg.setText("");
            String res = json.getString(KEY_SUCCESS);
            if (Integer.parseInt(res) == 1) {
                // user successfully logged in
                // Store user details in SQLite Database
                DatabaseHandler db = new DatabaseHandler(getApplicationContext());
                JSONObject json_user = json.getJSONObject("user");

                // Clear all previous data in database
                userFunction.logoutUser(getApplicationContext());
                db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));

                // Launch HomePage Screen
                Intent homepage = new Intent(getApplicationContext(), HomepageActivity.class);

                // Close all views before launching HomePage
                homepage.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(homepage);

                // Close Login Screen
                finish();
            } else {
                // Error in login
                loginErrorMsg.setText("Incorrect username/password");
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}
于 2012-08-18T14:47:22.620 回答
1

您只能从 UI 线程更新视图。因此,将更新视图的代码移动到onPostExecute.

另外,考虑阅读堆栈跟踪。您的错误是不言自明的。

于 2012-08-18T14:46:57.893 回答
0

您不能更改方法View内部的属性doInBackground(),这意味着您不能调用setText方法来更新TextView.

您可以通过将代码移动到onPostExecute方法或对方法中的每个方法执行类似操作来Views解决您的问题doInBackground()

loginErrorMsg.post(new Runnable() {
        public void run() {
            loginErrorMsg.setText("");
        }
    });

让我知道它是否对你有用。

于 2012-08-18T14:55:08.170 回答