avant-propos
Récemment, un nouveau projet pour le faire, de construire un cadre de temps, la façon de trier le prochain mode MVP, record par la présente, bienvenue pour me corriger.
Tout d'abord, la première dépend de
Deux, ApiServer, définit un certain nombre d'interfaces
interface publique ApiServer { @POST ( "shopping_login.htm") observable < chaîne > LoginByRx (@field ( "nom d'utilisateur") nom d'utilisateur String, @field ( "mot de passe") Mot de passe de chaîne); }Trois, ApiRetrofit, initialisation Rénovation, OkHttpClient, a rejoint l'intercepteur
public class {ApiRetrofit public final BASE_SERVER_URL = "https://wawa-api.vchangyi.com/" String; ApiRetrofit private static apiRetrofit; rénovation privée Rénovation; client OkHttpClient privé; ApiServer privé apiServer; private String TAG = "ApiRetrofit"; / ** * Demande quête d'accès * Intercepteurs de réponse * / Interceptor Interceptor privé = new Interceptor () { @Override interception de réponse publique (chaîne de la chaîne) throws IOException { Demande demande = chain.request (); longue startTime = System.currentTimeMillis (); réponse de réponse = chain.proceed (chain.request ()); longue endTime = System.currentTimeMillis (); longue durée = endTime - startTime; MediaType mediaType = response.body () contentType () .; Chaîne content = response.body () string () .; Log.e (TAG, "---------- Demande de départ ----------------"); Log.e (TAG, "|" + request.toString () + request.headers () toString ().); Log.e (TAG, "| Réponse:" + contenu); Log.e (TAG, "---------- demande Fin:" + durée + "millisecondes ----------"); retour response.newBuilder () .Body (ResponseBody.create (mediaType, le contenu)) .build (); } }; ApiRetrofit publique () { client = new OkHttpClient.Builder () // add intercepteur journal .addInterceptor (intercepteur) .connectTimeout (10, TimeUnit.SECONDS) .readTimeout (10, TimeUnit.SECONDS) .build (); retrofit = new Retrofit.Builder () .baseUrl (BASE_SERVER_URL) .addConverterFactory (GsonConverterFactory.create ()) .addConverterFactory (ScalarsConverterFactory.create ()) // support RxJava2 .addCallAdapterFactory (RxJava2CallAdapterFactory.create ()) .client (client) .build (); apiServer = retrofit.create (ApiServer.class); } public static ApiRetrofit getInstance () { if (apiRetrofit == NULL) { synchronisée (Object.class) { if (apiRetrofit == NULL) { apiRetrofit = new ApiRetrofit (); } } } retourner apiRetrofit; } publique ApiServer getApiService () { retourner apiServer; } }En quatrième lieu, la classe de base
1.BaseView, qui définit l'interface commune
2.BaseModel
3.BasePresenter
BasePresenter public class < V étend BaseView > { privé CompositeDisposable compositeDisposable; publique V baseView; protégé ApiServer apiServer = ApiRetrofit.getInstance () getApiService () .; BasePresenter publique (V baseView) { this.baseView = baseView; } / ** * Unbind * / detachView () {publique vide baseView = null; removeDisposable (); } / ** * Voir le retour * * @Return * / publique V getBaseView () { retourner baseView; } addDisposable public void (Observable < ? > observable, observateur BaseObserver) { if (compositeDisposable == NULL) { compositeDisposable = new CompositeDisposable (); } compositeDisposable.add (observable.subscribeOn (Schedulers.io ()) .observeOn (AndroidSchedulers.mainThread ()) .subscribeWith (observateur)); } removeDisposable public void () { si (compositeDisposable! = null) { compositeDisposable.dispose (); } } }4.BaseObserver, traitent principalement des erreurs communes
classe abstraite BaseObserver publique < T > étend DisposableObserver < T > { protégée vue BaseView; / ** * Données parse failed * / public static final int PARSE_ERROR = 1001; / ** * Problèmes de réseau * / public static final int BAD_NETWORK = 1002; / ** * Erreur de connexion * / public static final int connect_error = 1003; / ** * Délai de connexion dépassé * / public static final int connect_timeout = 1004; BaseObserver publique (vue BaseView) { this.view = vue; } @Override onStart protected void () { si (vue! = null) { view.showLoading (); } } @Override OnNext public void (T o) { try { modèle BaseModel = (BaseModel) o; si (model.getErrcode () == 0) { onSuccess (o); } Else { si (vue! = null) { view.onErrorCode (modèle); } } } Catch (Exception e) { e.printStackTrace (); onError (e.ToString ()); } } @Override onError public void (Throwable e) { si (vue! = null) { view.hideLoading (); } si (e instanceof HttpException) { // erreur HTTP onException (BAD_NETWORK); } Else if (e instanceof ConnectException || e instanceof UnknownHostException) { // erreur de connexion onException (connect_error); } Else if (e instanceof InterruptedIOException) { // délai de connexion onException (connect_timeout); } Else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) { // erreur d'analyse onException (PARSE_ERROR); } Else { if (e! = null) { onError (e.ToString ()); } Else { onError ( "erreur inconnue"); } } } onException private void (int unknownError) { commutateur (unknownError) { cas connect_error: le onError ( "Erreur de connexion"); break; cas connect_timeout: le onError ( "délai de connexion"); break; cas BAD_NETWORK: onError ( "des problèmes de réseau"); break; cas PARSE_ERROR: le onError ( « données d'analyse de défaut »); break; par défaut: break; } } @Override onComplete () {publique vide si (vue! = null) { view.hideLoading (); } } abstract onSuccess public void (T o); abstrait onError public void (String msg); }5.BaseActivity, atteindre BaseView, cycle de vie Présentateur traitée.
classe abstraite BaseActivity publique < P étend BasePresenter > étend de AppCompatActivity BaseView { contexte public de contexte; dialogue ProgressDialog privé; Toast publique toasts; présentateur de P protégé; protégé createPresenter résumé P (); abstract int getLayoutId protégé (); @Override onCreate vide protégé (Bundle savedInstanceState) { super.onCreate (savedInstanceState); contexte = ceci; setContentView (getLayoutId ()); présentateur = createPresenter (); initView (); InitData (); } InitData () {publique vide } initView public void () { } @Override OnDestroy protected void () { super.onDestroy (); si (présentateur! = null) { presenter.detachView (); } } / ** * @Param s * / showtoast public void (String s) { if (pain grillé == NULL) { toasts = Toast.makeText (getApplicationContext (), s, Toast.LENGTH_LONG); } toast.show (); } private void closeLoadingDialog () { if (dialogue! = null && dialog.isShowing ()) { dialog.dismiss (); } } private void showLoadingDialog () { if (dialogue == null) { dialogue = new ProgressDialog (contexte); } dialog.setCancelable (false); dialog.show (); } @Override showLoading public void () { showLoadingDialog (); } @Override hideLoading public void () { closeLoadingDialog (); } @Override showError public void (String msg) { showtoast (msg); } @Override onErrorCode public void (modèle BaseModel) { } @Override showLoadingFileDialog () {publique vide showFileDialog (); } @Override hideLoadingFileDialog public void () { hideFileDialog (); } @Override onProgress public void (long totalSize, longue DOWNSIZE) { if (dialogue! = null) { dialog.setProgress ((int) (Downsize * 100 / totalSize)); } } }Comme ci-dessus, le cadre a été mis en place bien, nous allons voir comment utiliser le projet réel.
Nous atterrissage simulé
1. Définir LoginView hérité de BaseView
interface publique LoginView étend BaseView { onLoginSucc vide (); }2. Définir LoginPresenter héritée de BasePresenter
LoginPresenter public class étend BasePresenter < LoginView > { LoginPresenter publique (LoginView baseView) { Super (baseView); } connexion public void (String name, String PWD) { addDisposable (apiServer.LoginByRx (nom, PWD), nouveau BaseObserver (baseView) { @Override onSuccess public void (Object o) { baseView.onLoginSucc (); } @Override onError public void (String msg) { baseView.showError (msg); } }); } }utilisation 3.LoginActivity
LoginActivity public class étend BaseActivity < LoginPresenter > met en uvre LoginView { privé AutoCompleteTextView mEmailView; privé EditText mPasswordView; @Override LoginPresenter protégé createPresenter () { return new LoginPresenter (this); } @Override protected int getLayoutId () { retourner R.layout.activity_login; } @Override initView public void () { mEmailView = (AutoCompleteTextView) findViewById (R.id.email); mPasswordView = (EditText) findViewById (R.id.password); Bouton mEmailSignInButton = (Bouton) findViewById (R.id.email_sign_in_button); mEmailSignInButton.setOnClickListener (nouveau OnClickListener () { @Override public void onClick (Voir vue) { // exemple de code, interface exemple presenter.login (mEmailView.getText () toString (), mPasswordView.getText () toString () ..); } }); } @Override onLoginSucc public void () { // Connexion Succ showtoast ( "Connexion réussie"); } }Résumé: Ce qui précède est beaucoup de cadre pour atteindre le MVP, MVP pour leur propre bien.
Votre approbation, j'insiste sur le pouvoir de mettre à jour le blog, si trouver utile, s'il vous plaît signaler une louange, merci.
Avant de faire quoi que ce soit bon devra personnaliser la direction de l'apprentissage ne fait pas exception, mettre la fin du dernier texte cadre d'apprentissage Andrews d'esprit, pour tout le monde d'apprendre une direction, s'il vous plaît accepter mon cadeau.
Accédez gratuitement à Android données d'ordre élevé, plus le groupe: 185873940
Accédez gratuitement à Android données d'ordre élevé, plus le groupe: 185873940
Pour le matériel d'apprentissage plus étude détaillée esprit Andrews Andrews carte et ordre supérieur libre de préoccupations type + réponse privée lettre « données Android » pour recevoir!