0

I was wondering if anyone could help. Every time I run my android app project it crashes. I've narrowed it down to a single function but I have no idea why it's crashing!

ERROR:

05-07 17:38:22.059 3952-3986/com.tfs.appname W/System: ClassLoader referenced         unknown path: /data/data/com.tfs.appname/lib
05-07 17:38:22.122 3952-3952/com.tfs.appname D/AndroidRuntime: Shutting down     VM
05-07 17:38:22.123 3952-3952/com.tfs.appname E/AndroidRuntime: FATAL EXCEPTION: main
                                                          Process: com.tfs.appname, PID: 3952
                                                          java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tfs.appname/com.tfs.appname.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                              at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
                                                              at android.app.ActivityThread.-wrap15(ActivityThread.java)
                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
                                                              at android.os.Handler.dispatchMessage(Handler.java:102)
                                                              at android.os.Looper.loop(Looper.java:148)
                                                              at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                           Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                                                              at android.content.ContextWrapper.getPackageName(ContextWrapper.java:133)
                                                              at android.app.Activity.getLocalClassName(Activity.java:5205)
                                                              at android.app.Activity.getPreferences(Activity.java:5239)
                                                              at com.tfs.appname.helpers.isLoggedIn(helpers.java:99)
                                                              at com.tfs.appname.MainActivity$override.onCreate(MainActivity.java:35)
                                                              at com.tfs.appname.MainActivity$override.access$dispatch(MainActivity.java)
                                                              at com.tfs.appname.MainActivity.onCreate(MainActivity.java:0)
                                                              at android.app.Activity.performCreate(Activity.java:6237)
                                                              at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                              at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 
                                                              at android.app.ActivityThread.-wrap15(ActivityThread.java) 
                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 
                                                              at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                              at android.os.Looper.loop(Looper.java:148) 
                                                              at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                              at java.lang.reflect.Method.invoke(Native Method) 
                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
05-07 17:38:30.716 3952-3952/com.tfs.appname I/Process: Sending signal. PID: 3952 SIG: 9

MainActivity.java:

package com.tfs.appname;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

public class MainActivity extends AppCompatActivity {

/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient client;

Button LoginButton, RegisterButton;

@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final helpers helpers = new helpers();
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();

    Button LoginButton = (Button) findViewById(R.id.button_login);
    Button RegisterButton = (Button) findViewById(R.id.button_register);

    if (helpers.isLoggedIn()) {
        startActivity(new Intent(MainActivity.this, Dashboard.class));
    }

    RegisterButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(MainActivity.this, Register.class));
        }
    });

    LoginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(MainActivity.this, Login.class));
        }
    });
}

@Override
public void onStart() {
    super.onStart();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app URL is correct.
            Uri.parse("android-app://com.tfs.appname/http/host/path")
    );
    AppIndex.AppIndexApi.start(client, viewAction);
}

@Override
public void onStop() {
    super.onStop();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app URL is correct.
            Uri.parse("android-app://com.tfs.appname/http/host/path")
    );
    AppIndex.AppIndexApi.end(client, viewAction);
    client.disconnect();
}
}

Login.Java:

package com.tfs.appname;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
import com.kosalgeek.asynctask.AsyncResponse;
import com.kosalgeek.asynctask.PostResponseAsyncTask;

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

import java.util.HashMap;

import static android.app.PendingIntent.getActivity;

public class Login extends AppCompatActivity implements AsyncResponse {

    Button LoginSubmitButton, LoginRegisterButton;
    EditText LoginEmail, LoginPassword;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        final helpers helpers = new helpers();

        final EditText LoginEmail = (EditText) findViewById(R.id.login_email);
        final EditText LoginPassword = (EditText) findViewById(R.id.login_password);
        Button LoginSubmitButton = (Button) findViewById(R.id.login_submit);
        Button LoginRegisterButton = (Button) findViewById(R.id.login_register_button);

        LoginRegisterButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(Login.this, Register.class));
            }
        });

        assert LoginSubmitButton != null;
        LoginSubmitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final Context context = getApplicationContext();
                int duration = Toast.LENGTH_SHORT;

                if (helpers.isEmpty(LoginEmail)) {
                    CharSequence text = "Please enter your email address.";

                    Toast toast = Toast.makeText(context, text, duration);
                    toast.show();
                } else {
                    if (helpers.isEmpty(LoginPassword)) {
                        CharSequence text = "Please enter your password.";

                        Toast toast = Toast.makeText(context, text, duration);
                        toast.show();
                    } else {
                        if (helpers.isValidEmail(LoginEmail))
                            if (helpers.isValidPassword(LoginPassword)) {
                                HashMap<String, String> postData = new HashMap<String, String>();
                                postData.put("emailaddress", LoginEmail.getText().toString());
                                postData.put("password", LoginPassword.getText().toString());
                                final PostResponseAsyncTask loginTask = new PostResponseAsyncTask(Login.this, postData, new AsyncResponse() {
                                    @Override
                                    public void processFinish(String s) {
                                        JSONObject results = null;
                                        String result_status = null;
                                        String MID = null;
                                        String MT = null;

                                        try {
                                            results = new JSONObject(s);
                                            result_status = results.getString("STATUS");
                                            MID = results.getString("MID");
                                            MT = results.getString("MT");
                                        } catch (JSONException e) {
                                            e.printStackTrace();
                                        }

                                        if (result_status.equalsIgnoreCase("success")) {
                                            SharedPreferences sharedPref = Login.this.getPreferences(Context.MODE_PRIVATE);
                                            SharedPreferences.Editor editor = sharedPref.edit();
                                            editor.putString("MID", MID);
                                            editor.putString("MTOK", MT);
                                            editor.commit();
                                            startActivity(new Intent(Login.this, Dashboard.class));
                                        } else {
                                            Context context = getApplicationContext();
                                            int duration = Toast.LENGTH_SHORT;
                                            CharSequence text = result_status;
                                            Toast toast = Toast.makeText(context, text, duration);
                                            toast.show();
                                        }
                                    }
                                });
                                loginTask.execute("http://192.168.1.64/app/test.php");
                            } else {
                                CharSequence text = "Invalid password.";

                                Toast toast = Toast.makeText(context, text, duration);
                                toast.show();
                            }
                        else {
                            CharSequence text = "Invalid email address.";

                            Toast toast = Toast.makeText(context, text, duration);
                            toast.show();
                        }
                    }
                }
            }
        });
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    @Override
    public void processFinish(String s) {

    }

    @Override
    public void onStart() {
        super.onStart();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client.connect();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Login Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse("android-app://com.tfs.appname/http/host/path")
        );
        AppIndex.AppIndexApi.start(client, viewAction);
    }

    @Override
    public void onStop() {
        super.onStop();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "Login Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse("android-app://com.tfs.appname/http/host/path")
        );
        AppIndex.AppIndexApi.end(client, viewAction);
        client.disconnect();
    }
}

Helpers.Java:

package com.tfs.appname;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Patterns;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
import com.kosalgeek.asynctask.AsyncResponse;
import com.kosalgeek.asynctask.PostResponseAsyncTask;

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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Offic on 03/05/2016.
 */
public class helpers extends AppCompatActivity implements AsyncResponse {

    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    boolean isEmpty(EditText etText) {
        return etText.getText().toString().trim().length() <= 0;
    }

    public boolean isValidEmail(EditText email) {
        if (TextUtils.isEmpty(email.getText())) {
            return false;
        } else {
            return Patterns.EMAIL_ADDRESS.matcher(email.getText()).matches();
        }
    }

    public boolean isValidPassword(EditText password) {
        String regExpn = "^[a-z0-9_]{6,24}$";
        CharSequence inputStr = password.getText();
        Pattern pattern = Pattern.compile(regExpn, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(inputStr);

        if (matcher.matches()) {
            return true;
        } else {
            return false;
        }
    }

    private boolean verifySession(String MID, String MTOK) {
        HashMap<String, String> postData = new HashMap<String, String>();
        postData.put("MID", MID);
        postData.put("MTOK", MTOK);
        final Boolean[] Ret = {false};
        final PostResponseAsyncTask loginTask = new PostResponseAsyncTask(this, postData, new AsyncResponse() {
            @Override
            public void processFinish(String s) {
                JSONObject results = null;
                String result_status = null;

                try {
                    results = new JSONObject(s);
                    result_status = results.getString("STATUS");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                if (result_status == "success") {
                    Ret[0] = true;
                } else {
                    Ret[0] = false;
                }
            }
        });
        loginTask.execute("http://192.168.1.64/app/test.php");

        return Ret[0];
    }

    public boolean isLoggedIn() {
        SharedPreferences sharedPref = this.getPreferences(Context.MODE_PRIVATE);
        String MID = sharedPref.getString("MID", null);
        String MT = sharedPref.getString("MTOK", null);

        if (MID == null || MT == null) {
            return false;
        } else {
            return verifySession(MID, MT);
        }
    }

    @Override
    public void processFinish(String s) {

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    @Override
    public void onStart() {
        super.onStart();
        client.connect();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "helpers Page", // TODO: Define a title for the content shown.
                Uri.parse("http://host/path"),
                Uri.parse("android-app://com.tfs.appname/http/host/path")
        );
        AppIndex.AppIndexApi.start(client, viewAction);
    }

    @Override
    public void onStop() {
        super.onStop();
        Action viewAction = Action.newAction(
                Action.TYPE_VIEW, // TODO: choose an action type.
                "helpers Page", // TODO: Define a title for the content shown.
                // TODO: If you have web page content that matches this app activity's content,
                // make sure this auto-generated web page URL is correct.
                // Otherwise, set the URL to null.
                Uri.parse("http://host/path"),
                // TODO: Make sure this auto-generated app URL is correct.
                Uri.parse("android-app://com.tfs.appname/http/host/path")
        );
        AppIndex.AppIndexApi.end(client, viewAction);
        client.disconnect();
    }
}

Any help would be greatly appreciated! I'm very, very new to this language so I'm still getting to grips on how it all works.

Many thanks

James P
  • 101
  • 10

1 Answers1

3

There is a major flaw in your design. The error is obvious. In this line

final helpers helpers = new helpers();

you are trying to create an object of an activity which is a very very bad practice. You cannot simply create an object of an activity like this. All Activities in Android must go through the Activity lifecycle so that they have a valid context attached to them. In this case a valid context is not attached to the helper instance. So as a result the line

SharedPreferences sharedPref = this.getPreferences(Context.MODE_PRIVATE);

causes a null pointer as 'this' is null. (Why? Because this refers to the context which has not yet been created as the activity is not started using startActivity(intent))

Another thing though this is not an error, you must use activity names starting with an upper case letter. It is the convention followed and will make your code more readable. Your code is pretty confusing due to the weird use of upper and lower case names. You declare your class with a lower case letter while at some places the variables are upper case. which causes confusion. The rule is that classes, interfaces, etc should start with upper case letters and variables as lower case.

So in this case what do you do?

You never start your Helper activity and I think you do not need to show it to the user. That is it needs to do some work without user interaction. You should make it a service. And then start it using startService(intent).Or you may also create it as a Java class, depends on your use case.

Edit: By the way I answered another similar question having the same problem but involving services later today.

Community
  • 1
  • 1
varunkr
  • 5,364
  • 11
  • 50
  • 99
  • 1
    Thank you so much for explaining it to me. Now I have the opportunity using knowledge to find the answer. I was worried someone would just post the answer and I would be stuck wondering how and why it fixed it and what went wrong. Based on your answer I'm going to start the project again and just using snippets from this one after modifying them to adhere to your post! Thanks again @varunkr – James P May 08 '16 at 10:51
  • @JamesP glad to help !! – varunkr May 08 '16 at 11:42