Android从零开搞系列:网络框架系列(1)OkHttp+可测试的服务器URL+Gson分析(上)
2016-12-15 22:03
405 查看
OkHttp的基本使用
转载请注意:http://blog.csdn.net/wjzj000/article/details/53677706本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
之前写过一篇相关的内容,比较粗糙,但是简单粗暴:
http://blog.csdn.net/wjzj000/article/details/52562674
从零系列,我自己真正开始记录总结技术的起点。这里边的分析都是我安安静静一点点看,一点点梳理记录的。希望给我带来帮助的同时,能传播一些爱与正义。
服务器绑定了域名
因此以前URL前面部分:http://120.27.4.196:8080/
需要更换成http://www.ohonor.xyz/
最简单的GET请求
这里使用的URL是我自己写的一个简单的Servlet类:http://120.27.4.196:8080/test/servlet/ShowServlet
正常返回的数据是:[{“temperature”:”123”,”humidity”:”41234”}]
这个服务器程序跑在我的阿里云服务器上,所以只要我还交着钱…这个URL随时可以拿来测试。
让我们来看一下请求代码
我知道这里肯定会有很多的问题和疑惑。因为最开始的我,也是如此。
所以我会把我的最初的一些疑惑,穿插着写在其中。
OkHttpClient okHttpClient=new OkHttpClient(); /** * 很明显这里是一个建造者模式,所以我们只需要调用Builder这个静态内部 * 类中的特定方法。比如url()这个方法,然后我们的参数就会被设置到Builder * 之中,然后通过调用build()方法,将Builder中的值赋值给Request,然后 * 返回Request对象。 */ Request request=new Request.Builder() .url("http://120.27.4.196:8080/test/servlet/ShowServlet") //.header("User-Agent", "XXXXXXXXX") //.addHeader("Accept", "XXXXXXXXXX") /** * 如上文所写,我们可以给Http请求添加头信息。 * header和addHeader的区别在于: * header内部调用了清空头信息的方法,也就是说用于初始化。 * 而addHeader就是单纯的添加头信息。 */ .build(); Call call=okHttpClient.newCall(request); //enqueue()方法是在子线程进行的,因此回调之中我们要进行异步操作。 call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { //请求失败的回调 } @Override public void onResponse(final Response response) throws IOException { //请求成功的回调。 /** * 在这里我们可以通过返回值response来转换我们想要的值: * 字符串,可以通过response.body().string()获取; * 二进制字节数组,可以通过response.body().bytes(); * 输入流,可以通过response.body().byteStream() */ //这个方法是Activity中的方法 /** * 我们查看源码可以发现: * if (Thread.currentThread() != mUiThread) { * mHandler.post(action); * } else { * action.run(); * } * 这里是通过Hanlder机制完成异步操作。 */ runOnUiThread(new Runnable() { @Override public void run() { try { tv_content.setText(response.body().string()); } catch (IOException e) { e.printStackTrace(); } } }); } });
让我们看一下效果
其实没啥好看的,就是在TextView中打印这么一行既然这里我们拿到的是JSON格式,所以关于Json的用法,怎么能少呢。不要着急,往下下下下下看。
疑惑:为什么通过访问URL能拿到数据?
这个问题曾经困扰过我很久。因为我在大学之前对计算机并没有什么兴趣。除了玩游戏以及和那些存在于高中物理复习资料文件夹中,德艺双馨的老师们交流以外。对电脑没有任何了解。
因此我在接触网络请求的时候,真的是一脸懵逼,感觉网络真的是so diao,犹如老树盘根倒挂蜡般冲击着我的灵魂。
扯的有点远,咱们交个闪现先回来。
通过代码我们可以看到,我们传递了一个URL,因此我们得到的数据一定是这个URL的作用。
URL全称:统一资源定位符。它就是浩瀚互联网计算机集群之中某个资源的id。通过它我们就能找到这个资源。而这个URL是我写的一个Servlet类。这个类的作用就是从数据库查询出符合条件的数据,然后输出:
[{“temperature”:”123”,”humidity”:”41234”}]这么简单的一句话。(为了更好的展示,又在数据库中加了2条数据。)
因此当我们访问这个URL的时候,我们拿到的就是这一句话。
这里必须要聊一聊服务器,关于服务器的概念也是一直困扰了我很长时间。直至后来我用我自己的理解方式,能够把这些网络现象解释给自己听。
我们想要访问互联网上的资源,实际上是进程和进程的通讯。也就是说我们用某一个程序去访问另一个程序。而每个程序都对应着端口号。我们就是通过IP地址和端口号来确定想要访问的对象。上文那个链接就可以解释这个问题。120.27.4.196是我的阿里云服务器(这里的服务器其实就是一台计算机。只不过它专门用于提供服务)的IP。但是为什么没有端口号?之前是有的。8080,有些朋友可能知道这是Tomcat的端口号。没错。既然我写的是Servlet所以只能部署在Tomcat上。那么为什么这里有没有端口号呢,实际上我将Tomacat的端口号改成了80,而80端口号可以不用显示的写出来。(避免端口号冲突,又改回了8080)
那么我们通过浏览器访问这个URL,其实就是浏览器和Tomcat就行通讯。通过IP+端口号的方式找到了我的这台计算机(服务器)上运行的Tomacat服务器(我更倾向于叫它服务器程序)。而后面的/test/servlet/ShowServlet就是我部署在Tomcat特定目录上的java后台程序中的那个Servlet类。
而这个类的作用就是操作数据库进行增删改查,然后把访问者想要的数据返回给它。
我们平时说看到的后台技术,本质就是在做这个工作。像php,Node.js….等等…他们的就是一系列操作数据库的代码,然后运行在能够容纳他们的特定服务器程序上,比如Apache,Nginx。而我们的请求就是通过IP定位到特定的服务器(计算机),在通过端口号定位到具体的服务器程序。然后找到这个后台程序具体的路径,完成请求…就是这样。说了好多…连自己都不知道有没有用……
关于代码的疑问:这里为什么是GET请求,没有声明啊?
通过源码我们可以很直观的看到原因
public Builder get() { return method("GET", null); } public Builder head() { return method("HEAD", null); } public Builder post(RequestBody body) { return method("POST", body); } //省略其他请求方式... //构造方法 public Builder() { this.method = "GET"; this.headers = new Headers.Builder(); }
我们可以通过Buidler中的方法来告诉Request我们使用什么方式请求。
在Builder的构造方法中,我们可以看到默认的方式是GET方式。
这里我们来接上文提到的Json问题
我们先看一看JSON的格式:{“a”:”1”,”b”:”2”} 最简单的JSON格式。
{ “aa”: [{ “name”: “Brett”, “age”:”1” },{ “name”: “Jason”, “age”:”2”}]} 数组的表示格式
稍稍解释一下数组格式的使用方法。首先我们先通过aa拿到其中的数组也就是[]包含的内容,然后按正常的方式去解析,放在一个List之中。
代码实现
我们可以直接使用官方的API对JSON进行解析:这里不知道大家注意没注意到,虽然我们服务器返回的数据很短,但是它却是一个数组类型!而解析数组类型和普通类型是不同的。
//解析数组 try { JSONArray jsonArray = new JSONArray(response.body().string()); JSONObject jsonObject=jsonArray.getJSONObject(0); String strOne=jsonObject.getString("temperature"); String strTwo=jsonObject.getString("humidity"); tv_content.setText("从JSON中拿到的第一个数据:"+strOne+","+"从JSON中拿到的第二个数据:"+strTwo); } catch (JSONException e) { } catch (IOException e) { e.printStackTrace(); } //普通解析 JSONObject jsonObject=new JSONObject(response.body().string()); String strOne=jsonObject.getString("temperature"); String strTwo=jsonObject.getString("humidity");
这样写说实话比较的长,尤其是当我们的JSON涵盖的数据非常多的时候。
因此我们要祭出我们常用的JSON解析框架:Gson。
Gson
既然是拓展库,我们肯定要在Gradle中引用:compile ‘com.google.code.gson:gson:2.8.0’
Gson gson=new Gson(); Type type=new TypeToken<List<GsonTestBean>>(){}.getType(); try { List<GsonTestBean> arrays=gson.fromJson(response.body().string(), type); tv_content.setText("从JSON中拿到的第一个数据:"+arrays.get(0).getTemperature()+","+"从JSON中拿到的第二个数据:"+arrays.get(0).getHumidity()); } catch (IOException e) { e.printStackTrace(); } //解析普通JSON Gson gson=new Gson(); try { GsonTestBean gsonTestBean= gson.fromJson(response.body().string(),GsonTestBean.class); } catch (IOException e) { e.printStackTrace(); }
效果和上边是一样的,没啥好说的…
简单梳理一下:正常解析普通JSON,只需要对应JSON格式中的键写好JavaBean即可。然后通过fromJson方法转好成对应的JavaBean对象。 我们想要将JavaBean转成JSON直接调用toJson(传入JavaBean的对象)
但是涉及到数组型,我们就要使用TypeToken。为什么?
其实比较好理解,因为fromJson方法中需要传递一个Class类型的参数。如果我们只是简单的解析,那么传一个简单的类这的确没有问题。因为这属于普通解析。
但是当我们传List就有问题了。因为这涉及到泛型擦除问题。在运行时,我们的泛型统一成了Object对象,所以我们无法在运行期间获知泛型参数的具体类型。因此我们的Gson就会一脸懵逼,没有类型所以没办法进行转换。因此这里使用了TypeToken就行了一些小小的转换。
尾声
先记录到此,以后遇到实用的就继续加上。上部分到此结束,更多用法请阅读下部分。最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
相关文章推荐
- Android从零开搞系列:网络框架系列(2)OkHttp+POST图片(下)
- android网络请求框架的学习之路——浅谈对Volley,OkHttp,Retrofit的了解与对比 标签: androidVolleyOkhttpRetrofit网络请求框架
- android 网络框架学习(okhttp,retrofit,rxjava)
- Android----------OkHttp网络请求框架Get和Post简单封装(泛型)
- Android网络框架-OkHttp使用
- Android 访问网络框架之——OkHttp框架的解析
- android 网络框架解析--OKHttp
- Android中贼好用的网络框架----OkHttp
- Android 网络框架(Android-async-http,OKHttp,retrofit,volley,xUtils,Afinal)
- Android 访问网络框架之——OkHttp框架的解析
- Android网络框架-OkHttp使用
- Android-网络框架01OKHttp3
- Android 网络访问框架retrofit2,okhttp3之简单封装,kotlin源码
- Android网络框架之----OKHttp简单二次封装
- Android网络请求框架之——okhttp3
- android网络请求框架的学习之路——浅谈对Volley,OkHttp,Retrofit的了解与对比
- android网络请求框架的学习之路——浅谈对Volley,OkHttp,Retrofit的了解与对比
- Android网络请求框架—OKHttp 源码解析
- Android更好的扩展性更强网络请求框架----okhttp
- Android网络框架综述(一)OkHttp、NoHttp、Volley