您的位置:首页 > 理论基础 > 计算机网络

基于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…



然后在新打开的窗口中搜索GsonFormat,点击右侧绿色按钮就可以下载安装了,安装完需要重启下studio,就可以用了。



它的用法也很简单,比如你先建立一个新的空类取名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 android gson解析