1

私はログインアプリケーション(ここから取得)を実行しています。基本的に、オンラインデータベースに接続するnricとパスワードを使用してログインしたいのですが、非同期タスクをコードに追加した後、プログラムがクラッシュします。

public class LoginActivity extends Activity {
Button btnLogin;
Button btnLinkToRegister;
EditText inputNric;
EditText inputPassword;
TextView loginErrorMsg;

// Progress Dialog
private ProgressDialog pDialog;

// JSON Response node names
//success is the column name of the database - KEY_SUCCESS is we create the name 
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_NAME = "name";
private static String KEY_NRIC = "nric";
private static String KEY_CREATED_AT = "created_at";

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login);

    // Importing all assets like buttons, text fields
    inputNric = (EditText) findViewById(R.id.loginNric);
    inputPassword = (EditText) findViewById(R.id.loginPassword);
    btnLogin = (Button) findViewById(R.id.buttonLogin);
    btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen);
    loginErrorMsg = (TextView) findViewById(R.id.login_error);

    // login button click event
    btnLogin.setOnClickListener(new View.OnClickListener() {

        public void onClick(View arg0) {
            // starting background task to update case
            new LoginUser().execute();
        }
    });

    // Link to Register Screen
    btnLinkToRegister.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            Intent i = new Intent(getApplicationContext(),
            RegisterActivity.class);
            startActivity(i);
            finish();
        }
    });
}

/**
 * Background Async Task to  Login User
 * */
class LoginUser extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */        
    protected void onPreExecute() {
    super.onPreExecute();
    pDialog = new ProgressDialog(LoginActivity.this);
    pDialog.setMessage("Logging In ...");
    pDialog.setIndeterminate(false);
    pDialog.setCancelable(true);
    pDialog.show();
    }

    /**
    * Logging in
    * */
    protected String doInBackground(String... params) {

            String nric = inputNric.getText().toString();
            String password = inputPassword.getText().toString();
            UserFunctions userFunction = new UserFunctions();
            Log.d("Button", "Login");
            JSONObject json = userFunction.loginUser(nric, 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_NRIC), json_user.getString(KEY_CREATED_AT));                      

                        // Launch home Screen
                        Intent home = new Intent(getApplicationContext(), HomeActivity.class);

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

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

     /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once case deleted
        pDialog.dismiss();

    }
}

}

Logcat エラー:

08-15 06:20:26.254: E/AndroidRuntime(302): FATAL EXCEPTION: AsyncTask #1
08-15 06:20:26.254: E/AndroidRuntime(302): java.lang.RuntimeException: An error occured      while executing doInBackground()
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.lang.Thread.run(Thread.java:1096)
08-15 06:20:26.254: E/AndroidRuntime(302): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
08-15 06:20:26.254: E/AndroidRuntime(302):  at      android.view.ViewRoot.requestLayout(ViewRoot.java:594)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.View.requestLayout(View.java:8125)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.View.requestLayout(View.java:8125)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.View.requestLayout(View.java:8125)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.View.requestLayout(View.java:8125)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:254)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.view.View.requestLayout(View.java:8125)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.widget.TextView.checkForRelayout(TextView.java:5378)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.widget.TextView.setText(TextView.java:2688)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.widget.TextView.setText(TextView.java:2556)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.widget.TextView.setText(TextView.java:2531)
08-15 06:20:26.254: E/AndroidRuntime(302):  at com.pivestigator.LoginActivity$LoginUser.doInBackground(LoginActivity.java:107)
08-15 06:20:26.254: E/AndroidRuntime(302):  at com.pivestigator.LoginActivity$LoginUser.doInBackground(LoginActivity.java:1)
08-15 06:20:26.254: E/AndroidRuntime(302):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
08-15 06:20:26.254: E/AndroidRuntime(302):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-15 06:20:26.254: E/AndroidRuntime(302):  ... 4 more
08-15 06:20:26.344: W/ActivityManager(75):   Force finishing activity com.pivestigator/.LoginActivity
08-15 06:20:28.554: E/WindowManager(302): Activity com.pivestigator.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f33188 that was originally added here
08-15 06:20:28.554: E/WindowManager(302): android.view.WindowLeaked: Activity com.pivestigator.LoginActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f33188 that was originally added here
08-15 06:20:28.554: E/WindowManager(302):   at android.view.ViewRoot.<init>(ViewRoot.java:247)
08-15 06:20:28.554: E/WindowManager(302):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
08-15 06:20:28.554: E/WindowManager(302):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
08-15 06:20:28.554: E/WindowManager(302):   at android.view.Window$LocalWindowManager.addView(Window.java:424)
08-15 06:20:28.554: E/WindowManager(302):   at android.app.Dialog.show(Dialog.java:241)
08-15 06:20:28.554: E/WindowManager(302):   at com.pivestigator.LoginActivity$LoginUser.onPreExecute(LoginActivity.java:90)
08-15 06:20:28.554: E/WindowManager(302):   at android.os.AsyncTask.execute(AsyncTask.java:391)
08-15 06:20:28.554: E/WindowManager(302):   at com.pivestigator.LoginActivity$1.onClick(LoginActivity.java:60)
08-15 06:20:28.554: E/WindowManager(302):   at android.view.View.performClick(View.java:2408)
08-15 06:20:28.554: E/WindowManager(302):   at android.view.View$PerformClick.run(View.java:8816)
08-15 06:20:28.554: E/WindowManager(302):   at android.os.Handler.handleCallback(Handler.java:587)
08-15 06:20:28.554: E/WindowManager(302):   at android.os.Handler.dispatchMessage(Handler.java:92)
08-15 06:20:28.554: E/WindowManager(302):   at android.os.Looper.loop(Looper.java:123)
08-15 06:20:28.554: E/WindowManager(302):   at android.app.ActivityThread.main(ActivityThread.java:4627)
08-15 06:20:28.554: E/WindowManager(302):   at java.lang.reflect.Method.invokeNative(Native Method)
08-15 06:20:28.554: E/WindowManager(302):   at java.lang.reflect.Method.invoke(Method.java:521)
08-15 06:20:28.554: E/WindowManager(302):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-15 06:20:28.554: E/WindowManager(302):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-15 06:20:28.554: E/WindowManager(302):   at dalvik.system.NativeStart.main(Native Method)
4

2 に答える 2

2

エラー自体は、許可されていない他のスレッドでアクティビティのメイン UI スレッドを更新またはアクセスしようとしていることを示しています。

doInBackground()実際には、AsyncTask の(doInBAckground() はワーカー スレッドで実行されるため) メソッドからアクティビティのビューを更新しようとしています。Androidでは許可されていません。

これらの行は、

String nric = inputNric.getText().toString();
String password = inputPassword.getText().toString();

loginErrorMsg.setText("Incorrect username/password");

エラーが発生します。したがって、これらの行を AsyncTask から削除し、doInBackground()それらのコード行を AsyncTask とのonPreExecute()入れます。onPostExecute()

于 2012-08-15T06:43:19.377 に答える
0

メソッドに移動loginErrorMsg.setText("Incorrect username/password");し、代わりにスレッドAsyncTask's onProgressUpdate(..)で呼び出します。publishProgress(..)doInBackground()

もう1つの問題は(私の意見ではクラッシュの原因でした)Activity、ワーカースレッドから新しいスレッドを開始しようとしていることです。次のコードをonPostExecute(..)メソッドの直後に移動し、戻り値との引数をpDialog.dismiss()使用してログインが成功したかどうかを確認します。doInBackground()onPostExecute()

リークされたウィンドウの例外は、ProgressDialogアクティビティを終了しようとしたときに、がまだ表示されていることを意味します。

class LoginUser extends AsyncTask<Void, String, Boolean> {

    /**
     * Before starting background thread Show Progress Dialog
     * */        
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(LoginActivity.this);
        pDialog.setMessage("Logging In ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
    * Logging in
    * */
    protected Boolean doInBackground(Void... params) {

        String nric = inputNric.getText().toString();
        String password = inputPassword.getText().toString();
        UserFunctions userFunction = new UserFunctions();
        Log.d("Button", "Login");
        JSONObject json = userFunction.loginUser(nric, password);

        boolean isSuccess = false;

        // check for login response
        try {
            if (json.getString(KEY_SUCCESS) != null) {
                // Set the error TextField on the UI thread
                publishProgress("");

                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_NRIC), json_user.getString(KEY_CREATED_AT));                      


                    // We logged in successfully
                    isSuccess = true;
                }else{
                    // Error in login
                    // Set the error TextField on the UI thread
                    publishProgress("Incorrect username/password");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return isSuccess;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        loginErrorMsg.setText(values[0]);
    }

     /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(Boolean result) {
        // dismiss the dialog once case deleted
        pDialog.dismiss();

        if(result.booleanValue()){
            // Launch home Screen
                Intent home = new Intent(getApplicationContext(), HomeActivity.class);

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

                // Close Login Screen
                finish();
        }
    }
}
于 2012-08-15T06:58:25.320 に答える