模型层(MVP)应该使用Activity引用

时间:2017-04-13 21:26:28

标签: android android-mvp

当我在Model中有需要当前活动实例的操作时,如何在Model层和View层之间进行适当的分离?

例如,我在我的Android应用程序(用MVP编写)中集成了Linkedin SDK。 在auth过程中,我有以下代码片段,当init()方法的第一个参数类型是Activity:

public void authWithLinkedin(final IAuth listener, Activity activity) {
    LISessionManager.getInstance(MyApplication.getContext()).init(activity, buildScope(), new AuthListener() {

        @Override
        public void onAuthSuccess() {
            listener.onSuccess();
        }

        @Override
        public void onAuthError(LIAuthError error) {
            listener.onError();
        }

    }, true);
}

如果我的Model层应该了解Android框架组件,我还有哪些选项可以保持MVP架构的清洁?

2 个答案:

答案 0 :(得分:1)

您可以使用

等软件约定/原则

"dependency inversion principle"

"ports and adapters"

您的模型图层了解Android ,如果可以避免它就是重点。

尝试这样的事情:

型号:

private final SocialLoginProvider socialLoginProvider;

public MyModel(SocialLoginProvider socialLoginProvider) {
       this.socialLoginProvider = socialLoginProvider;
}

public void authWithLinkedin(final IAuth listener) {
       socialLoginProvider.init(buildScope(), new SocialLoginProvider.Listener() {

        @Override
        public void onAuthSuccess() {
            listener.onSuccess();
        }

        @Override
        public void onAuthError() {
            listener.onError();
        }

    }, true);
}

厂:

public MyModel getModel(Context context) {
    LISessionManager li = LISessionManager.getInstance(context);
    SocialLoginProvider provider = new LinkedInSocialLoginProvider(context, li);
    return new MyModel(provider);
}

接口:

public interface SocialLoginProvider {
     void init(Scope scope, Listener listener);

     interface Listener {
           void onAuthSuccess();
           void onAuthError();
     } 
}

SocialLoginProvider适配器:

public class LinkedInSocialLoginProvider implements SocialLoginProvider {

          private final Context context;
          private final LISessionManager linkedInSessionManager;

          public LinkedInSocialLoginProvider(Context context, LISessionManager linkedInSessionManager) {
               this.context = context;
               this.linkedInSessionManager = linkedInSessionManager;
          }

          @Override
          public void init(Scope scope, Listener listener) {
              linkedInSessionManager.init(context, scope, 
                    new AuthListener() {
                      @Override
                      public void onAuthSuccess() {
                         listener.onSuccess();
                      }

                      @Override
                      public void onAuthError(LIAuthError error) {
                         listener.onError();
                      }
                   }, true);
           }

}

答案 1 :(得分:0)

理想情况下,可以在Model层中安装Android Framework组件。例如,您需要netstandard使用Context在本地存储/访问数据和/或使用getDefaultSharedPreferences(Context)管理本地数据库。

SQLiteOpenHelper似乎与LISessionManager.getInstance(MyApplication.getContext()).init类似,因为它是一种从外部组件接收特定结果的侦听器。要处理这种情况,您可以参考this