0

我在这里学习教程:http ://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/ 我有所有相同的编码和一切,但是当我去运行应用程序,我注意到我收到了 ANR 错误。以下是我得到的主要 LogCat 错误(您也可以在评论部分看到这一点,如 Christopher Ashmore @ http://www.androidhive.info/2011/10/android-login-and-registration-screen-design/

08-31 17:29:39.837: E/Buffer Error(8168): Error converting result java.lang.NullPointerException
08-31 17:29:39.847: E/JSON Parser(8168): Error parsing data org.json.JSONException: End of input at character 0 of 
08-31 17:29:39.857: E/AndroidRuntime(8168): FATAL EXCEPTION: main
08-31 17:29:39.857: E/AndroidRuntime(8168): java.lang.NullPointerException
08-31 17:29:39.857: E/AndroidRuntime(8168):     at com.example.dashboardactivity.LoginActivity$1.onClick(LoginActivity.java:61)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.view.View.performClick(View.java:2532)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.view.View$PerformClick.run(View.java:9308)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.os.Handler.handleCallback(Handler.java:587)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.os.Looper.loop(Looper.java:150)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at android.app.ActivityThread.main(ActivityThread.java:4333)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at java.lang.reflect.Method.invokeNative(Native Method)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at java.lang.reflect.Method.invoke(Method.java:507)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-31 17:29:39.857: E/AndroidRuntime(8168):     at dalvik.system.NativeStart.main(Native Method)

08-31 17:37:47.953: E/ActivityManager(1472): ANR in com.example.dashboardactivity (com.example.dashboardactivity/.RegisterActivity),  time=1069291870
08-31 17:37:47.953: E/ActivityManager(1472): Reason: keyDispatchingTimedOut
08-31 17:37:47.953: E/ActivityManager(1472): Load: 5.64 / 5.27 / 5.15
08-31 17:37:47.953: E/ActivityManager(1472): CPU usage from 18994ms to 3621ms ago:
08-31 17:37:47.953: E/ActivityManager(1472):   1.6% 1472/system_server: 0.7% user + 0.8% kernel / faults: 1 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0.8% 1369/akmd: 0% user + 0.7% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.6% 10852/com.android.systemui: 0.5% user + 0.1% kernel / faults: 12 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0.5% 1635/com.android.phone: 0.4% user + 0.1% kernel / faults: 14 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0.2% 6775/logcat: 0.1% user + 0.1% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.2% 25987/com.facebook.katana: 0.2% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.1% 27858/com.htc.android.mail: 0.1% user + 0% kernel / faults: 16 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0.1% 5/events/0: 0% user + 0.1% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.1% 3/ksoftirqd/0: 0% user + 0.1% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.1% 1358/rild: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.1% 1655/com.google.process.gapps: 0.1% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 6692/adbd: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 1354/servicemanager: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 1446/logcat2: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 4489/com.htc.android.omadm.service: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 6143/com.google.android.apps.maps:NetworkLocationService: 0% user + 0% kernel / faults: 9 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0% 6195/com.google.process.location: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0% 7638/com.htc.bg: 0% user + 0% kernel / faults: 4 minor
08-31 17:37:47.953: E/ActivityManager(1472):   0% 8249/com.example.dashboardactivity: 0% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472): 5% TOTAL: 2.4% user + 2.4% kernel + 0.1% iowait
08-31 17:37:47.953: E/ActivityManager(1472): CPU usage from 635ms to 1158ms later:
08-31 17:37:47.953: E/ActivityManager(1472):   7.4% 1472/system_server: 3.7% user + 3.7% kernel
08-31 17:37:47.953: E/ActivityManager(1472):     7.4% 1562/InputDispatcher: 1.8% user + 5.5% kernel
08-31 17:37:47.953: E/ActivityManager(1472):     1.8% 1716/Binder Thread #: 1.8% user + 0% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.9% 267/kondemand/0: 0% user + 0.9% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   56% 528/kswapd0: 0% user + 1.8% kernel + 54% iowait
08-31 17:37:47.953: E/ActivityManager(1472):   0.9% 684/usb_mass_storag: 0% user + 0.9% kernel
08-31 17:37:47.953: E/ActivityManager(1472):   0.9% 1369/akmd: 0% user + 0.9% kernel
08-31 17:37:47.953: E/ActivityManager(1472):     0.9% 8258/akmd: 0% user + 0.9% kernel
08-31 17:37:47.953: E/ActivityManager(1472): 55% TOTAL: 1.9% user + 7.6% kernel + 46% iowait
08-31 17:38:02.117: E/InputDispatcher(1472): channel '40a8ab28 com.example.dashboardactivity/com.example.dashboardactivity.RegisterActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
08-31 17:38:02.117: E/InputDispatcher(1472): channel '40a8ab28 com.example.dashboardactivity/com.example.dashboardactivity.RegisterActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
08-31 17:38:02.137: E/ActivityManager(1472): fail to set top app changed!

查了之后,我注意到 developer.android.com 说我应该创建一个 AsyncTask 类来处理这个问题。有人可以看看androidhive网站上的编码(因为我的也是一样)并告诉我我会在哪里创建这个类?我以前从未使用过 AsyncTask,那么我应该将它放在编码中的什么位置以及如何构建它?提前致谢!

这是RegisterActivity.java:

package com.example.dashboardactivity;

import org.json.JSONException;
import org.json.JSONObject;

import libary.DatabaseHandler;
import libary.UserFunctions;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class RegisterActivity extends Activity {
public final String TAG = "LoginActivity";
Button btnRegister;
Button btnLinkToLogin;
EditText inputFullName;
EditText inputEmail;
EditText inputPassword;
TextView registerErrorMsg;

// JSON Response node names
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";

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

// Importing all assets like buttons, text fields
inputFullName = (EditText) findViewById(R.id.registerName);
inputEmail = (EditText) findViewById(R.id.registerEmail);
inputPassword = (EditText) findViewById(R.id.registerPassword);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
registerErrorMsg = (TextView) findViewById(R.id.register_error);

// Register Button Click event
Log.i(TAG, "RegisterActivity Register button Click Event" );
btnRegister.setOnClickListener(new View.OnClickListener() {         
    public void onClick(View view) {
        String name = inputFullName.getText().toString();
        String email = inputEmail.getText().toString();
        String password = inputPassword.getText().toString();
        UserFunctions userFunction = new UserFunctions();
        JSONObject json = userFunction.registerUser(name, email, password);

        // check for login response
        Log.i(TAG, "RegisterActivity check for login response" );
        try {
            if (json.getString(KEY_SUCCESS) != null) {
                registerErrorMsg.setText("");
                String res = json.getString(KEY_SUCCESS); 
                if(Integer.parseInt(res) == 1){
                    // user successfully registred
                    // 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 Dashboard Screen
                    Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
                    // Close all views before launching Dashboard
                    dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(dashboard);
                    // Close Registration Screen
                    finish();
                }else{
                    // Error in registration
                    registerErrorMsg.setText("Error occured in registration");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
});

// Link to Login Screen
Log.i(TAG, "RegisterActivity Link to Login Screen" );
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {

    public void onClick(View view) {
        Intent i = new Intent(getApplicationContext(),
                LoginActivity.class);
        startActivity(i);
        // Close Registration View
        finish();
    }
});
}
}
4

1 回答 1

0

你在网上有很多使用的例子AsyncTask,例如:AsyncTask 参考文档Stackoverflow 问题

关于在哪里,我建议在注册的监听器AsyncTask的方法中创建并执行. 您可以在任务的方法中运行,然后在方法中检查登录响应。例如:onClickbtnLoginuserFunction.loginUserdoInBackgroundonPostExecute

// Login button Click Event
btnLogin.setOnClickListener(new View.OnClickListener() {
    public void onClick(View view) {
        new AsyncTask<String, Void, JSONObject>(){
            @Override
            protected JSONObject doInBackground(String... args) { //This is run on a background thread
                String email = args[0];
                String password = args[1];
                UserFunctions userFunction = new UserFunctions();
                JSONObject json = userFunction.loginUser(email, password);
                return json;
            }

            @Override
            protected void onPostExecute(JSONObject json) { //This is run on the UI thread
                if(json != null){
                    //... update the user interface ...
                }else{
                    Log.e("LoginTask", "No login response was received");
                }
                super.onPostExecute(json);
            }

        }.execute(inputEmail.getText().toString(), inputPassword.getText().toString());
    }
});

根据经验,所有输入/输出操作和繁重的任务(网络通信、解析等)都应该在后台线程上运行(同时向用户显示进度对话框)。获得结果后,可以使用 UI 线程更新屏幕。

但是,使用时AsyncTasks还有其他问题,如本讨论中关于持有对 Context 的引用所解释的那样。

于 2013-09-01T01:32:59.590 回答