简体   繁体   English

Android MVP:在Presenter中访问内容提供商

[英]Android MVP:Accessing Content Provider in Presenter

I am working on a project with Android MVP, so far the things I am able to understand as thumb rules for this architecture are: 我正在开发一个使用Android MVP的项目,到目前为止,我能够理解为这种架构的拇指规则是:

  1. Presenter should not contain any android code. Presenter不应包含任何Android代码。

  2. View should not contain a reference to the Model. 视图不应包含对模型的引用。

I am following this and so far I am successful in implementing this. 我跟着这个,到目前为止我成功实现了这一点。 In my project, I need to access ContentProvider and SharedPreference. 在我的项目中,我需要访问ContentProvider和SharedPreference。 For them, I need context to be passed to the presenter and this is bad practice. 对于他们来说,我需要将上下文传递给演示者,这是不好的做法。

One solution is to create a class for accessing the SharedPreference and let it implement the interface whose reference could be passed to the presenter. 一种解决方案是创建一个用于访问SharedPreference的类,并让它实现可以将引用传递给演示者的接口。

  1. Is this a standard way to do this? 这是一种标准的方法吗?
  2. How should I implement the content provider part? 我该如何实现内容提供商部分?

Am I missing something with this architecture implementation? 我错过了这个架构实现的东西吗?

This is for those who come across this problem. 这适用于遇到此问题的人。

In my question as I quoted -"I create a class for accessing the SharedPreference and let it implement the interface whose reference could be passed to the presenter." 在我引用的问题中 - “我创建了一个用于访问SharedPreference的类,并让它实现了可以将引用传递给演示者的接口。”

I asked about this solution from Antonio Leive who has written a great article on Android MVP, here is the link http://antonioleiva.com/mvp-android/ . 我问过Antonio Leive的这个解决方案,他写了一篇关于Android MVP的精彩文章,这里是链接http://antonioleiva.com/mvp-android/

Here is his reply: 这是他的回复:

"The thing you mention is related to dependency inversion. You must delegate the use of the framework to the minimum possible part of the code. “你提到的事情与依赖性反转有关。你必须将框架的使用委托给代码的最小可能部分。

So, for instance, if you want to use the SharedPreferences on a presenter, you will use an entity called PreferencesManager (or something more descriptive) that will probably be just an interface. 因此,例如,如果您想在演示者上使用SharedPreferences,您将使用一个名为PreferencesManager的实体(或更具描述性的实体),它可能只是一个接口。 You then inject (through the constructor or a setter) an implementation of the interface, which will use the context to retrieve the preferences. 然后,您(通过构造函数或setter)注入接口的实现,该实现将使用上下文来检索首选项。 You can do the injection manually, which will become a bit tedious if you have many entities that use the context, or use a dependency injector. 您可以手动执行注入,如果您有许多使用上下文的实体或使用依赖注入器,这将变得有点单调乏味。 Do you know Dagger? 你知道Dagger吗? I have three articles about it in the blog. 我在博客中有三篇关于它的文章。 Though they're based on Dagger 1, the theory may help you understand the concept." 虽然它们基于Dagger 1,但这个理论可以帮助你理解这个概念。“

This is how I implemented, 这是我实施的方式,

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

Create the implementation of the above interface, 创建上述接口的实现,

  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;
}
 }

Pass the implementation of interface to the presenter, I initialized the presenter as 将接口的实现传递给演示者,我将演示者初始化为

AppPrefsManager appprefs=AppPrefs.getInstance(this);
Presentor mypresenter=new Presenter(apprefs);

Now my Presenter can access the SharedPreferences. 现在,我的Presenter可以访问SharedPreferences。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM