我有一个Preference包装器类,我正在使用它:
public final class Preferences implements OnSharedPreferenceChangeListener
{
private SharedPreferences sharedPreferences;
Context context;
private final int FB_REQUESTCODE=1;
private final int FB_SELCTFRIENDS=2;
public Preferences(Context context)
{
this.context=context;
this.sharedPreferences=PreferenceManager.getDefaultSharedPreferences(context);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
public String getFBFriends()
{
return sharedPreferences.getString(Keys.FB_FRIENDS.key, Defaults.FB_FRIENDS);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key)
{
if (key.equals(Keys.FB_FRIENDS.key))
{
String fbFriendsVal = getFBFriends();
if (fbFriendsVal.equals(Consts.FB_FRIENDS_FIRE))
{
if(context instanceof Activity)
{
Activity activity = (Activity) context;
activity.startActivityForResult(new Intent(context,
FriendPickerActivity.class), FB_SELCTFRIENDS);
}
else if (context instanceof Service)
{
Service service=(Service) context;
service.startActivity(new Intent(context,
FriendPickerActivity.class), null);
}
else
{
Log.e(App.TAG, "Could not start FB Friends Activity");
}
}
}
}
}
此处FB_FRIENDS指的是ListPreference
的密钥。当用户选择此列表中的特定项目时,我想触发结果的活动,我在onSharedPreferenceShared
方法中执行此操作。
问题是context
。我在我的应用程序中的各个位置使用此首选项类,例如Activty
和Service
。由于在服务内部,我不维护活动上下文,我只是传递服务上下文。
现在的问题是,startActivityForResult
显然不适用于服务类,而且当我得到ClassCastException
时(如果我没有把这个逻辑检查实例类)。
我认为很少有解决方案:
直接维护对MainActivity的引用,而不是Context,例如:
MainActivity context
;而不是Context context;
但是,这意味着我无法从服务中访问我的偏好。
或者我可以保持对服务和MainActivity的引用,如下所示
public Preferences(MainActivity context1, Service context2)
{
if(context1!=null)
this.context=context1;
else
this.context=context2
this.sharedPreferences=PreferenceManager.getDefaultSharedPreferences(context);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
即使在这种情况下,我也会将服务中的首选项实例化为
new Preferences(null, this);
我无法致电StartActivityForResult
这是我的最终目标。
在这种情况下最干净的解决方案是什么?
答案 0 :(得分:2)
最干净的解决方案是发送一个界面,例如类中定义的LocalPreferenceChangeCallback
:
public static interface LocalPreferenceChangeCallback {
void onPreferenceChanges();
}
服务类和活动都将实现此接口 - 随意添加您希望此方法的任何参数;最重要的主题是拥有界面:
startActivityForResult
startActivity
将该界面作为参数发送,而不是context
:
public final class Preferences implements OnSharedPreferenceChangeListener
{
private SharedPreferences sharedPreferences;
private LocalPreferenceChangeCallback prefCallback;
private final int FB_REQUESTCODE=1;
private final int FB_SELCTFRIENDS=2;
public Preferences(Context appContext, LocalPreferenceChangeCallback prefCallback)
{
this.prefCallback = prefCallback;
this.sharedPreferences=PreferenceManager.getDefaultSharedPreferences(appContext);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
public String getFBFriends()
{
return sharedPreferences.getString(Keys.FB_FRIENDS.key, Defaults.FB_FRIENDS);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key)
{
if (key.equals(Keys.FB_FRIENDS.key))
{
String fbFriendsVal = getFBFriends();
if (fbFriendsVal.equals(Consts.FB_FRIENDS_FIRE))
{
if(prefCallback != null) {
prefCallback.onPreferenceChanges();
}
}
}
}
public static interface LocalPreferenceChangeCallback {
void onPreferenceChanges();
}
}
你需要发送某种Context
来实例化sharedPreferences
对象,但是你只是因为这个事实而发送它,你不需要担心如何处理偏好变化。最后,这是一个OOP问题......
由于Preferences
与java.utils.prefs.Preferences
发生冲突,因此类命名会导致误导。