jila
jila

Reputation: 23

Android and SharedPreferences on an independent class

I'm starting to programming for Android and I hadn't had any serious problems until I tried to separate the reading/writing code of SharedPreferences (on each activity) to a separate class, say ConfigManager.

Here is my ConfigManager class:

package com.application.testing;

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

public class ConfigManager extends Activity {

    public boolean boolPref;
    public String stringPref;

    private SharedPreferences prefs;

    public ConfigManager() {
        prefs = getSharedPreferences(
                getResources().getString(R.string.preferences),
                Context.MODE_PRIVATE);
        loadCfg();
    }

    public void saveCfg() {

        SharedPreferences.Editor editor = prefs.edit();

        editor.putBoolean("boolPreference", boolPref);
        editor.putString("stringPreference", stringPref);

        editor.commit();

    }

    public void loadCfg() {

        this.boolPref = prefs.getBoolean("boolPreference", false);
        this.stringPref = prefs.getString("stringPreference", "");

    }

}

Now, when I try to instantiate this class to read/write preferences, I receive error and the application exits.

Let's say a splashscreen, if the user decides not to show, I keep it in a preference, and on the start of the application I read if it's true or false, to show the splashscreen or move to the next activity.

This would be the splashscreen class code:

package com.application.testing;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class SplashScreen extends Activity {

    public ConfigManager cfg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        cfg = new ConfigManager();

        if (!(cfg.boolPref)) {
            Intent i = new Intent("com.application.testing.NEXTACTIVITY");
            startActivity(i);
        } else {

            setContentView(R.layout.splash);

            Thread timer = new Thread() {
                public void run() {

                    try {
                        sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        Intent i = new Intent("com.application.testing.NEXTACTIVITY");
                        startActivity(i);
                    }

                }
            };

            timer.start();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        cfg.saveCfg(); // not neccesary, no preference changes during splashscreen execution
        finish();
    }

}

Finally, this is Logcat output:

12-21 23:46:48.294: D/AndroidRuntime(1381): Shutting down VM
12-21 23:46:48.344: W/dalvikvm(1381): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-21 23:46:48.375: E/AndroidRuntime(1381): FATAL EXCEPTION: main
12-21 23:46:48.375: E/AndroidRuntime(1381): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.application.testing/com.application.testing.SplashScreen}: java.lang.NullPointerException
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.os.Looper.loop(Looper.java:123)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread.main(ActivityThread.java:4627)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at java.lang.reflect.Method.invokeNative(Native Method)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at java.lang.reflect.Method.invoke(Method.java:521)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at dalvik.system.NativeStart.main(Native Method)
12-21 23:46:48.375: E/AndroidRuntime(1381): Caused by: java.lang.NullPointerException
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at com.application.testing.ConfigManager.<init>(ConfigManager.java:22)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at com.application.testing.SplashScreen.onCreate(SplashScreen.java:22)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-21 23:46:48.375: E/AndroidRuntime(1381):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
12-21 23:46:48.375: E/AndroidRuntime(1381):     ... 11 more

Does anyone know where my error is?

A lot of thanks in advance, because I'm going crazy :)

Upvotes: 0

Views: 1523

Answers (1)

chiuki
chiuki

Reputation: 14700

ConfigManager should not extend Activity. Instead, change its constructor to take a Context:

public ConfigManager(Context context) {
    prefs = context.getSharedPreferences(
            context.getResources().getString(R.string.preferences),
            Context.MODE_PRIVATE);
    loadCfg();
}

You can then pass the Activity to ConfigManager in the onCreate of SplashScreen:

cfg = new ConfigManager(this);

Upvotes: 3

Related Questions