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
- Android开源项目LifeUtil 之网络请求
- Android开源项目LifeUtil
- Android开源项目LifeUtil 之Base类
- Android开源项目LifeUtil 之数据展示
- ANDROID开源项目推荐之网络请求
- Android开源项目之(网络请求框架)
- Android项目之网络请求
- Android开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- ANDROID开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- Android开源项目推荐之「网络请求哪家强」
- 优雅的构建Android项目之RxAndroid+Retrofit网络请求
- 【Android 开源系列】之网络请求框架
- Android开发之网络请求
- 4.17
- 5.Springboot 之 单元测试
- 1016. 部分A+B
- CTF 伪加密
- 日期类
- Android开源项目LifeUtil 之网络请求
- 单链表冒泡排序
- GDOI2017模拟 第二场(4.15~4.17)
- 1016. 部分A+B (这个版本仅供讨论)
- Android架构设计02-网络请求框架(一)
- ACM-动态规划6-登山
- Android 设备WebView远程调试
- KVO 观察者模式
- java 自旋锁