基于OKhttp的MVP封装
2017-12-21 20:30
357 查看
高级MVP架构封装演变全过程这篇文章是基于Retrofit 的,写的很好,感兴趣的可以看一下。本文基于上文的思想,做了OKhttp的实现,并指出其中的差异和问题解决。这里只给出最简单的MVP实现,为了不重复造轮子,请大家参考给出的上文,自行封装。
本文接口采用豆瓣公开接口https://api.douban.com/v2/book/search?q=金瓶梅&tag=&start=0&count=1
当我们拿到一个GET接口的时候,首先就是考虑解析,这里给出一个基于GSON的快速解析方法。Android 教你一步步搭建MVP+Retrofit+RxJava网络请求框架
首先是安装GSON的解析插件:GsonFormat
,首先需要在Android Studio中下载,点击左上角菜单栏中的File,然后点击Settings,在弹窗中选择Plugins,然后点击下方的Browse repositories…
![](http://upload-images.jianshu.io/upload_images/3057657-aa502d14b5fd3fb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
然后在新打开的窗口中搜索GsonFormat,点击右侧绿色按钮就可以下载安装了,安装完需要重启下studio,就可以用了。
![](http://upload-images.jianshu.io/upload_images/3057657-2852cb1ed273df1a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
它的用法也很简单,比如你先建立一个新的空类取名Book,然后在里面按Alt+insert,会有个小弹窗选择GsonFormat,之后在弹出的编辑框中拷入在浏览器中请求下来的那一坨东西,然后一直点ok就会自动生成字段,以及set和get方法,一会儿我们用OKhttp请求下来的数据都会保存在这个实体类中,还是挺方便的。
知道了怎么解析数据,也就知道了针对view的接口应该怎么定义了
然后就是我们的model实现网络请求,这里用的是OKhttp的异步方法
然后就是P层,就是V和M中间的管理者
最后就是view层的调用:
这里我们看到,具体在view调用的时候,我们并没有在resultSucess方法里直接对TextView赋值,而是通过主线程的Handler使用message来赋值的。为什么这么做呢?因为它崩了。。。
什么意思呢?Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI。
那我们唯一的UI操作,就是在给TextView赋值的时候,所以就有了我们的上文中的Log,然后我们发现,好像是不在主线程啊。
本文接口采用豆瓣公开接口https://api.douban.com/v2/book/search?q=金瓶梅&tag=&start=0&count=1
当我们拿到一个GET接口的时候,首先就是考虑解析,这里给出一个基于GSON的快速解析方法。Android 教你一步步搭建MVP+Retrofit+RxJava网络请求框架
首先是安装GSON的解析插件:GsonFormat
,首先需要在Android Studio中下载,点击左上角菜单栏中的File,然后点击Settings,在弹窗中选择Plugins,然后点击下方的Browse repositories…
![](http://upload-images.jianshu.io/upload_images/3057657-aa502d14b5fd3fb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
然后在新打开的窗口中搜索GsonFormat,点击右侧绿色按钮就可以下载安装了,安装完需要重启下studio,就可以用了。
![](http://upload-images.jianshu.io/upload_images/3057657-2852cb1ed273df1a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)
它的用法也很简单,比如你先建立一个新的空类取名Book,然后在里面按Alt+insert,会有个小弹窗选择GsonFormat,之后在弹出的编辑框中拷入在浏览器中请求下来的那一坨东西,然后一直点ok就会自动生成字段,以及set和get方法,一会儿我们用OKhttp请求下来的数据都会保存在这个实体类中,还是挺方便的。
知道了怎么解析数据,也就知道了针对view的接口应该怎么定义了
public interface RequestView1 { //请求时展示加载 void requestLoading(); //请求成功 void resultSucess(Book book); //请求失败 void resultFailure(String result); }
然后就是我们的model实现网络请求,这里用的是OKhttp的异步方法
public class RequestMode1 { private static final String BASE_URL = "https://api.douban.com/v2/book/search?q=%E9%87%91%E7%93%B6%E6%A2%85&tag=&start=0&count=1"; public void request(okhttp3.Callback callback) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(BASE_URL).build(); client.newCall(request).enqueue(callback); } }
然后就是P层,就是V和M中间的管理者
public class RequestPresenter1 { private final RequestView1 mRequestView; private final RequestMode1 mRequestMode; public RequestPresenter1(RequestView1 requestView1) { this.mRequestView = requestView1; this.mRequestMode = new RequestMode1(); } public void clickRequest() { mRequestView.requestLoading(); mRequestMode.request(new okhttp3.Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { mRequestView.resultFailure("加载失败"); } @Override public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException { Gson gson = new Gson(); Type type = new TypeToken<Book>() { }.getType(); Book book = gson.fromJson(response.body().string(), type); mRequestView.resultSucess(book); } }); } }
最后就是view层的调用:
public class TestHandlerActivity extends AppCompatActivity implements RequestView1 { TextView textView; RequestPresenter1 presenter1; Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch (msg.what) { case 0: textView.setText(msg.getData().getString("json")); break; case 1: break; } return false; } }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test_handler); Log.e("1234", Thread.currentThread().getName()); textView = (TextView) findViewById(R.id.textView); presenter1 = new RequestPresenter1(this); presenter1.clickRequest(); } @Override public void requestLoading() { textView.setText("正在加载"); } @Override public void resultSucess(Book book) { Log.e("1234", Thread.currentThread( 4000 ).getName()); Message message = new Message(); Bundle bundle = new Bundle(); bundle.putString("json", book.getBooks().get(0).getAlt_title()); message.setData(bundle); message.what = 0; handler.sendMessage(message); } @Override public void resultFailure(String result) { handler.sendEmptyMessage(1); } }
这里我们看到,具体在view调用的时候,我们并没有在resultSucess方法里直接对TextView赋值,而是通过主线程的Handler使用message来赋值的。为什么这么做呢?因为它崩了。。。
`Only the original thread that created a view hierarchy can touch its views
什么意思呢?Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI。
那我们唯一的UI操作,就是在给TextView赋值的时候,所以就有了我们的上文中的Log,然后我们发现,好像是不在主线程啊。
12-21 19:31:51.144 12175-12175/com.test1 E/1234: main 12-21 19:31:53.477 12175-12222/com.test1 E/1234: OkHttp https://api.douban.com/...[/code]
那么,我们刚开始的参考文章中为什么可以这么做呢?因为是使用的Retrofit ,我们知道Retrofit 的优点之一就是可以在subscribe操作之前,指定线程。.subscribeOn(Schedulers.io())//指定Http请求运行在io线程 .observeOn(AndroidSchedulers.mainThread())//指定运行在main线程
人家两行代码就解决了,所以最近RxJava+Retrofit 最近这么流行不是没有原因的。
以上就是针对开头参考文章的基于OKhttp的MVP封装,当然只是基本的封装,其中针对内存的优化,还有解决代码的冗余等,大家可以参考开头文章,自行封装。
相关文章推荐
- 基于MVP架构的OKHttp3的封装
- Android——MVP架构OkHttp的二次封装以及RecyclerView的使用
- MVP模式+OKhttp的封装请求数据
- fastokhttp是基于okhttp-3.8.1.jar、okio-1.13.0.jar深度封装的OkHttp网络框架解读
- 基于鸿洋okhttp封装工具类okhttputils 返回数据回调封装
- 优雅设计封装基于Okhttp3的网络框架(六):HttpHeader接口设计实现 及 Response、Request封装实现
- 【Android架构】基于MVP模式的Retrofit2+RXjava封装(一)
- 基于Retrofit、OkHttp、Gson封装通用网络框架
- 网络请求Okhttp封装加单例加拦截器 结合MVP
- 基于okhttp和RxJava封装的自动重连的WebSocket
- 【Android架构】基于MVP模式的Retrofit2+RXjava封装之文件下载(二)
- 基于OkHttp的封装库TigerOkHttp的使用
- 基于OkHttp和RxJava封装的Socket长连接开源库
- MVP和Retrofit+Rxjava+OkHttp封装结合请求数据
- RxJava+okhttp+Retrofit+Mvp 的封装
- 基于OkHttp Retrofit RxJava 多线程下载。请求、缓存、自动更新.限制队列数.封装库
- 网络新宠:基于MVP由okhttp衍生的Retrofit网络新框架
- 优雅设计封装基于Okhttp3的网络框架(一):Http网络协议与Okhttp3解析
- OKhttp+Retrofit的封装加单例模式MVP实现
- 仿京东APP分类页面(mvp模式+OkHttp封装工具类+拦截器+弱引用回收)