EditTextPreference导致膨胀异常

7

在相关主题中寻找解决方案约1小时后,我决定公开我的问题。我的问题是:每次尝试打开PreferenceActivity时,我都会遇到InflateException。

日志

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: lineo.smarteam, PID: 5087
                  Theme: themes:{}
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{lineo.smarteam/lineo.smarteam.activity.SettingsActivity}: android.view.InflateException: Binary XML file line #5: Error inflating class lineo.smarteam.preference.MyEditTextPreference
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
                      at android.app.ActivityThread.-wrap11(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5461)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                   Caused by: android.view.InflateException: Binary XML file line #5: Error inflating class lineo.smarteam.preference.MyEditTextPreference
                      at android.preference.GenericInflater.createItem(GenericInflater.java:388)
                      at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:432)
                      at android.preference.GenericInflater.rInflate(GenericInflater.java:483)
                      at android.preference.GenericInflater.rInflate(GenericInflater.java:495)
                      at android.preference.GenericInflater.inflate(GenericInflater.java:327)
                      at android.preference.GenericInflater.inflate(GenericInflater.java:264)
                      at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:273)
                      at android.preference.PreferenceFragment.addPreferencesFromResource(PreferenceFragment.java:304)
                      at lineo.smarteam.activity.SettingsActivity$SettingsFragment.onCreate(SettingsActivity.java:57)
                      at android.app.Fragment.performCreate(Fragment.java:2198)
                      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
                      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
                      at android.app.BackStackRecord.run(BackStackRecord.java:793)
                      at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
                      at android.app.FragmentController.execPendingActions(FragmentController.java:325)
                      at android.app.Activity.performStart(Activity.java:6267)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510) 
                      at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5461) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                   Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]

我有一个偏好设置屏幕,其中包含多个EditTextPreferences,允许配置一些整数参数。

res\xml\preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory     android:title="@string/scores_category_title"
                            android:key="pref_key_scores_settings">
        <lineo.smarteam.preference.MyEditTextPreference
            android:title="@string/pref_title_win_score"
            android:inputType="numberSigned"
            android:maxLength="9"
            android:defaultValue="@integer/def_win_score"
            android:key="pref_key_win_score" >
        </lineo.smarteam.preference.MyEditTextPreference>
        (more of the same)
    </PreferenceCategory>
</PreferenceScreen>

因为我很固执,希望每次点击任何偏好设置时光标都能对齐到文本末尾,所以我创建了一个自定义的EditTextPreference。

preference\MyEditTextPreference.java

package lineo.smarteam.preference;

import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.widget.EditText;

public class MyEditTextPreference extends EditTextPreference {
    public MyEditTextPreference(Context context) {
        super(context);
    }
    public MyEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onClick() {
        super.onClick();
        EditText et = getEditText();
        et.setSelection(et.getText().length());
    }
}

如您所见,我在与此问题相关的所有主题中都提到了所有构造函数。然后我有实际的PreferenceActivity:

activity\SettingsActivity

package lineo.smarteam.activity;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.MenuItem;

import lineo.smarteam.MyApplication;
import lineo.smarteam.R;

public class SettingsActivity extends PreferenceActivity {
    static SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Context context = this;
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
    }

    public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
            setListeners();
        }

        //EDIT:
        public void setListeners(){
            setListenerA();
            //other listeners
        }

        pulic void setListenerA(){
            findPreference("KEY_PREF_WIN_SCORE").setOnPreferenceChangeListener() {
                //(...)
            }
        }
    }
}

如上所述,在省略的最后一段代码中,我调用了getActivity(),根据我所读到的资料,这可能会导致问题。但问题在于,我尝试注释掉所有对该方法的调用,问题仍然存在。因此,我得出结论,这不是问题的原因。此外,我也看到该方法可能会抛出NullPointerException异常,因此每次使用它时我都会进行检查。
我有一种感觉,解决方案就在我的眼前,只是我没有看到。在我所阅读的大多数相关主题中,情况都是这样的。
有人能帮我找到它吗?
谢谢。
编辑:
根据Vijai的建议,我重新安装了应用程序。它仍然在相同的操作中崩溃,但错误已经改变。
新日志
E/AndroidRuntime: FATAL EXCEPTION: main
Process: lineo.smarteam, PID: 19210
Theme: themes:{}
java.lang.RuntimeException: Unable to start activity ComponentInfo{lineo.smarteam/lineo.smarteam.activity.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.preference.Preference.setOnPreferenceChangeListener(android.preference.Preference$OnPreferenceChangeListener)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
    at android.app.ActivityThread.-wrap11(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5461)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

你是否启用了ProGuard?如果是这样,你可能需要在自定义的Preference上添加@Keep注解。 - CommonsWare
我不知道那是什么... - Marco Castanho
https://developer.android.com/studio/build/shrink-code.html - CommonsWare
有趣!将来可能会有用。谢谢。但是因为我不知道它,所以没有启用ProGuard。 - Marco Castanho
你尝试过清除数据或卸载/重新安装应用程序吗?即时运行可能是原因。 - Vijai
我现在已经做了,错误已经改变。我在上面添加了新的错误日志。谢谢! - Marco Castanho
2个回答

6

我找到了它。

我试图找到一个偏好设置,其ID与preferences.xml文件中的任何ID都不匹配。

这实在是一个愚蠢的错误。而且这是在我一开始没有分享的一段代码中出现的(抱歉)。

无论如何,感谢每个试图帮助我的人!


3
错误提示说你的MyEditTextPreference类中有错误。
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]

我之前也遇到过这个错误,但具体情况因人而异,你可以尝试以下几点:

  1. 查看你的 MyEditTextPreference 类,并检查你的布局 xml 是否正确调用了偏好设置。 包名必须相同。这就是我犯的错误所在。

  2. 试着修改你的 MyEditTextPreference 类,例如删除一些行,我的建议是:

    protected void onClick() { super.onClick(); EditText et = getEditText(); et.setSelection(et.getText().length()); }

或者你也可以修改你的构造函数。看看是否有新的错误日志。

  1. 在部署到设备之前,构建 gradle 并清除项目。通常这会指出 xml 中的错误。

如果所有方法都无效,则应该修复 MyEditTextPreference 类。这是我的建议,希望对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接