0

I am following the tutorial here:http://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/ I have all the same coding and everything but when I go to run the app, I notice that I get an ANR error. Here are the major LogCat errors I get (You can also see this in the comments section as 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)

And

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!

After looking this up I noticed the developer.android.com said that I should create a AsyncTask class to deal with this problem. Can someone please take a look at the coding on the androidhive site (since mine is the same) and tell me where I would create this class? I've never worked with AsyncTask before so where should I put it in the coding and how do I construct it? Thanks in advance!

Here is the 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();
    }
});
}
}
user2712795
  • 65
  • 1
  • 3
  • 11

1 Answers1

0

You have plenty of examples of the usage of AsyncTask on the Internet, for example: AsyncTask reference doc, Stackoverflow question.

Regarding where, I'd suggest to create and execute the AsyncTask in the onClick method of the registered listener of btnLogin. You could run userFunction.loginUser in the doInBackground method of the task and then check the login response in the onPostExecute method. For example:

// 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());
    }
});

As a rule of thumb, all input / output operations and heavy tasks (network communications, parsing, etc) should be run on a background thread (while showing a progress dialog to the user). Once the results are obtained, the screen can be updated using the UI thread.

However, when using AsyncTasks there are additional concerns, as explained in this discussion about holding references to the Context.

Community
  • 1
  • 1
rbarriuso
  • 787
  • 8
  • 30
  • Oh ok thank you and also the thing that is bugging me is if that recommended coding is for the ENTIRE onClick method or just for a part of it. If you can help clear that up that would also be really reassuring. I'll show my entire RegisterActivity.java (as an example that I will just copy over to my LoginActivity.java) because there is a part where it checks for login response and I am not sure if that should be kept or not (or if it can be kept on)) :) – user2712795 Sep 02 '13 at 03:31
  • The example code above was meant to be only part. I guess in the `onClick` method before launching the async task you should show a progress dialog (see [DialogFragment](http://developer.android.com/reference/android/app/DialogFragment.html) and [ProgressDialog](http://developer.android.com/reference/android/app/ProgressDialog.html)). – rbarriuso Sep 02 '13 at 17:08
  • The login response should be checked where I wrote the comment "... update the user interface ...". There you can check the received JSON object and if the credentials are correct, start the next activity. – rbarriuso Sep 02 '13 at 17:10