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

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;


导入android.support.v7.app.ActionBarActivity;

公共类ThemeChanger
{
    私有静态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);


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

这是我的日志

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

最佳答案

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

我也会让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启动循环。因此,onActivityCreateSetTheme()是更好的选择。还应在setContentView()之前设置主题,以便在上方进行相应的更改。

09-10 07:06
查看更多