在MVP模式下使用OkHttp3

前言

为什么使用okhttp3就不说了,网上有很多资料。也看到过很多关于OkHttp3资料博客等等,有很多内容确实很不错。但有时候就想实现一些小功能,代码却设计得挺复杂的。所以我这里尽量使用最简单的方法实现我们的mvp使用okHttp3。

概述要实现的功能

在MVP模式下使用OkHttp3_第1张图片

  • 通过调用果壳的API,将传送过来的json数据通过GSON获取实例,所以要添加依赖
    compile 'com.google.code.gson:gson:2.8.1'

还要有访问网络权限

    <uses-permission android:name="android.permission.INTERNET">uses-permission>
  • 然后将获得的实例集合中拿出title,并将它显示到自定义RecyclerView的标题,其中RecyclerView可以参考 这里

  • 果壳API返回的JSON数据实例如下:


/**
 *
 {
 "now": "2017-04-05T20:45:50.433517+08:00",
 "ok": true,
 "result": [
 {
 "link_v2_sync_img": "http://jingxuan.guokr.com/pick/v2/81717/sync/",
 "source_name": "天了噜!",
 "video_url": "",
 "current_user_has_collected": false,
 "likings_count": 5,
 "images": [
 "http://1.im.guokr.com/12kEBJJ68jxKvIS7tH0w-5aOVdbWe5cr-g915ctFd12AAgAAtQEAAEpQ.jpg?imageView2/1/w/480/h/327",
 "http://2.im.guokr.com/5UfOz7iKuTCf6CywMRri0dz9z-ZBHB5CfqDr4ISt0dKUAgAADwEAAEpQ.jpg?imageView2/1/w/480/h/197",
 "http://2.im.guokr.com/Cp-1LlznSmBkA1zcQcbuUiBcoB8UV6H9HrIA6T4_5l6AAgAA-gEAAEpQ.jpg?imageView2/1/w/480/h/379"
 ],
 "video_duration": null,
 "id": 81717,
 "category": "humanities",
 "style": "article",
 "title": "如果人类灭绝了,该不该被复活?",
 "source_data": {
 "image": "http://2.im.guokr.com/r8PINb_RG_niPP_rsxxvHLK7HmQE9i1NZD6pWV_0VDKgAAAAoAAAAFBO.png?imageView2/1/w/160/h/160",
 "summary": "吸走你的无聊时间!",
 "id": 52,
 "key": "天了噜!",
 "title": "天了噜!"
 },
 "headline_img_tb": "http://1.im.guokr.com/12kEBJJ68jxKvIS7tH0w-5aOVdbWe5cr-g915ctFd12AAgAAtQEAAEpQ.jpg?imageView2/1/w/288/h/196",
 "link_v2": "http://jingxuan.guokr.com/pick/v2/81717/",
 "date_picked": 1491386460,
 "is_top": false,
 "link": "http://jingxuan.guokr.com/pick/81717/",
 "headline_img": "http://1.im.guokr.com/12kEBJJ68jxKvIS7tH0w-5aOVdbWe5cr-g915ctFd12AAgAAtQEAAEpQ.jpg",
 "replies_count": 2,
 "current_user_has_liked": false,
 "page_source": "http://jingxuan.guokr.com/pick/81717/?ad=1",
 "author": "春天来了啊",
 "summary": "如果人类灭绝了,该不该被复活?对这个问题,每个人应该都有自己的想法。 3月29日,纽约,美国自然史博物馆(AMNH)举行了艾萨克·",
 "source": "group",
 "reply_root_id": 779351,
 "date_created": 1491201409
 },
 ]
 }
 */

实现步骤

首先看一下需要建的类
在MVP模式下使用OkHttp3_第2张图片

第一步

根据API返回的数据写出News的实例

API

public class Api
{
    // 获取果壳精选的文章列表,通过组合相应的参数成为完整的url
    // Guokr handpick articles. make complete url by combining params
    public static final String GUOKR_ARTICLES = "http://apis.guokr.com/handpick/article.json?retrieve_type=by_since&category=all&limit=25&ad=1";
}

News:要写的很多,看懂直接copy就好


public class News {
    private String now;
    private boolean ok;
    private ArrayList result;
    public String getNow() {
        return now;
    }
    public void setNow(String now) {
        this.now = now;
    }
    public boolean isOk() {
        return ok;
    }
    public void setOk(boolean ok) {
        this.ok = ok;
    }
    public ArrayList getResult() {
        return result;
    }
    public void setResult(ArrayList result) {
        this.result = result;
    }
    public  class result {
        private String link_v2_sync_img;
        private String source_name;
        private String video_url;
        private boolean current_user_has_collected;
        private int likings_count;
        private String[] images;
        private String video_duration;
        private int id;
        private String category;
        private String style;
        private String title;
        private source_data source_data;
        private String headline_img_tb;
        private String link_v2;
        private double date_picked;
        private boolean is_top;
        private String link;
        private String headline_img;
        private int replies_count;
        private boolean current_user_has_liked;
        private String page_source;
        private String author;
        private String summary;
        private String source;
        private int reply_root_id;
        private double date_created;

        public String getLink_v2_sync_img() {
            return link_v2_sync_img;
        }
        public void setLink_v2_sync_img(String link_v2_sync_img) {
            this.link_v2_sync_img = link_v2_sync_img;
        }
        public String getSource_name() {
            return source_name;
        }
        public void setSource_name(String source_name) {
            this.source_name = source_name;
        }
        public String getVideo_url() {
            return video_url;
        }
        public void setVideo_url(String video_url) {
            this.video_url = video_url;
        }
        public boolean isCurrent_user_has_collected() {
            return current_user_has_collected;
        }
        public void setCurrent_user_has_collected(boolean current_user_has_collected) {
            this.current_user_has_collected = current_user_has_collected;
        }
        public int getLikings_count() {
            return likings_count;
        }
        public void setLikings_count(int likings_count) {
            this.likings_count = likings_count;
        }
        public String[] getImages() {
            return images;
        }
        public void setImages(String[] images) {
            this.images = images;
        }
        public String getVideo_duration() {
            return video_duration;
        }
        public void setVideo_duration(String video_duration) {
            this.video_duration = video_duration;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getCategory() {
            return category;
        }
        public void setCategory(String category) {
            this.category = category;
        }
        public String getStyle() {
            return style;
        }
        public void setStyle(String style) {
            this.style = style;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
        public News.source_data getSource_data() {
            return source_data;
        }
        public void setSource_data(News.source_data source_data) {
            this.source_data = source_data;
        }
        public String getHeadline_img_tb() {
            return headline_img_tb;
        }
        public void setHeadline_img_tb(String headline_img_tb) {
            this.headline_img_tb = headline_img_tb;
        }
        public String getLink_v2() {
            return link_v2;
        }
        public void setLink_v2(String link_v2) {
            this.link_v2 = link_v2;
        }
        public double getDate_picked() {
            return date_picked;
        }
        public void setDate_picked(double date_picked) {
            this.date_picked = date_picked;
        }
        public boolean is_top() {
            return is_top;
        }
        public void setIs_top(boolean is_top) {
            this.is_top = is_top;
        }
        public String getLink() {
            return link;
        }
        public void setLink(String link) {
            this.link = link;
        }
        public String getHeadline_img() {
            return headline_img;
        }
        public void setHeadline_img(String headline_img) {
            this.headline_img = headline_img;
        }
        public int getReplies_count() {
            return replies_count;
        }
        public void setReplies_count(int replies_count) {
            this.replies_count = replies_count;
        }
        public boolean isCurrent_user_has_liked() {
            return current_user_has_liked;
        }
        public void setCurrent_user_has_liked(boolean current_user_has_liked) {
            this.current_user_has_liked = current_user_has_liked;
        }
        public String getPage_source() {
            return page_source;
        }
        public void setPage_source(String page_source) {
            this.page_source = page_source;
        }
        public String getAuthor() {
            return author;
        }
        public void setAuthor(String author) {
            this.author = author;
        }
        public String getSummary() {
            return summary;
        }
        public void setSummary(String summary) {
            this.summary = summary;
        }
        public String getSource() {
            return source;
        }
        public void setSource(String source) {
            this.source = source;
        }
        public int getReply_root_id() {
            return reply_root_id;
        }
        public void setReply_root_id(int reply_root_id) {
            this.reply_root_id = reply_root_id;
        }
        public double getDate_created() {
            return date_created;
        }
        public void setDate_created(double date_created) {
            this.date_created = date_created;
        }
    }
    public class source_data {
        private String image;
        private String summary;
        private int id;
        private String title;

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }

        public String getSummary() {
            return summary;
        }

        public void setSummary(String summary) {
            this.summary = summary;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

}

第二步

获得OkHttpClient单例,网络请求方面一般要求单例,关于单例,可以看这里

OkHttp3

public class OkHttp3 {
    private static OkHttpClient client = new OkHttpClient();
    public static OkHttpClient getClient() {
        return client;
    }
}

然后在Model里面实现get请求和post请求,但这里只用到get请求,还有就是okHttp3自带的Callback非常方便,无须自己定义回调接口,直接在调用的时候就可以收到返回数据

Model


public class Model {
    private static Model instance = new Model();//单例

    public static Model getInstance() {
        return instance;
    }
    public OkHttpClient client = OkHttp3.getClient();



    /**
     * post请求
     * @param address
     * @param callback
     * @param map
     */

    public void post(String address, okhttp3.Callback callback, Map map)
    {
        OkHttpClient client = new OkHttpClient();
        FormBody.Builder builder = new FormBody.Builder();
        if (map!=null)
        {
            for (Map.Entry entry:map.entrySet())
            {
                builder.add(entry.getKey(),entry.getValue());
            }
        }
        FormBody body = builder.build();
        Request request = new Request.Builder()
                .url(address)
                .post(body)
                .build();
        client.newCall(request).enqueue(callback);
    }


    /**
     * post请求
     * @param address
     * @param callback
     */

    public void get(String address, okhttp3.Callback callback)
    {
        OkHttpClient client = new OkHttpClient();
        FormBody.Builder builder = new FormBody.Builder();
        FormBody body = builder.build();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
    }
}

第三步

这一步实现在Presenter中所需的动作,即调用Model中的get方法

    @Override
    public void loadPosts() {
        view.showLoading();
        model = new Model();
        model.get(Api.GUOKR_ARTICLES, new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                view.showError();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseBody = response.body().string();
                Log.d("打印",responseBody);
                News question = gson.fromJson(responseBody, News.class);
                for (News.result re : question.getResult()) {
                    // list.add(re);
                    Log.d("打印标题",re.getTitle());
                    list.add(re);
                }
                view.showResult(list);
            }
        });
        view.stopLoading();
    }

使用了GSON和okhttp3.Callback()就是变得这么精简,这也是我一直推崇的东西

第四步

这一步要在UI界面上操作,之前忽略了在子线程中不能直接操作UI界面被坑了很长时间,为什么网络请求不属于主线程呢?大概因为网络请求容易导致阻塞,所以是子线程的一种。因此,我们在 view.showResult(list)即更新界面时应加入 runOnUiThread,所以MainAcitvity中showResult中应该这样写

    @Override
    public void showResult(final ArrayList list) {
       runOnUiThread(new Runnable() {
            @Override
            public void run() {
                myAdapter.addData(list);
            }
        });
    }

关于Adapter里面的addData怎么就不说了,RecyclerView怎么使用上面也给了链接。

最后

MVP模式还是比较常用的一种模式,这篇文章也是基于这种模式上实现的,想要了解MVP的推荐看这里
本文所用的Demo:http://download.csdn.net/detail/qq_34261214/9910206
个人博客:https://dream97.github.io/

你可能感兴趣的:(Android开发记录)