• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Problems Making Plugin - Null Context

lblast

Lurker
Hi there,
I was trying to develop a simple plugin for a Unity app to get shared preferences (they are stored in a slightly different location than Unity stores them). The problem I'm encountering is that the context is null.

I've tried a lot of methods to get context but it always ends up with some sort of null:

AndroidJavaException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference


This is the plugin I've written currently. One thing I noticed (when I put Log.e in) is that it doesn't seem to call onCreate. Is that a problem?

Java:
package com.test;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.content.SharedPreferences;

// This Util is used to help transition from the Android SDK to the Unity SDK
public class SharedPreferencesUtility extends Activity
{
    private Context context;
    private Activity activity;
    private static SharedPreferencesUtility instance;
    SharedPreferences sharedpreferences;

    private static final String TAG = "USERID_UTIL";
    public static final String PREFS_NAME = "user_saved_prefs";

    @Override
    public void onCreate(Bundle savedInstance) {

        super.onCreate(savedInstance);

        activity = this;

        context = this.getApplicationContext();
    }

    public SharedPreferencesUtility() {
        this.instance = this;
    }

    public static SharedPreferencesUtility instance() {
        if(instance == null) {
            instance = new SharedPreferencesUtility();
        }

        return instance;
    }

    public String getPreferenceString (String prefKey) {

        //context = getApplicationContext();
        //context = instance.getApplicationContext();
        //context = this.getApplicationContext();

        sharedpreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String userId = sharedpreferences.getString(prefKey, "");
        return userId;
    }
}


Any help solving this problem is greatly appreciated. I've done a lot of googling but I must be missing something.
 
Please post a full stack trace.

The question is, from where are you calling method getPreferenceString() ?

I suspect this is not your main Activity, or the Activity isn't being started by startActivityForResult().
You cannot simply extend Activity and expect it to be initialised with an application context.

What I can suggest you do (and this is guesswork without seeing the full stacktrace), is to pass in the application context from the calling code. So your method would be -

Code:
public String getPreferenceString (String prefKey, Context context) {
 ...
 
Please post a full stack trace.

The question is, from where are you calling method getPreferenceString() ?

I suspect this is not your main Activity, or the Activity isn't being started by startActivityForResult().
You cannot simply extend Activity and expect it to be initialised with an application context.

What I can suggest you do (and this is guesswork without seeing the full stacktrace), is to pass in the application context from the calling code. So your method would be -

Code:
public String getPreferenceString (String prefKey, Context context) {
 ...


Thanks for the reply. I ran it again and this is the stacktrace I get:
http://puu.sh/yZj0U/58b2a463a1.png

01-11 13:47:20.566: E/Unity(22773): AndroidJavaException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
01-11 13:47:20.566: E/Unity(22773): java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
01-11 13:47:20.566: E/Unity(22773): at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
01-11 13:47:20.566: E/Unity(22773): at com.blastworksinc.SwrveUserIdUtil.getPreferenceString(SwrveUserIdUtil.java:52)
01-11 13:47:20.566: E/Unity(22773): at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
01-11 13:47:20.566: E/Unity(22773): at com.unity3d.player.UnityPlayer.c(Unknown Source:0)
01-11 13:47:20.566: E/Unity(22773): at com.unity3d.player.UnityPlayer$c$1.handleMessage(Unknown Source:157)
01-11 13:47:20.566: E/Unity(22773): at android.os.Handler.dispatchMessage(Handler.java:101)
01-11 13:47:20.566: E/Unity(22773): at android.os.Looper.loop(Looper.java:164)
01-11 13:47:20.566: E/Unity(22773): at com.unity3d.player.UnityPlayer$c.run(Unknown Source:20)
01-11 13:47:20.566: E/Unity(22773): at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <filename unknown>:0
01-11 13:47:20.566: E/Unity(22773): at UnityEngine.AndroidJNISafe.CallStringMethod (IntPtr obj, IntPt


What you said seemed like a good idea (passing the context). So I modified the code:

Java:
    public String getPreferenceString (String prefKey, Context context) {
        Log.e(TAG, "SwrveUserIdUtil starting getpreference " + prefKey);

        sharedpreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String userId = sharedpreferences.getString(prefKey, "");
        return userId;
    }

I then call that code like so:

Code:
        using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
            if (activityContext == null)
            {
                Logger.Error("Could not load activity context!");
            }
        }
       
        pluginInstance = new AndroidJavaObject("com.blastworksinc.SwrveUserIdUtil");
        if (pluginInstance == null)
        {
            Logger.Error("Could not instantiate plugin class!");
        }
        else
        {
            var savedPreference = pluginInstance.Call<string>("getPreferenceString", "userId", activityContext);
        }


Running this I did not get the null exception. :) Thanks a lot!
 
Back
Top Bottom