【问题标题】:Android MVP + Google Dagger 2 + SQLiteAndroid MVP + Google Dagger 2 + SQLite
【发布时间】:2017-01-01 18:23:53
【问题描述】:

我正在做一个学校项目,我必须在 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 模式。因此,任何建议都会有所帮助。我只是希望它是正确的。不想丢分。 :)

任何建议和意见都会有所帮助。 :)

【问题讨论】:

标签: android sqlite dagger-2


【解决方案1】:

将上下文传递给演示者胜过使用 Google Dagger 的目的

如果 Android 应用程序只有一个入口点(如 main(String [] args) 方法),那么单独使用 Dagger 来注入所有依赖项(包括 Context)将是可能且可取的。换句话说,您不必在这个系统中使用 Context 作为参数来初始化 Dagger 组件。如果是这种情况,那么将 Context 传递给演示者在某种程度上会超出使用 Dagger 2 的目的。

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

同样,将 Application 或 Activity 的 Context 作为存储库/数据或模型的依赖项并不是可预防的违反模型和视图之间关注点分离的行为。

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

为此,我认为您必须将您所做的工作与其他示例 MVP 项目进行比较。这是official one from Google

此外,您还必须确定您是否真正实现了MVP 的三个显着特征:

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

与其担心你是否有 Android MVP 的“正确解决方案”,我认为最重要的是你自己能够理解和证明你的应用如何满足 MVP 的标准并实现关注点分离在 Android 架构的约束范围内。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多