免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
一步一步帶你認(rèn)識(shí) MVP+Retrofit+Rxjava 并封裝(一)

MVP 舉例(附圖)

有一家早餐店,他們家賣包子、饅頭、油條、粥等等這些東西,他們需要用到最重要的東西是面粉(原材料:大米),每次早餐店老板都從一家面粉店(大米店)訂購(gòu),而這些大米都是面粉店老板去農(nóng)民伯伯那里收購(gòu)的。在這個(gè)小例子當(dāng)中,農(nóng)民伯伯的任務(wù)就是生產(chǎn)出大米,這其實(shí)就相當(dāng)于 MVP 模式中的Model,大米就是實(shí)體,生產(chǎn)大米就是業(yè)務(wù)的邏輯;面粉店老板負(fù)責(zé)收購(gòu)大米然后加工成面粉,這其實(shí)就相當(dāng)于 MVP 模式中的 Presenter,負(fù)責(zé)完成農(nóng)民伯伯和早餐店老板這兩邊的間接交易;最后早餐店老板的任務(wù)就是負(fù)責(zé)將面粉做成各種各樣的早餐供大家享用,這其實(shí)就相當(dāng)于 MVP 模式中的 View,負(fù)責(zé)將面粉做成各種各樣的食物呈現(xiàn)在大家眼前。好了,相信通過(guò)這個(gè)栗子大家應(yīng)該對(duì)MVP模式有一定的了解了,下面來(lái)看一張圖:

代碼編寫(步驟)

(1)、

首先我們來(lái)看一下 Model,這部分我理解的就是數(shù)據(jù)獲得的地方,換句話說(shuō)就是進(jìn)行網(wǎng)絡(luò)請(qǐng)求的地方(或者本地?cái)?shù)據(jù)的獲?。?,這里我寫了一個(gè) Base類,將所有的 Model 請(qǐng)求數(shù)據(jù)相同的部分都放到了一起:

public class BaseModel extends BaseRetrofit {

   private static final String TAG = "BaseModel";

   protected CygApi mServletApi;   //所有的注解接口

   protected Map<String, String> mParams = new HashMap<>();

   public BaseModel() {
       super();
       mServletApi = mRetrofit.create(CygApi.class);
   }

   //獲取公共參數(shù)
   @Override
   protected Map<String, String> getCommonMap() {
       Map<String, String> commonMap = new HashMap<>();
       commonMap.put("user_id", String.valueOf(UserDao.getInstance().getUserId()));
       commonMap.put("token", String.valueOf(UserDao.getInstance().getToken()));
       return commonMap;
   }

   //添加一個(gè)參數(shù)
   protected void addParams(String key, String value) {
       if (TextUtils.isEmpty(key)) {
           Log.e(TAG, "the key is null");
           return;
       }
       mParams.put(key, value);
   }

   //添加多個(gè)參數(shù)
   protected void addParams(Map<String, String> params) {
       if (null == params) {
           Log.e(TAG, "the map is null");
           return;
       }
       mParams.putAll(params);
   }
}

這里網(wǎng)絡(luò)請(qǐng)求用的是 Retrofit+RxJava,這一部分我打算放到下一篇再講,在這個(gè) Base 類里面主要添加了公共參數(shù)和添加普通參數(shù)。來(lái)看看一個(gè)登錄的 Model

public class LoginModel extends BaseModel {

   public static LoginModel getInstance() {
       return getPresent(LoginModel.class);
   }

   public void execute(String phone, String password, Observer<User>     observer) {
       addParams("username", phone);
       addParams("password", password);
       Observable observable = mServletApi.getUserInfo(mParams).map(new HttpFunction());
       toSubscribe(observable, observer);
   }
}

(2)

這里我是用的單例模式(其實(shí)我也不知道這樣寫單例會(huì)不會(huì)有錯(cuò),用類去實(shí)例化一個(gè)對(duì)象>_<我覺(jué)得沒(méi)啥問(wèn)題,哈哈哈),然后execute方法就是進(jìn)行網(wǎng)絡(luò)請(qǐng)求了,在Presenter中調(diào)用這個(gè)方法就行了。然后我們來(lái)看一下BasePresenter

public class BasePresenter<VIEW> {

   private WeakReference<VIEW> mViews;

   protected void attachView(VIEW view) {
       mViews = new WeakReference<VIEW>(view);
   }

   protected VIEW getView() {
       return isViewAttached() ? mViews.get() : null;
   }

   private boolean isViewAttached() {
       return null != mViews && null != mViews.get();
   }

   protected void detachView() {
       if (null != mViews) {
           mViews.clear();
           mViews = null;
       }
   }
}

在 BasePresenter 里面我只是關(guān)注了 View,按照 MVP 模式的理解,我們應(yīng)該在這個(gè)里面同時(shí)關(guān)注 View 和 Model,確實(shí),很多 demo 都是這樣干的,但是LZ前面是用的單例來(lái)寫 Model,所以在 BasePresenter 里面就暫時(shí)先關(guān)注 View,還有一點(diǎn)需要說(shuō)明的是,這里對(duì) View 使用的弱引用,我們都知道 View 通常來(lái)說(shuō)都是很大只的存在,為了防止內(nèi)存泄漏,使用弱引用來(lái)及時(shí)釋放內(nèi)存。來(lái)看看一個(gè)登錄的 LoginPresenter

public class LoginPresenter extends BasePresenter<LoginView<User>> {

   public LoginPresenter(LoginView<User> loginView) {
       attachView(loginView);
   }

   public void getUserInfo(BaseImpl baseImpl) {
       LoginModel.getInstance().execute(getView().getUserName(), getView().getPassword(), new CygBaseObserver<User>(baseImpl, "正在登錄") {
           @Override
           protected void onBaseNext(User data) {
               UserInfo userInfo = new UserInfo();
               userInfo.setId(data.getId());
               userInfo.setUsername(getView().getUserName());
               userInfo.setToken(data.getToken());
               UserDao.getInstance().deleteAll(UserInfo.class);
               UserDao.getInstance().insertObject(userInfo);
               getView().onRequestSuccessData(data);
           }
       });
   }

   public void toMainActivity(Activity activity) {
       activity.startActivity(new Intent(activity, MainActivity.class));
   }
}

(3)、

在登錄的 LoginPresenter 中調(diào)用 LoginModel 進(jìn)行網(wǎng)絡(luò)請(qǐng)求,只返回一個(gè)成功的回調(diào),失敗的回調(diào)我們?cè)趦?nèi)部處理掉了,然后在回調(diào)成功之后做相應(yīng)的數(shù)據(jù)操作(該回調(diào)給 View的就回調(diào)給 View,該存本地的就存本地)。然后來(lái)看看我們的 View

public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginView<User> {

   @BindView(R.id.al_et_user_name)
   TextInputEditText alEtUserName;
   @BindView(R.id.al_et_password)
   TextInputEditText alEtPassword;

   @Override
   protected int layoutRes() {
       return R.layout.activity_login;
   }

   @Override
   protected LoginPresenter createPresenter() {
       return new LoginPresenter(this);
   }

   @Override
   protected void initView() {

   }

   @Override
   public String getUserName() {
       return alEtUserName.getText().toString().trim();
   }

   @Override
   public String getPassword() {
       return alEtPassword.getText().toString().trim();
   }

   @OnClick(R.id.al_btn_login)
   public void onViewClicked() {
       if (TextUtils.isEmpty(getUserName())) {
           alEtPassword.setError("用戶名不能為空");
           return;
       }
       if (TextUtils.isEmpty(getPassword())) {
           alEtPassword.setError("密碼不能為空");
           return;
       }
       mPresenter.getUserInfo(this);
   }

   @Override
   public void onBackPressed() {
       super.onBackPressed();
       moveTaskToBack(true);
   }

   @Override
   public void onRequestSuccessData(User data) {
       mPresenter.toMainActivity(this);
   }
}

View中,就是初始化Presenter,然后各種調(diào)Presenter中的方法,這里本來(lái)是可以在Presenter中直接調(diào)用toMainActivity()方法的,為了演示成功回調(diào)之后再回調(diào)給View,這里我就多做了一步操作。好了,接下來(lái)我們來(lái)看看接口:

public interface BaseRequestContract<T> {

   void onRequestSuccessData(T data);

}

這里寫了一個(gè)Base接口,由于大多時(shí)候我們只關(guān)注成功的回調(diào)數(shù)據(jù),這里我也只寫了一個(gè)成功回調(diào)的方法(如果你有其他的需求,你可以在這里加一些公共的方法),如果你有需要的話你可以在子類中寫錯(cuò)誤回調(diào)的接口,接著我們來(lái)看看登錄的接口有哪些方法:

public interface LoginView<T> extends BaseRequestContract<T>{

   String getUserName();

   String getPassword();

}

這里我需要獲得用戶的輸入信息,所以只簡(jiǎn)單定義了兩個(gè)方法用來(lái)獲取用戶名和密碼。到這里我們的MVP模式就簡(jiǎn)單封裝的差不多了,接下來(lái)我們來(lái)看一下最終的效果吧:

這里用eclipse+tomcat+mysql簡(jiǎn)單寫了一個(gè)登錄接口,這一部分LZ在之前的博客中有詳細(xì)講解,如有興趣,請(qǐng)移步:

android開(kāi)發(fā)怎么少的了后端(上)

android開(kāi)發(fā)怎么少的了后端(中)

android開(kāi)發(fā)怎么少的了后端(下)

好了,MVP 的基本封裝就講到這里,下一節(jié)我們?cè)賮?lái)講一下 Retrofit+Rxjava 的簡(jiǎn)單封裝及使用,這里先奉上代碼:

MVP 主工程代碼 https://github.com/Jakemesdg/MVPDemo

MVP module工程代碼 https://github.com/Jakemesdg/cygmodule

可能很多人就會(huì)問(wèn)了,為什么會(huì)有兩份呢,這里我給大家看看我的項(xiàng)目工程

與之相關(guān)

SmartRecom:一款干貨滿滿,助你進(jìn)階的 App 項(xiàng)目

Android 仿今日頭條的開(kāi)源項(xiàng)目

手把手教你從零開(kāi)始做一個(gè)好看的 APP

關(guān)鍵詞:code小生

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android
極光 IM 構(gòu)建聊天功能
Android 共享參數(shù) SharedPreferences
萬(wàn)能 Activity 重構(gòu)篇(Android)
[asp.net mvc]自定義filter
Apache Shiro實(shí)現(xiàn)單點(diǎn)登錄SSO | 沐風(fēng)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服