Как использовать метод Retrofit call.enqueue () (правильный путь) при работе с шаблоном MVP - PullRequest
0 голосов
/ 07 февраля 2019

Я новичок в Android, и это первый раз, когда я пытаюсь использовать шаблон MVP в своем коде ... как я понимаю, пока мой взгляд должен говорить с докладчиком, а с докладчиком - моделью, а затем - с докладчиком.поговорим еще раз, чтобы посмотреть .. Я хотел бы, чтобы я был прав с этим !!!как показано ниже в моем простом примере кода, я пытаюсь вернуть значение результата из модели докладчику, а затем я буду использовать это значение результата в докладчике, чтобы решить, какой метод следует вызвать в представлении. У меня есть 2 вопросаи я надеюсь, что это поможет.1) Метод enqueue работает асинхронно, и значение результата всегда будет возвращать пустое значение, сбой или что-то еще ... потому что он работает один ... и когда я пытаюсь использовать метод execute вместо этого, я сталкиваюсь с ошибкой NetworkOnMainThreadException ... таккак я могу сделать правильный путь?2) Это правильный способ использования шаблона MVP?

Это класс RegistrationContract

public class SignupContract {
public interface IView{
    void signupSuccess();
    void signupFailed(String message);
}

public interface IPresenter{
    void signup(UserProfile userProfile);
}

public interface IModel{
    String signup(UserProfile userProfile);
}

}
Это код View ..

public class SignupActivity extends AppCompatActivity implements SignupContract.IView {

//some code

@Override
protected void onCreate(Bundle savedInstanceState) {
    //some code

    createAccountBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

           //some code

            presenter.signup(userProfile);
        }
    });
}

@Override
public void signupSuccess() {
    /*AppUtils.dismissLoadingDialog(SignupActivity.this,"","");*/
    Intent intent = new Intent(SignupActivity.this, SigninActivity.class);
    startActivity(intent);
    finish();
}

@Override
public void signupFailed(String message) {
    /*AppUtils.dismissLoadingDialog(SignupActivity.this,"","");*/
    AppUtils.showErrorMessage(SignupActivity.this, message);
}

и это ведущий

public class SignupPresenter implements SignupContract.IPresenter {

SignupContract.IView view;
SignupContract.IModel model;

public SignupPresenter(SignupContract.IView view){
    model = new SignupModel();
    this.view = view;
}

@Override
public void signup(UserProfile userProfile) {

    userProfile = UserProfileCleaner.clean(userProfile, "signup");

    UserProfileDTO dto = new UserProfileDTO();
    String validationMessage = dto.validateUserProfile(userProfile, "signup");

    if(validationMessage != null && !validationMessage.equals("")){
        view.signupFailed(validationMessage);
    }else{


        String signupResult = model.signup(userProfile);

        if(signupResult.equals("success")){
            view.signupSuccess();
        }else {
            view.signupFailed(signupResult);
        }

    }

}

}

и это класс модели

public class SignupModel implements SignupContract.IModel {

private String TAG = "SignupModel";

private String result = "";

@Override
public String signup(UserProfile userProfile) {
    final Context context = DKApp.getContext();
    ServiceWrapper serviceWrapper = new ServiceWrapper(null);
    Call<SignupResponse> userSignUpCall = serviceWrapper.userSignUpCall(userProfile.getUser().getUsername(),
            userProfile.getUser().getPassword(),userProfile.getPhoneNumber(), userProfile.getEmailAddress(),
            userProfile.getFullName());


    userSignUpCall.enqueue(new Callback<SignupResponse>() {
        @Override
        public void onResponse(Call<SignupResponse> call, Response<SignupResponse> response) {
            if( response.body() != null && response.isSuccessful() ){
                Log.e(TAG,response.body().toString());
                if(response.body().getStatus() == 1){
                    //some code
                    result = "success";
                }else{
                    result = response.body().getMessage();
                }
            }else{
                result = context.getResources().getString(R.string.request_failed);
            }
        }

        @Override
        public void onFailure(Call<SignupResponse> call, Throwable t) {
            Log.e(TAG, "Failure : " + t.toString());
            result = context.getResources().getString(R.string.request_failed);
        }
    });

    return result;
}

}

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

В паттерне MVP вы должны сделать пустышку.Ведущий всегда рассказывает, что делать.Вот пример:

In View =>

presenter.login(userName, password)

In Presenter =>

fun login(userName: String, password: String) {
//login logic
     if(success) view.showLoginSuccess()
     else view.showLoginError()
}

Это очень краткое объяснение шаблона MVP.По вашему вопросу вы не можете делать запросы в Главной теме.К счастью, Retrofit имеет систему управления потоками.Но вы не должны использовать его в такой модели, как вы, вы можете использовать его в презентере или искать статьи по чистой архитектуре для более правильного подхода.Если вы используете его в Presenter, вы должны сделать что-то вроде

userSignUpCall.enqueue(new Callback<SignupResponse>() {
        @Override
        public void onResponse(Call<SignupResponse> call, Response<SignupResponse> response) {
            if( response.body() != null && response.isSuccessful() ){
                Log.e(TAG,response.body().toString());
                if(response.body().getStatus() == 1){
                    //some code
                    view.showMessage("success");
                }else{
                    view.showMessage(response.body().getMessage());
                }
            }else{
                view.showError(context.getResources().getString(R.string.request_failed));
            }
        }

        @Override
        public void onFailure(Call<SignupResponse> call, Throwable t) {
            Log.e(TAG, "Failure : " + t.toString());
            view.showError(context.getResources().getString(R.string.request_failed));
        }
    });
0 голосов
/ 07 февраля 2019

Вы делаете асинхронный вызов в модели, который может занять 100 мсек или 2-4 с, поэтому вы получаете signupResult от него, например String signupResult = model.signup(userProfile);, это неправильно.

Изменения, которые вам потребуются:

1) Добавьте метод onComplete в IPresenter и измените IModel

public interface IPresenter{ 
    void signup(UserProfile userProfile);
    //add
    void onComplete(String signUpresult);
} 

public interface IModel{ 
    //changed
    void signup(UserProfile userProfile);
} 

2) В вашем RegistrationPresenter передайте экземпляр презентатора модели

public class SignupPresenter implements SignupContract.IPresenter { 
..

   public SignupPresenter(SignupContract.IView view){ 
       model = new SignupModel(this); 
       this.view = view;
   } 

   ...

   @Overrides
   public void onComplete(String signupResult){
      if(signupResult.equals("success")){
        view.signupSuccess(); 
      }else { 
         view.signupFailed(signupResult);
      }
   } 

   ...
}

3) В вашем RegistrationModel после получения результатавызовите onComplete (// result) от докладчика

public class SignupModel implements SignupContract.IModel {

   SignupPresenter presenter; 

   public SignupModel(SignupPresenter presenter){ 
       this.presenter = presenter
   }

   @Override 
   public void signup(UserProfile userProfile) {
        ...
        userSignUpCall.enqueue(new Callback<SignupResponse>() {
        @Override 
        public void onResponse(Call<SignupResponse> call, Response<SignupResponse> response) { 
            if(response.body() != null && response.isSuccessful() ){ 

                if(response.body().getStatus() == 1){ 
                    //some code 
                    presenter.onComplete("success"); 
                }else{ 
                    presenter.onComplete(response.body().getMessage()); 
                } 
            }else{ 
                presenter.onComplete(context.getResources().getString(R.string.request_failed)); 
            } 
        } 

        @Override 
        public void onFailure(Call<SignupResponse> call, Throwable t) { 
            Log.e(TAG, "Failure : " + t.toString()); 
            presenter.onComplete(context.getResources().getString(R.string.request_failed));  
        } 
    }); 
   }

}

Обязательно: Отображение диалогового окна хода выполнения при вызове и отклонение его по onComplete в RegistrationPresenter.

ВашПонимание достаточно хорошее, также нужно знать, что модель должна общаться и с докладчиком.Чтобы узнать больше о шаблоне проектирования MVP, прочитайте this

...