Android MVP模式:在Presenter中访问内容提供者

3
我正在使用Android MVP架构开发项目,到目前为止,我能理解的这种架构的基本规则是:
  1. Presenter不应包含任何Android代码。

  2. View不应包含对Model的引用。

我遵循了这些规则,并且目前在实现中取得了成功。在我的项目中,我需要访问ContentProvider和SharedPreference。为此,我需要将上下文传递给Presenter,但这是不好的做法。
一种解决方案是创建一个类来访问SharedPreference,并使其实现接口,然后将接口的引用传递给Presenter。
  1. 这是标准的做法吗?
  2. 我该如何实现ContentProvider部分?
我在这个架构实现中是否遗漏了什么?

  1. 没有“标准”方法,但在我看来这是最合理的解决方案。
  2. 请查看 https://github.com/googlesamples/android-architecture/tree/todo-mvp-contentproviders,他们提供了一个关于MVP +内容提供程序的示例。
- rciovati
太棒了,这正是我在寻找的。谢谢 @RiccardoCiovati - karan vs
1个回答

2
这是给那些遇到这个问题的人。

我引用了我的问题 - “我创建了一个用于访问SharedPreference的类,并让它实现接口,其引用可以传递给Presenter。”

我向在Android MVP上写了一篇很棒的文章的Antonio Leiva询问了这个解决方案,这是链接http://antonioleiva.com/mvp-android/

以下是他的回复:

“你提到的事情与依赖反转有关。您必须将框架的使用委托给代码的最小可能部分。

因此,例如,如果您想在Presenter上使用SharedPreferences,则将使用名为PreferencesManager(或更具描述性的内容)的实体,该实体可能仅是一个接口。然后,通过构造函数或setter注入接口的实现,该实现将使用上下文检索首选项。您可以手动进行注入,如果有许多使用上下文的实体,则会变得有点乏味,或者使用依赖注入器。您知道Dagger吗?我在博客中有三篇关于它的文章。虽然它们基于Dagger 1,但理论可能会帮助您了解概念。”

这就是我实现的方式,

 interface AppPrefsManager {
    <T> void  putData(String key,T obj);
    <T> T getData(String key, T obj);
}

创建上述接口的实现:
  public class AppPrefs implements Repository.Appprefsrepository {

private Context context;

private static AppPrefs ourInstance;
private SharedPreferences preferences;

public static AppPrefs getInstance(Context context) {
    if (ourInstance == null) {
        ourInstance = new AppPrefs(context);
    }
    return ourInstance;
}

private AppPrefs(Context context) {
    this.context = context;
}

public SharedPreferences getPreferences() {
    if (preferences == null) {
        preferences = context.getSharedPreferences("prefs", Context.MODE_MULTI_PROCESS);
    }
    return preferences;
}

public <T> void putData(String key, T obj) {

    SharedPreferences.Editor editor = getPreferences().edit();
    if (obj instanceof String) {
        editor.putString(key, (String) obj);
    } else if (obj instanceof Boolean) {
        editor.putBoolean(key, ((Boolean) obj).booleanValue());
    } else if (obj instanceof Integer) {
        editor.putInt(key, ((Integer) obj).intValue());
    } else if (obj instanceof Long) {
        editor.putLong(key, ((Long) obj).longValue());
    }
    editor.commit();
}




public <T> T getData(String key, T obj) {
    if (obj instanceof String) {
        return (T) getPreferences().getString(key, (String) obj);
    } else if (obj instanceof Boolean) {
        return (T) (Boolean) getPreferences().getBoolean(key, ((Boolean) obj).booleanValue());
    } else if (obj instanceof Integer) {
        return (T) (Integer) getPreferences().getInt(key, ((Integer) obj).intValue());
    } else if (obj instanceof Long) {
        return (T) (Long) getPreferences().getLong(key, ((Long) obj).longValue());
    }
    return null;
}
 }

将接口的实现传递给Presenter,我将Presenter初始化为:
AppPrefsManager appprefs=AppPrefs.getInstance(this);
Presentor mypresenter=new Presenter(apprefs);

现在我的Presenter可以访问SharedPreferences了。

+1 给你的好回答。我唯一的问题是“这是最好的方法吗?还是有改进的空间?”另外,你是否已经得到了解决方案来回答你的第二个问题? - eRaisedToX
使用依赖注入,这似乎是标准解决方案。 - karan vs

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