我登录android的异步任务

时间:2012-08-18 14:42:02

标签: android multithreading android-asynctask

我将登录代码实现到异步任务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;
    }

这是我的logcat:

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)

3 个答案:

答案 0 :(得分:2)

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

userFunction.loginUser(email, password);之后的try块移动到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();
    }
}

答案 1 :(得分:1)

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

另外,请考虑读取堆栈跟踪。你的错误是自我解释的。

答案 2 :(得分:0)

您无法在View方法中更改doInBackground()的属性,这意味着您无法调用setText方法来更新TextView

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

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

让我知道它是否适合你。