Android开源项目LifeUtil 之网络请求

来源:互联网 发布:java命令行参数输入 编辑:程序博客网 时间:2024/06/05 15:35

在LifeUtil项目中,我们的“阅读”模块和“图片”模块都需要请求网络数据。
效果如下图:
这里写图片描述

无论是图片展示还是右边的文字项,都得获取网络数据。所以,有必要单独拿出来讲讲。这里先声明一下,阅读和图片模块中除美女专题外数据均是用Jsoup去网上爬取,(仅做学习交流,如有侵权,立即删除)。
这里的数据获取有两种方式:

  • “图片”模块中的美女专题,我在项目中使用了RxJava+Retofit +Gson解析。然后使用Glide加载展示图片。

  • “其他的”,使用Jsoup爬取。

一、Gson解析Json
下面是RxJava+Retrofit+Gson解析网络数据的代码模板:

  • Retofit管理类

封装了Retrofit,并以Gson来解析Json格式的数据。

public class RetrofitManager {    private static RetrofitManager instance;    private static Retrofit retrofit;    private static Gson gson;    private static String cookie = "";    private static final String BASE_URL ="";    public RetrofitManager() {        retrofit = new Retrofit.Builder()                .baseUrl(BASE_URL)                .client(httpClient())                .addConverterFactory(GsonConverterFactory.create(gson()))                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                .build();    }    public static void reset() {        instance = null;    }    public <T> T create(Class<T> service) {        return retrofit.create(service);    }    public static RetrofitManager getInstance() {        if (instance == null) {            synchronized (RetrofitManager.class) {                instance = new RetrofitManager();            }        }        return instance;    }    private static OkHttpClient httpClient() {        return new OkHttpClient.Builder()                .connectTimeout(15, TimeUnit.SECONDS)                .readTimeout(20, TimeUnit.SECONDS)                .writeTimeout(20, TimeUnit.SECONDS)                .retryOnConnectionFailure(true)                .build();    }    private  Gson gson() {        if (gson == null) {            synchronized (RetrofitManager.class) {                gson = new GsonBuilder().setLenient().create();            }        }        return gson;    }}
  • API工厂类
    封装所有的API,并以单例模式返回。
public class ApiFactory {    //用于同步处理    protected static final Object monitor = new Object();    private static GirlsController girlsController;    public static GirlsController getGirlsController(){        if(girlsController==null){            synchronized (monitor){                girlsController =RetrofitManager.getInstance().create(GirlsController.class);            }        }        return girlsController;    }}
  • 具体Retrofit数据接口实现(这里是美女专题的接口)
public interface GirlsController {    @GET ("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/6/{page}")    Observable<BaseGankResponse<List<Girl>>> getGank(@Path("page") String page);    @GET ("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/10/{page}")    Observable<ResponseBody> getGankBody(@Path("page") String page);}

上面三个步骤创建好了之后,就可以在MainActivity中使用RxJava调用,实现网络数据的请求了。
代码如下:

 public void getGank(int curPage) {        ApiFactory.getGirlsController().getGank(curPage + "").subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Subscriber<BaseGankResponse<List<Girl>>>() {                    @Override                    public void onCompleted() {                        ((MainActivity) getActivity()).showSnack("加载完成");                        binding.swipRefreshLayout.setRefreshing(false);                    }                    @Override                    public void onError(Throwable e) {                        ((MainActivity) getActivity()).showSnack("加载失败");                        binding.swipRefreshLayout.setRefreshing(false);                    }                    @Override                    public void onNext(BaseGankResponse<List<Girl>> response) {                        for (Girl girl : response.datas) {                            if (girl.getHeight() == 0) {                                girl.setHeight((new Random().nextInt(100)) + 500);                            }                        }                        //Adapter更新数据                        if (isRefresh) {                            adapter.setNewData(response.datas);                        } else {                            adapter.addDatas(response.datas);                        }                    }                });    }

当然,我们不能把Girl类忘掉的,否则Gson是解析不出来数据的。

GirlBean类

public class Girl implements Serializable {    private String url;    @SerializedName("who")    String name ;    @SerializedName("desc")    String date;     public Girl(String url) {        this.url = url;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getDate() {        return date;    }    public void setDate(String date) {        this.date = date;    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }}

这样,数据请求就完成了。然后在Adapter中使用Glide加载显示图片就ok了。可以看到使用RxJava很方便的帮我们解决了异步的问题,而不用在数据加载完成后使用Handler机制切换回到主线程进行UI操作。

二、Jsoup爬取网页

 /**     * 从服务器上获取数据     */    public void getDataFromServer() {        final String url =  getArguments().getString("url");        subscription = Observable.just(url).subscribeOn(Schedulers.io()).map(new Func1<String, List<PhotoItem>>() {            @Override            public List<PhotoItem> call(String s) {                List<PhotoItem> photoList = new ArrayList<>();                try {                    Document doc = Jsoup.connect(url).timeout(5000).get();                    Element element = doc.select("div.wrap").last();                    Elements items = element.select("div.kboxgrid");                    for (Element ele : items) {                        PhotoItem item = new PhotoItem();                        Element content = ele.select("div.boxgrid").first();                        Element info = ele.select("div.citemqt").first();                        String name = info.select("a").first().text();                        String imgUrl = content.select("img").first().attr("src");                        String from =content.select("a").first().attr("href");                        String date =info.select("a").last().text();                        item.setName(name);                        item.setImg(imgUrl);                        item.setFrom(from);                        item.setDate(date);                        photoList.add(item);                    }                } catch (IOException e) {                    e.printStackTrace();                }                return photoList;            }        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<PhotoItem>>() {            @Override            public void onCompleted() {                binding.swipeRefreshLayout.setRefreshing(false);                ((MainActivity) getActivity()).showSnack("加载完成");            }            @Override            public void onError(Throwable e) {                ((MainActivity) getActivity()).showSnack("加载失败");                binding.swipeRefreshLayout.setRefreshing(false);            }            @Override            public void onNext(List<PhotoItem> list) {                adapter.setNewData(list);            }        });    }

这里主要是在map方法中将url使用Jsoup解析html,然后获取到我们所需的类,设置到Adpater中就搞定了。

上一篇:Android开源项目LifeUtil 之Base类
下一篇:Android开源项目LifeUtil 之数据展示

1 0
原创粉丝点击