0

我正在尝试建立自己的Preference课程,但遇到了一些麻烦。看起来将数据保存到首选项的方式是通过Preference类中的“持久”组方法。但是,在我的偏好中,我打开了一个颜色选择器对话框,我需要从对话框的colorChanged覆盖中保存偏好。每当我运行应用程序并尝试更改颜色偏好时,我都会得到:

06-05 10:21:46.396: ERROR/AndroidRuntime(516): FATAL EXCEPTION: main
java.lang.IllegalAccessError: tried to access method android.preference.Preference.persistInt:(IIII)V from class android.preference.ColorSelectionPreference$1
at android.preference.ColorSelectionPreference$1.colorChanged(ColorSelectionPreference.java:55)
at android.apis.graphics.ColorPickerDialog.onClick(ColorPickerDialog.java:168)

(更新:2012 年 6 月 5 日 12:20)我尝试使用callChangeListener强制onPreferenceChangeListener触发,但它崩溃并出现相同的错误。没有callChangeListener,偏好数据(可能)被保存,但onPreferenceChangeListener不会被触发:

06-05 12:20:23.691: ERROR/AndroidRuntime(2834): FATAL EXCEPTION: main
java.lang.IllegalAccessError: tried to access method android.preference.ColorSelectionPreference.callChangeListener:(IIII)V from class android.preference.ColorSelectionPreference$1
at android.preference.ColorSelectionPreference$1.colorChanged(ColorSelectionPreference.java:52)
at android.apis.graphics.ColorPickerDialog.onClick(ColorPickerDialog.java:168)

这是实际的课程:

package android.preference;

import android.apis.graphics.ColorPickerDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.util.AttributeSet;

public class ColorSelectionPreference extends Preference {
    private Context mContext;
    private int mColor;

    public ColorSelectionPreference(Context context) {
        super(context);
        mContext = context;
    }

    public ColorSelectionPreference(Context context, AttributeSet attr) {
        super(context, attr);
        mContext = context;
    }

    public int getColor() {
        return mColor;
    }

    public void setColor(int color) {
        mColor = color;
    }

    @Override
    public void onClick() {
        //get original preference
        //set ColorPickerDialog to original preference color or default color
        ColorPickerDialog dialog = new ColorPickerDialog(mContext, new ColorPickerDialog.OnColorChangedListener() {
            public void colorChanged(int a, int r, int g, int b) {
                int selectedColor = Color.argb(a,r,g,b);
                setColor(selectedColor);

                /*** crashes on callChangeListener ***/
                //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
                //SharedPreferences.Editor edit = prefs.edit();
                //edit.putInt(getKey(), selectedColor);
                //edit.commit();
                //callChangeListener(selectedColor);

                /*** the offending code, error refers to this line ***/
                persistInt(selectedColor);

                /*** tried this as well by request on IRC ***/
                //ColorSelectionPreference.this.persistInt(selectedColor);
            }
        }, mColor);
        dialog.show();
    }
}
4

2 回答 2

0

这是一个 hacky 解决方法,它使用 Handler 从内部类回调主类。它不漂亮,但它有效。

package android.preference;

import android.apis.graphics.ColorPickerDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;

public class ColorSelectionPreference extends Preference {
    private Context mContext;
    private int mColor;

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if(msg.getData().containsKey("color")) {
                int color = msg.getData().getInt("color");
                setColor(color);
            }
        }
    };

    public ColorSelectionPreference(Context context) {
        super(context);
        mContext = context;
    }

    public ColorSelectionPreference(Context context, AttributeSet attr) {
        super(context, attr);
        mContext = context;
    }

    public int getColor() {
        return mColor;
    }

    public void setColor(int color) {
        mColor = color;
        persistInt(new Integer(color));
    }

    @Override
    public void onClick() {
        //get original preference
        //set ColorPickerDialog to original preference color or default color
        ColorPickerDialog dialog = new ColorPickerDialog(mContext, new ColorPickerDialog.OnColorChangedListener() {
            public void colorChanged(int a, int r, int g, int b) {
                int selectedColor = Color.argb(a,r,g,b);
                Bundle bundle = new Bundle();
                bundle.putInt("color", selectedColor);
                Message msg = new Message();
                msg.setData(bundle);
                mHandler.sendMessage(msg);

                //setColor(selectedColor);

                /*** tried this, but the onPreferenceChangedListener never gets triggered, so this won't work ***/
                //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
                //SharedPreferences.Editor edit = prefs.edit();
                //edit.putInt(getKey(), selectedColor);
                //edit.commit();
                //callChangeListener(selectedColor);

                /*** the offending code, error refers to this line ***/
                //container.

                /*** tried this as well by request on IRC ***/
                //ColorSelectionPreference.this.persistInt(selectedColor);
            }
        }, mColor);
        dialog.show();
    }
}
于 2012-06-05T18:00:34.307 回答
0

我自己也遇到了这个问题。我不会假装理解它,但这似乎更容易解决:

// ...why is this necessary?  what is special about Preference.persistInt?
@Override protected boolean persistInt(int value)
{
    return super.persistInt(value);
}
于 2013-05-09T14:22:30.647 回答