当我尝试恢复用户最后设置的主题时应用程序崩溃?

时间:2014-03-19 02:29:47

标签: android

这是我的代码,用户设置主题:

case R.id.darkorangetheme:
          ThemeChanger.onActivityCreateSetTheme(this, ThemeChanger.THEME_DARKORANGE);
          editor.putInt("mytheme", appliedtheme);
          editor.commit();
          return true;
      case R.id.bluetheme:
          ThemeChanger.onActivityCreateSetTheme(this, ThemeChanger.THEME_BLUE);
          editor.putInt("mytheme", appliedtheme);
          editor.commit();
          return true;
      case R.id.greentheme:
          ThemeChanger.onActivityCreateSetTheme(this, ThemeChanger.THEME_GREEN);
          editor.putInt("mytheme", appliedtheme);
          editor.commit();
          return true;
        default: return super.onOptionsItemSelected(item);

这是我的主题转换器类的代码:

package com.example.calculator;

import android.support.v7.app.ActionBarActivity;

公共类ThemeChanger {     private static int sTh​​eme;

public final static int THEME_DARKORANGE = 0;
public final static int THEME_GREEN = 1;
public final static int THEME_BLUE = 2;
public final static int THEME_LIGHT = 3;


public static void onActivityCreateSetTheme(ActionBarActivity activity, int theme)
{
    switch (sTheme)
    {
    default:
    case THEME_DARKORANGE:
        activity.setTheme(R.style.Theme_Darkorange);
        break;
    case THEME_GREEN:
        activity.setTheme(R.style.Theme_Green);
        break;
    case THEME_BLUE:
        activity.setTheme(R.style.Theme_Blue);
        break;
    case THEME_LIGHT:
        activity.setTheme(R.style.Theme_AppCompat_Light);
    }
}

}

现在我的onCreate方法:

public class MainActivity extends ActionBarActivity 
{

private TextView inputText,resultText,memoryStatText;
public static int button1,buttoncos,buttonmadd;
double firstNumber=0,secondNumber=0,result=0;
int firstOperand=0,TotalOperator=0;
Stack<String> mInputStack;
Stack<String> mOperationStack;
boolean resetInput = false;
boolean hasFinalResult = false;
int appliedtheme;

String mDecimalSeparator;
double memoryValue = Double.NaN;

SharedPreferences preferences = null;
SharedPreferences.Editor editor = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    preferences = PreferenceManager.getDefaultSharedPreferences(this);      
    int defaultValue = R.drawable.blue;
    int themedefault = ThemeChanger.THEME_BLUE;
    appliedtheme = preferences.getInt("mytheme", themedefault);
    ThemeChanger.onActivityCreateSetTheme(this,appliedtheme);
    setContentView(R.layout.main);


    button1 = preferences.getInt("DigitButtonStyle",defaultValue);
    buttonmadd = preferences.getInt("MemoryButtonStyle",defaultValue);
    buttoncos = preferences.getInt("FunctionButtonStyle",defaultValue);

现在我的问题是为什么我的应用程序崩溃了?

这是我的logcat

03-19 08:02:05.298: E/AndroidRuntime(3217): FATAL EXCEPTION: main
03-19 08:02:05.298: E/AndroidRuntime(3217): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.calculator/com.example.calculator.MainActivity}: java.lang.NullPointerException
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread.access$600(ActivityThread.java:162)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.os.Handler.dispatchMessage(Handler.java:107)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.os.Looper.loop(Looper.java:194)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread.main(ActivityThread.java:5371)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at java.lang.reflect.Method.invokeNative(Native Method)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at java.lang.reflect.Method.invoke(Method.java:525)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at dalvik.system.NativeStart.main(Native Method)
03-19 08:02:05.298: E/AndroidRuntime(3217): Caused by: java.lang.NullPointerException
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:161)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at com.example.calculator.MainActivity.<init>(MainActivity.java:38)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at java.lang.Class.newInstanceImpl(Native Method)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at java.lang.Class.newInstance(Class.java:1319)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
03-19 08:02:05.298: E/AndroidRuntime(3217):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2260)
03-19 08:02:05.298: E/AndroidRuntime(3217):     ... 11 more

1 个答案:

答案 0 :(得分:1)

以下是我根据您问题中的信息更改代码的方法。

我也会在主题编号中接受onActivityCreateSetTheme接受:

public static void onActivityCreateSetTheme(Activity activity, int theme)
{
    switch (theme)
    {
    default:
    case THEME_DARKORANGE:
        activity.setTheme(R.style.Theme_Darkorange);
        break;
    case THEME_GREEN:
        activity.setTheme(R.style.Theme_Green);
        break;
    case THEME_BLUE:
        activity.setTheme(R.style.Theme_Blue);
        break;
    case THEME_LIGHT:
        activity.setTheme(R.style.Theme_AppCompat_Light);
    }
}

我会更改preferences以及需要Context的所有其他变量,以便他们在onCreate()而非课外获得参考。简单地实例化Activity时,它远远不是一个完整的Activity。因此,onCreate()确保我们处理完整的Activity实例,避免“神秘”的NPE。

我也会改变onCreate()

SharedPreferences preferences;

public void onCreate(Bundle savedInstanceState){
  preferences = //get preferences however you need to.
  int themedefault = ThemeChanger.THEME_BLUE;
  appliedtheme = preferences.getInt("mytheme", themedefault);
  ThemeChanger.onActivityCreateSetTheme(this, appliedtheme);

  setContentView (R.layout.main);
}

changeToTheme() 始终重新启动活动。由于缺少代码,如果您没有检查,则可能会进入无限的Activity start循环。因此,onActivityCreateSetTheme()是更好的选择。主题也应该在setContentView()之前设置,以便相应地在上面进行更改。