Android Retrofit+Rxjava+MVP三大框架整合
Retrofit的詳解
-
retrofit是基於okhttp的封裝工具類,功能十分豐富.我能力還是有限,在這裡先說下它的使用吧!
簡單使用
-
新增Gradle依賴項
compile 'com.squareup.retrofit2:retrofit:2.1.0'
-
建立Api介面
作為一個get請求的url,並提供一些可變的引數
@GET("yoururl/{neededParameter}") Call<ResponseBody> getParameter(@Path("parameter") String parameter);
這裡的@Path只是為了用後面parameter來代替{neededParameter}這個佔位符
還有其他的例如@Query就是類似於url?parameter=…這種
-
建立retrofit例項
Retrofit retrofit=new Retrofit.Builder() .baseUrl(yourUrl) .addConverterFactory(GsonConventerFactory.create()) .build(); IApimanager apiManager=retrofit.create(IApiManager.class); Call<ResponseBody> call=apiManager.getParameter("parameter"); call.enqueue(new Callback<ResponseBody>(){ @Override public void onResponse(Call<User> call, Response<User> response) { Log.e(TAG, "getParameter:" + response.body()); } @Override public void onFailure(Call<User> call, Throwable t) { Log.e(TAG,t.printStackTrace(); } });
-
Rxjava
-
Rxjava,簡單來說, 它是一種模式, 類似於觀察者模式的這種,但又好像是升級的版本.總的來說,他也是一種簡化非同步操作的庫。
-
我就結合一下我的這個專案給大家講一下RxJava的基本使用吧!
-
RxJava的基本使用
- 相信大家也看到了上面的ApiManager返回的是一個Call型別的, 如果我們要使用RxJava的話, 就應該像下面這樣寫;
@GET("index") rx.Observable<NewList> getNews(@Query("key") String key);
只是把返回值換成了Rxjava 的Observable, 為什麼這麼做呢, 接下來就在Retrofit下做手腳了:
public void getData(String key) { Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constant.URL_NEWS) .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); IApiManager apiManager = retrofit.create(IApiManager.class); apiManager.getNews(key) .subscribeOn(Schedulers.io()) .map(new Func1<NewList, List<News>>() { @Override public List<News> call(NewList newList) { List<News> news = new ArrayList<News>(); for (NewList.ResultBean.DataBean eachNews : newList.getResult().getData()) { News everyNews = new News(); everyNews.setDate(eachNews.getDate()); everyNews.setTitle(eachNews.getTitle()); everyNews.setThumbnail_pic_s(eachNews.getThumbnail_pic_s()); everyNews.setUrl(eachNews.getUrl()); news.add(everyNews); } return news; } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<News>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { Toast.makeText(getActivity(), "網路出了些問題", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } @Override public void onNext(List<News> newses) { mRefreshNewsAdapter.addAll(newses); } }); }
或許你會感到頭疼, 為什麼這麼長一大串啊, 說好的簡潔去了哪裡.
其實, RxJava是邏輯的簡潔, 讓我來給你分析一下吧!
首先是addCallAdapterFactory(RxJavaCallAdapterFactory.create()) ,這個是新增一個RxJava介面卡
然後就是那一大串什麼鬼, getNews(key)後面是什麼鬼, 其實是 getNews返回的一個Obserable型別, 這個Obserable呢, 就是可以被觀察的物件了, 詳情就可以去了解上面那篇文章.
map操作進行了簡單的json資料解析, 而這個操作是進行再子執行緒的io裡, 然後再回到主執行緒, 將資料分別顯示出來.
對於RxJava的我這裡也就用了這麼多, 其實還有很多用法沒有在這裡寫出來, 有興趣的朋友可以去探索上面那篇文章, 寫得真的很適合新手入門的.
MVP
-
什麼是MVP結構?
相信大家應該聽說過什麼是MVC結構(model,view,controller) , 這三個英文單詞簡單的說一下, model(模型)業務邏輯和實體模型, view(檢視)就是佈局檔案, controller(控制器)Activity.
沒錯, 大家入門開始寫的專案, 大多數都是以這種為架構的, 常說的Activity處理一切事物, 導致了一個檔案裡面程式碼幾百行, 甚至上千行, 所以我們要學習MVP結構 , 從而來提高專案的解耦性, 啥是解耦?
就是各個模組的依賴度, 你依賴著你爸媽, 當你長大了, 慢慢獨立了, 解耦性就高了.
好了, 說了那麼多MVC, 換到MVP來, MVP和MVC只是一字之差?
P和C 有什麼區別啊? P-presenter / C-controller
Presenter主要用來完成View和Model的互動, controller是Activity,完成大多數工作.
-
MVC 和 MCP 的區別
這裡引用一下hongyang大佬的圖片, 地址淺談 MVP in Android
-
專案例項
其實大多數用來做登入註冊的demo, 其實整個app用的MVP主要還是在登入註冊, 其他的用了Retrofit和RxJava
首先看看下面的紅色框的檔案
-
建立Model
實體類User
public class User { private String mUserName; private String mPassword; public User(String userName, String password) { mUserName = userName; mPassword = password; } public String getUserName() { return mUserName; } public void setUserName(String userName) { mUserName = userName; } public String getPassword() { return mPassword; } public void setPassword(String password) { mPassword = password; } }
業務邏輯UserModel類
public class UserModel { public void login(final String userName, final String password, final OnLoginListener onLoginListener){ new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } if("ThatNight".equals(userName)&&"123".equals(password)){ User user=new User(userName,password); onLoginListener.loginSuccess(user); }else{ onLoginListener.loginFailed(); } } }).start(); } }
登入監聽介面OnLoginListener
public interface OnLoginListener { void loginSuccess(User user); void loginFailed(); }
-
建立View
登入介面ILoginView,主要是寫一些在UI操作的方法
public interface ILoginView { void loginSuccess(); void loginFailed(); void setPbVisiable(int visiable); void showText(String text); String getUserName(); String getPassword(); }
然後LoginActivity實現ILoginView介面, 並實現方法
public class LoginActivity extends AppCompatActivity implements ILoginView { @InjectView(R.id.et_login_name) EditText mEtLoginName; @InjectView(R.id.et_login_pwd) EditText mEtLoginPwd; @InjectView(R.id.btn_login_login) Button mBtnLoginLogin; @InjectView(R.id.progressBar) ProgressBar mProgressBar; private LoginPresenter mLoginPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); ButterKnife.inject(this); init(); } private void init() { mLoginPresenter = new LoginPresenter(this); } @Override public void loginSuccess() { setPbVisiable(View.INVISIBLE); Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } @Override public void loginFailed() { Toast.makeText(this, "登入失敗!", Toast.LENGTH_SHORT).show(); } @Override public void setPbVisiable(int visiable) { mProgressBar.setVisibility(visiable); if (visiable == View.VISIBLE) { mBtnLoginLogin.setEnabled(false); } else { mBtnLoginLogin.setEnabled(true); } } @Override public void showText(String text) { Toast.makeText(this, text + " 登入成功!", Toast.LENGTH_SHORT).show(); } @Override public String getUserName() { return mEtLoginName.getText().toString(); } @Override public String getPassword() { return mEtLoginPwd.getText().toString(); } @OnClick(R.id.btn_login_login) public void onClick() { } }
-
建立Presenter類
主要是寫一個方法讓LoginActivity呼叫, 比如按下登入按鈕就呼叫這裡的login方法.
public class LoginPresenter { private ILoginView mILoginView; private UserModel mUserModel; private Handler mHandler = new Handler(); public LoginPresenter(ILoginView ILoginView) { mILoginView = ILoginView; mUserModel = new UserModel(); } public void login() { mILoginView.setPbVisiable(View.VISIBLE); mUserModel.login(mILoginView.getUserName(), mILoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final User user) { mHandler.post(new Runnable() { @Override public void run() { mILoginView.showText(user.getUserName()); mILoginView.loginSuccess(); } }); } @Override public void loginFailed() { mHandler.post(new Runnable() { @Override public void run() { mILoginView.loginFailed(); } }); } }); } }
效果圖:
-
總結
-
雖然感覺這三大框架的app到處都是, 但是要真正的熟悉裡面的邏輯, 還是需要花費一定時間來拆輪子, 不研究這些原始碼,只會使用是永遠不足夠的, 好好加油!
-
最終效果圖: