【问题标题】:Application crashes when i try to restore the theme last set by user?当我尝试恢复用户上次设置的主题时应用程序崩溃?
【发布时间】:2014-03-19 12:22:22
【问题描述】:

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

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

【问题讨论】:

  • 相关:您总是将0 保存到mytheme 首选项,而不是用户选择的主题。
  • 是的,这是一个错误,谢谢。但是,为什么我的应用程序在设置为零时会崩溃,它应该使我的主题变成橙色而不是崩溃。
  • 啊,我现在在您的其他文件中看到了定义。无论如何,提供更多代码。 preferences 在哪里实例化?最早可以在onCreate() 中完成。我也看不到你从哪里打电话给onActivityCreateSetTheme。我还认为,一旦它不崩溃,你应该得到一个无限重启循环。
  • 是的,你是对的,我编辑了我的代码,它的工作但进入了无限循环。为什么会这样。
  • @A--C 是在正确的轨道上....不过,如果您只是显示实际失败的代码,那么提供帮助会容易得多。错误在 MainActivity 的构造函数中...

标签: android


【解决方案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。由于缺少代码,如果您没有适当的检查,您可能会陷入无限的 Activity 启动循环。因此,onActivityCreateSetTheme() 是更好的选择。主题也应设置在setContentView() 之前,因此上面已相应更改。

【讨论】:

  • 谢谢,它现在没有崩溃,但主题除了橙色之外没有任何其他值。如果我发布我的完整代码,你能帮我吗,因为我找不到任何问题。
  • @user3404195 这取决于您将主题保存的位置。真的不是自己能想出来的吗?我确实回答了你关于它为什么会崩溃的问题,为什么不接受这个答案并提出另一个问题让新鲜的眼睛看看?此外,如果您根本没有更改我的代码并且它始终是橙色的,那么您在某个时候正确保存了一些内容,因为默认值应该是蓝色
  • @user3404195 实际上你可能不需要提出一个新问题appliedtheme 它的值永远不会改变。我将编辑我的答案,因为它应该是一个简单的修复。
  • 那么我应该把它作为一个新问题发布吗?
  • 我认为 editor.putInt("mytheme", appliedtheme);正在设置应用主题的值。
猜你喜欢
  • 1970-01-01
  • 2017-05-22
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
相关资源
最近更新 更多