[Android入门]从零构建Android app之天气——5.设计网络请求底层架构
来源:互联网 发布:公共科目大数据贵州 编辑:程序博客网 时间:2024/05/21 14:08
经过前面4篇构建,我们的App已经初具框架了,现在可以开始按照框架逐步的添加具体内容了。本篇我们将一起使用Retrofit+OkHttpClient(Retrofit+OkHttp3的使用)完成底层网络请求架构。
数据来源
天气数据来源是从聚合数据申请的一个免费天气接口,这个平台上免费数据挺多的,可以看看聚合数据链接。
分析接口及数据结构
数据请求
聚合数据的接口开始都是以http://op.juhe.cn/ 开始的,考虑到后期还会用到聚合数据的其他接口,所以我们的第一个网络Client的BaseUrl就设置为http://op.juhe.cn/ 。
必要的接口参数为有两个,请求时上传它两就够了。详细使用方法在聚合数据上看(这点还是很贴心的):
String cityname;String key;
根据以上的接口分析,我们已经可以编写出符合要求的网络请求底层了。
再次说明,以下是使用Retrofit+OkHttpClient 完成的,具体使用方法参考:Retrofit+OkHttp3的使用。
- Retrofit生成网络访问客户端需要的接口Api。
public interface Api {//第二个参数为我们在聚合数据申请的key,每次访问时携带 @GET("onebox/weather/query") Call<BaseWeatherResponse<Result>> getWeatherData(@Query("cityname") String cityName, @Query("key") String key);}
- 生成网络访问客户端。
public class ApiClient { public static final Api api; private static String BASE_WEATHER_URL = "http://op.juhe.cn/";//该类创建时就实例化Api static { api = getRetrofit().create(Api.class); }//创建Retrofit对象 private static Retrofit getRetrofit() { OkHttpClient client = getClient(); //见下 //Json数据解析使用Gson GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(GsonUtils.newInstance()); return new Retrofit.Builder() .baseUrl(BASE_WEATHER_URL) .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //异步任务处理使用RxJava .client(client) //设置OkHttpClient .build(); } @NonNull private static OkHttpClient getClient() { //添加拦截器,这个拦截器可以在添加一些header信息,实际开发中我们可能需要携带很多信息进行请求 Interceptor interceptor = chain -> { Request request = chain.request(); return chain.proceed(addRequestHeader(request)); }; // 是一个拦截器,用于输出网络请求和结果的 Log, // 可以配置 level 为 BASIC / HEADERS / BODY,都很好理解,对应的是原来 retrofit 的 set log level 方法,现在 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel( BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE); return new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .addNetworkInterceptor(interceptor) .retryOnConnectionFailure(true) //允许自动重新链接 .build(); }//添加Header信息 private synchronized static Request addRequestHeader(Request request) { Request.Builder rq = request.newBuilder(); if (ChiceApplication.getAppContext() != null) { String imei = AppUtils.getImei(ChiceApplication.getAppContext()); if (imei != null) { rq.addHeader("imei", imei); LogUtils.v("imei: " + imei); } String imsi = AppUtils.getImsi(ChiceApplication.getAppContext()); if (imsi != null) { rq.addHeader("imsi", imsi); LogUtils.v("imsi: " + imsi); } String networkType = NetworkUtils.getCurrentNetworkType(ChiceApplication.getAppContext()); if (networkType != null) { rq.addHeader("net", networkType); LogUtils.e("net: " + networkType); } } String sdk = AppUtils.getSdkVersion(); rq.addHeader("cv", sdk); LogUtils.e("cv: " + sdk); String os = "Android"; rq.addHeader("os", os); LogUtils.e("os: " + os); String tc = AppUtils.getChannelName(); rq.addHeader("tc", tc); LogUtils.e("tc: " + tc); String dt = AppUtils.getModelVersion(); rq.addHeader("dt", dt); LogUtils.e("dt: " + dt); return rq.build(); }//使用这个静态方法进行请求,通过我们自己编写的回调获取请求结果。//请求数据时,调用这个方法,在回调接口中获取数据 public static void getWeatherData(OnSuccessCallback<Result> onSuccessCallback, OnFailureCallback<Result> onFailureCallback) { requestData(api.getWeatherData("cityname", "key"), onSuccessCallback, onFailureCallback); } private static <T> void requestData(Call<BaseWeatherResponse<T>> call, OnSuccessCallback<T> onSuccessCallback, OnFailureCallback<T> onFailureCallback) { //异步执行请求 call.enqueue(new Callback<BaseWeatherResponse<T>>() { @Override public void onResponse(Call<BaseWeatherResponse<T>> call, Response<BaseWeatherResponse<T>> response) { if (response.isSuccessful() && response.body() != null) { if (onSuccessCallback != null) { //请求成功时,通过该回调将数据暴露给调用处 onSuccessCallback.onSuccess(response.body().getResult()); } } } @Override public void onFailure(Call<BaseWeatherResponse<T>> call, Throwable t) { } }); }}
- 用于暴露请求结果的回调
public interface OnSuccessCallback<T> { void onSuccess(@Nullable T t);}public interface OnFailureCallback<T> { void onFailure(@Nullable T t);}
数据解析
请求的数据结构可以到聚合数据看一下,这里我要说明的是,由于它这个接口返回的数据相对复杂,在使用GsonFormat生成实体类后,会有重名报错,并且看起来十分杂乱,所以我把该数据结构进行了拆分。详细的请移步GitHub查看。
拆分的好处是结构清晰,方便我们查看和修改。
看看怎么使用
ApiClient.getWeatherData(data -> { //在请求成功的回调中获取并操作数据 LogUtils.e("结果 = " + GsonUtils.getSingleInstance().toJson(data)); }, thr -> {});
以北京为例,下面是请求结果:
怎么样?使用起来十分简洁吧。
项目地址GitHub
0 0
- [Android入门]从零构建Android app之天气——5.设计网络请求底层架构
- [Android入门]从零构建Android app之天气——4.App初始化、设计主要结构、封装工具类
- [Android入门]从零构建Android app之天气——1.创建项目
- [Android入门]从零构建Android app之天气——2.托管项目到GitHub
- [Android入门]从零构建Android app之天气——3.配置项目环境
- [Android入门]从零构建Android app之天气——6.app图标和欢迎页
- [Android入门]从零构建Android app之天气——7.在欢迎页加载并缓存数据
- Android网络请求的架构之路
- Android----网络底层框架设计
- Android App架构设计
- Android App架构设计
- Android APP架构设计
- Android App 架构设计
- Java Http网络请求HttpURLConnection应用之【Android网络请求框架底层剖析】
- 【Android的从零单排开发日记】之入门篇(十六)——Android的动画效果
- 【Android的从零单排开发日记】之入门篇(十六)——Android的动画效果
- Android架构设计02-网络请求框架(一)
- Android应用架构之MVP--->天气实例
- [LeetCode]Surrounded Regions
- springmvc中上传下载解决乱码的问题
- Java Reflect JDK动态代理
- remap函数用法示例
- 【android开发】Google RenderScript文档【一】
- [Android入门]从零构建Android app之天气——5.设计网络请求底层架构
- geany配置
- 实现多种重映射综合示例
- 学习笔记之DNS配置(视图,日志,动态DNS)
- POJ 1018 Communication System(贪心+优化)
- 一个优秀的Android应用从建项目开始
- 帝国cms常见问题汇总整理
- 仿射变换综合示例
- Docker的安装,配置,更新和卸载