Tôi đã chơi xung quanh với mẫu MVP trong một vài tuần và tôi đã đến thời điểm tôi cần ngữ cảnh để bắt đầu một số service
và truy cập Shared Preferences
.Người trình bày có kiến thức về Hoạt động/Bối cảnh là một ý tưởng tồi trong mẫu MVP không?
Tôi đã đọc rằng mục đích của MVP là tách chế độ xem khỏi logic và có context
trong phạm vi Presenter
có thể đánh bại mục đích đó (sửa tôi nếu tôi sai về điều này).
Hiện nay, tôi có một LoginActivity mà trông giống như sau:
LoginActivity.java
public class LoginActivity extends Activity implements ILoginView {
private final String LOG_TAG = "LOGIN_ACTIVITY";
@Inject
ILoginPresenter mPresenter;
@Bind(R.id.edit_login_password)
EditText editLoginPassword;
@Bind(R.id.edit_login_username)
EditText editLoginUsername;
@Bind(R.id.progress)
ProgressBar mProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
MyApplication.getObjectGraphPresenters().inject(this);
mPresenter.setLoginView(this, getApplicationContext());
}
@Override
public void onStart() {
mPresenter.onStart();
ButterKnife.bind(this);
super.onStart();
}
@Override
public void onResume() {
mPresenter.onResume();
super.onResume();
}
@Override
public void onPause() {
mPresenter.onPause();
super.onPause();
}
@Override
public void onStop() {
mPresenter.onStop();
super.onStop();
}
@Override
public void onDestroy() {
ButterKnife.unbind(this);
super.onDestroy();
}
@OnClick(R.id.button_login)
public void onClickLogin(View view) {
mPresenter.validateCredentials(editLoginUsername.getText().toString(),
editLoginPassword.getText().toString());
}
@Override public void showProgress() { mProgressBar.setVisibility(View.VISIBLE); }
@Override public void hideProgress() {
mProgressBar.setVisibility(View.GONE);
}
@Override public void setUsernameError() { editLoginUsername.setError("Username Error"); }
@Override public void setPasswordError() { editLoginPassword.setError("Password Error"); }
@Override public void navigateToHome() {
startActivity(new Intent(this, HomeActivity.class));
finish();
}
}
Presenter Interface ILoginPresenter.java
public interface ILoginPresenter {
public void validateCredentials(String username, String password);
public void onUsernameError();
public void onPasswordError();
public void onSuccess(LoginEvent event);
public void setLoginView(ILoginView loginView, Context context);
public void onResume();
public void onPause();
public void onStart();
public void onStop();
}
Cuối cùng, trình bày của tôi :
LoginPresenterImpl.java
public class LoginPresenterImpl implements ILoginPresenter {
@Inject
Bus bus;
private final String LOG_TAG = "LOGIN_PRESENTER";
private ILoginView loginView;
private Context context;
private LoginInteractorImpl loginInteractor;
public LoginPresenterImpl() {
MyApplication.getObjectGraph().inject(this);
this.loginInteractor = new LoginInteractorImpl();
}
/**
* This method is set by the activity so that way we have context of the interface
* for the activity while being able to inject this presenter into the activity.
*
* @param loginView
*/
@Override
public void setLoginView(ILoginView loginView, Context context) {
this.loginView = loginView;
this.context = context;
if(SessionUtil.isLoggedIn(this.context)) {
Log.i(LOG_TAG, "User logged in already");
this.loginView.navigateToHome();
}
}
@Override
public void validateCredentials(String username, String password) {
loginView.showProgress();
loginInteractor.login(username, password, this);
}
@Override
public void onUsernameError() {
loginView.setUsernameError();
loginView.hideProgress();
}
@Override
public void onPasswordError() {
loginView.setPasswordError();
loginView.hideProgress();
}
@Subscribe
@Override
public void onSuccess(LoginEvent event) {
if (event.getIsSuccess()) {
SharedPreferences.Editor editor =
context.getSharedPreferences(SharedPrefs.LOGIN_PREFERENCES
.isLoggedIn, 0).edit();
editor.putString("logged_in", "true");
editor.commit();
loginView.navigateToHome();
loginView.hideProgress();
}
}
@Override
public void onStart() {
bus.register(this);
}
@Override
public void onStop() {
bus.unregister(this);
}
@Override
public void onPause() {
}
@Override
public void onResume() {
}
}
Như bạn thấy đấy, tôi đã thông qua bối cảnh từ Activity
vào Presenter
của tôi chỉ để tôi có thể truy cập vào Shared Preferences
. Tôi khá lo lắng về việc chuyển ngữ cảnh vào người trình bày của tôi. Đây có phải là một điều tốt để làm? Hay tôi nên làm theo cách khác?
EDIT thực hiện ưu tiên thứ 3 Jahnold của
Vì vậy, hãy bỏ qua các giao diện và thực hiện bởi vì nó khá nhiều toàn bộ điều. Vì vậy, bây giờ tôi là injecting
giao diện cho Sharedpreference vào người trình bày của tôi. Dưới đây là mã của tôi cho AppModule
AppModule.java
@Module(library = true,
injects = {
LoginInteractorImpl.class,
LoginPresenterImpl.class,
HomeInteractorImpl.class,
HomePresenterImpl.class,
}
)
public class AppModule {
private MyApplication application;
public AppModule(MyApplication application) {
this.application = application;
}
@Provides
@Singleton
public RestClient getRestClient() {
return new RestClient();
}
@Provides
@Singleton
public Bus getBus() {
return new Bus(ThreadEnforcer.ANY);
}
@Provides
@Singleton
public ISharedPreferencesRepository getSharedPreferenceRepository() { return new SharedPreferencesRepositoryImpl(application.getBaseContext()); }
}
}
Con đường tôi lấy bối cảnh là từ MyApplication.java
Khi ứng dụng bắt đầu, tôi chắc chắn rằng để tạo ra đồ thị đối tượng này với dòng mã này:
objectGraph = ObjectGraph.create(new AppModule(this));
Điều này có được không? Ý tôi là bây giờ tôi không phải chuyển ngữ cảnh từ hoạt động này sang người trình bày của tôi, nhưng tôi vẫn có ngữ cảnh của ứng dụng.
Tôi thích cái cuối cùng, nhưng nhìn vào việc triển khai, tôi vẫn cần ngữ cảnh đúng không? Vì vậy, bên trong mô-đun DI của tôi, tôi phải xác định một nơi nào đó bối cảnh chính xác? Tôi hỏi điều này bởi vì tôi không biết làm thế nào để thiết lập tiêm lên này. Ngoài ra, có thể thực hiện tương tự với các dịch vụ không? –
Nevermind, tôi đã tìm ra. Làm việc tốt nhưng tôi không chắc chắn làm thế nào điều này là làm việc đằng sau hậu trường. Tôi sẽ cập nhật câu hỏi của tôi để cho bạn thấy những gì tôi đã làm để thực hiện tiêm và cho tôi biết nếu điều này không phải là tối ưu. –
Điều bạn đã làm có vẻ ổn. Ngữ cảnh ứng dụng hiện bị ẩn khỏi Trình bày vì nó được đóng gói trong SharedPreferencesRepository. Tất cả các Presenter biết về là kho lưu trữ. – Jahnold