"Cadre Android" basé en mode MVP Retrofit2 + package RXjava

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!

Un examen plus approfondi « le plus comme un robot humain », le responsable production Sophia année prochaine
Précédent
« Je suis très bon » Ming Ming Yu conseillé de réfléchir à deux fois d'acheter une maison Mingzhe veulent des investissements Nuekuan était contre
Prochain
En fonction de la scène SD, licorne et nouveau numéro Zeon: module de commande de jeu
Illustré 190417 Long Time No See divinité Cui Xiuying est prise la participation du public à des événements de charité
Cadre cadre Android série DisplayManagerService (a)
007 série de films "Goldfinger 007" actrice Tan Niya · Ma Leite est mort à l'âge de 77 ans
module de commande de lecture: gratuit et illimité dimension haut, le plus beau libre?
190,417 Deng Lun ancien lycée Sentimental beau soleil beau Shots
la plupart des bovins gros services de marketing de recrutement de la Chine plate-forme, vous avez le courage de venir!
suivi de l'oeil devient une des sources d'entrée auxiliaires, autres que la souris, le clavier
framework de développement rapide Android, la bibliothèque de la fondation, la bibliothèque de styles, composants, intégration des composants
Résumé de la célèbre fosse d'escalade du défi du rouge à lèvres d'Android Douyin
Après Wanda, qui est le roi du prochain Cinémas
Module de jeu de contrôle: seul survivant, le mélange de type sol et correspond Zagu