我正在一个学校项目中工作,我必须以MVP架构模式编写一个android项目。我也开始对Google Dagger 2进行一些研究。现在,我只是在尝试检查数据库中是否存在用户。众所周知,这个问题正在传递上下文。我寻找一个简明的答案,但找不到任何东西。这就是我试图做到的方式。

将Dagger 2用于上下文的代码:

public class DaggerApplication extends Application {
    DaggerComponent daggerComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        daggerComponent = DaggerComponent.builder().daggerModule(new DaggerModule(this)).build();
        daggerComponent.inject(this);
    }

    public DaggerComponent getAppComponent(){
        return daggerComponent;
    }
}


@Module
public class DaggerModule {
    private final DaggerApplication daggerApplication;

    public DaggerModule(DaggerApplication daggerApplication){
        this.daggerApplication = daggerApplication;
    }

    @Provides
    @Singleton
    Context providesApplicationContext() {
        return this.daggerApplication;
    }

    @Provides
    @Singleton
    SharedPreferences providesSharedPreferences(Context context) {
        return context.getSharedPreferences("My_Pref", Context.MODE_PRIVATE);
    }
}

@Singleton
@Component
        (modules = {DaggerModule.class})
public interface DaggerComponent {
    void inject(DaggerApplication daggerApplication);
    void inject(SigninActivityFragment signinActivityFragment);
}


然后,我在这样的片段中获取上下文:

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ((DaggerApplication)getActivity().getApplication()).getAppComponent().inject(this);
        accountPresenter = new AccountPresenter(this,new MyDatabaseSource(context));
    }


MyDatabaseSource需要此上下文才能使数据库正常工作。然后,此MyDatabaseSource打开数据库,从数据库中获取用户并关闭它。像这样:

public class MyDatabaseSource implements MyModel {
    public MyDatabaseSource(@NonNull Context context) {
        checkNotNull(context);
        myLocalDatabaseOpenHelper = new MyLocalDatabaseOpenHelper(context);
    }
    //Implementing MyModel functions here
}


这就是为什么我需要上下文。

public class MyLocalDatabaseOpenHelper extends SQLiteOpenHelper {

    private static final String MY_LOCAL_DATABASE_NAME = "MyUserDatabase";
    private static final int MY_LOCAL_DATABASE_VERSION = 1;

    public MyLocalDatabaseOpenHelper(Context context) {
        super(context, MY_LOCAL_DATABASE_NAME, null, MY_LOCAL_DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //Created my database here

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Not required as at version 1
    }

    @Override
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Not required as at version 1
    }
}


我创建了MyDatabaseSource实现的接口,并将其称为MyModel。

这是代码:

public interface MyModel {

    void insertUser(User user);
    void deleteUser(int index);
    void updateUser(User user);
    ArrayList <User> getUsers();
    User getUser(int index);

}


然后,我的主持人拥有了成为我的视图和模型之间的中间人所需的一切。

这是我的演示者代码:

public AccountPresenter(AccountView accountView, MyModel myModel) {
        this.accountView = accountView;
        this.myModel = myModel;
    }

    public void onSignInButtonClicked() {
        String username = accountView.getUsername();
        String password = accountView.getPassword();
        if (username.isEmpty()) {
            accountView.setUsernameErrorMessage(R.string.activity_signin_username_error);
        }
        if (password.isEmpty()) {
            accountView.setPasswordErrorMessage(R.string.activity_signin_password_error);
        }

        ArrayList<User> userArrayList = myModel.getUsers();
        if (userArrayList.size() != 0) {
            for (int i = 0; i < userArrayList.size(); i++) {
                if (username.equals(userArrayList.get(i).getUserName())) {
                    if (password.equals(userArrayList.get(i).getUserPassword())) {
                        accountView.showUserExists(R.string.activity_signin_user_exists_toast);
                    } else {
                        accountView.showIncorrectPassword(R.string.activity_signin_incorrect_password_toast);
                    }
                } else {
                    accountView.showUserDoesNotExist(R.string.activity_signin_user_does_not_exist_toast);
                }
            }
        } else {
            accountView.showNoUserExists(R.string.activity_signin_no_exists_toast);
        }
    }


我想知道这是否是使用Google Dagger 2实现MVP的正确方法。我个人认为应该有另一种实现此方法的方法。向演示者传递上下文超出了使用Google Dagger的目的。我刚刚开始研究Google Dagger 2和MVP模式。因此,任何建议都将有所帮助。我只是希望它是正确的。不想失去成绩。 :)

任何建议都将有所帮助。 :)

最佳答案

向演示者传递上下文优于使用Google Dagger的目的


如果Android应用程序具有单个入口点(例如main(String [] args)方法),则可能并且希望单独使用Dagger注入所有依赖项,包括Context。换句话说,您不必具有将Context作为参数初始化Dagger Component的系统。如果是这种情况,则以某种方式将Context传递给演示者将达到使用Dagger 2的目的。

但是,构成应用程序的Application和Activity实例不能直接实例化。尽管其中一些类可能具有公共构造函数,但您无法通过实例化获得功能齐全的实例。而是由系统为这些类实例化提供了Context和其他依赖项(例如FragmentManager)。

同样,将应用程序或活动中的上下文作为存储库/数据或模型的依存关系也不能避免模型和视图之间的关注点分离。


  我想知道这是否是使用Google Dagger 2实施MVP的正确方法


为此,我认为您将不得不与其他示例MVP项目进行比较。这是official one from Google

此外,您还必须确定您是否真正满足了MVP的三个突出特点:


  
  该模型是定义要在用户界面中显示或作用的数据的界面。
  演示者根据模型和视图进行操作。它从存储库(模型)中检索数据,并将其格式化以在视图中显示。
  该视图是一个被动界面,用于显示数据(模型)并将用户命令(事件)路由到演示者以对该数据进行操作。
  


我认为,最重要的是让您自己能够理解并证明您的应用程序如何满足MVP的标准,并在应用程序内部实现关注点分离,而不必担心您是否拥有适用于Android MVP的“正确解决方案”。 Android体系结构的约束。

09-10 09:47
查看更多