Reputation: 23
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
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