携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
今日实战内容:写一个网络版的天气预报App。
一、知识储备
两个知识点:第一,利用HttpURLConnection实现网络请求;第二,利用JSONObject解析json数据。
1.1 HttpURLConnection 网络请求
我们开发App,肯定需要连接网络,比如获取最新天气、资讯,都需要通过网络进行传输。
网络传输就牵扯到了网络协议,我们要协商以怎样的方式交互:我说了你懂,你发送的我能收到。
HTTP协议是现在Internet上使用得最多、最重要的协议,我们通过HTTP来访问网络资源。
Android已经提供了访问HTTP协议的基本功能的类:HttpURLConnection
。它可用于向指定网站发送GET、POST请求。
构建一个网络连接很简单,指定url配置请求方式就可以了。
// 构建URL对象
URL url = new URL("http://www.weather.com.cn/data/sk/101010100.html");
//建立HttpURLConnection实例
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置请求方式
connection.setRequestMethod("GET");
HttpURLConnection
连接建立完成,就可以去访问和获取数据了。
// 使用getInputStream获取服务器返回的输入流
InputStream stresm = connection.getInputStream();
//对返回的输入流进行读取
BufferedReader reader = new BufferedReader(new InputStreamReader(stresm));
//构建字符对象存放数据
StringBuilder response = new StringBuilder();
String line;
//循环数据流存入字符对象
while ((line = reader.readLine()) != null) {
response.append(line);
}
// 输出字符对象,这就是网络返回的数据
String res = response.toString();
步骤如下:
- 使用getInputStream获取服务器返回的输入流。
- 对返回的输入流进行读取。
- 构建字符对象存放数据,循环数据流存入字符对象。
- 输出字符对象,这就是网络返回的数据。
以上就是网络请求的过程。
1.2 JSONObject解析json
网络交互的格式有很多,比较常用的就是json。
我们面临json如何处理呢?不对,应该先说json是什么样子的?
// 一段json
{
"code":1,
"name":"tom",
"num":"it1011"
}
// 一个Java类
public class LoginBean {
private int code;
private String name;
private String num;
}
你可以认为json和Java类对应,因为最终我们也是要把json转换成实体类。
Android系统提供解析json的类JSONObject
,具体使用方法如下:
- 将json字符串jsonData装入JSONObject,实例jsonObject对象。
- 根据json的键,从jsonObject中读取期望的值。
举个例子,还是这一段json:
{
"code":1,
"name":"tom",
"num":"it1011"
}
我们如何解析呢?
先将json字符串jsonData装入JSONObject,然后根据数据类型和键值取值就可以了。
JSONObject jsonObject = new JSONObject(jsonData);
int code = jsonObject.getInt("code");
String name = jsonObject.getString("name");
String num = jsonObject.getString("num");
二、实战应用
2.1 效果
现在再来看看,我们要实战的一个应用。这是一个天气预报程序。
如果要开发它,那么流程应该是:点击按钮请求网络,获取数据并解析,最后展示到界面上。
2.2 接口和格式
数据来源我们使用天气网,接口的url是 www.weather.com.cn/data/sk/101… ,这是北京天气。此接口通过get方式可直接访问,返回json格式:
{
"weatherinfo": {
"city": "北京",
"temp": "27.9",
"WD": "南风",
"WS": "小于3级",
"SD": "28%",
……
}
}
2.3 逻辑架构
写代码前,我们先想一想逻辑流程和数据流转,最好能简单写一写伪代码,先整体思考。
public class MainActivity extends Activity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
}
// 1、新启动一个线程用于网络请求
public void getTextFromNet(View view) {
new Thread(new Runnable() {
@Override
public void run() {
// 2、从接口url访问获取json
String jsonText = getNetString(url);
// 3、解析json显示到界面上
showData(jsonText);
}
}).start();
}
}
为什么要新启动线程去请求网络,之前讲过UI的线程模型,有兴趣的可以去参考。
下面我们进行功能拆分,首先访问接口获取json,也就是那个getNetString
函数,代码如下,还是联网的那一套,主要通过HttpURLConnection
来实现。
private String getNetString(String urlString){
try {
// 构建一个URL
URL url = new URL(urlString);
// 通过url对象来打开一个HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方式
connection.setRequestMethod("GET");
// 获取输入流
InputStream stresm = connection.getInputStream();
// 把输入流读取到buffer
BufferedReader reader = new BufferedReader(new InputStreamReader(stresm));
// 构建一个字符对象
StringBuilder response = new StringBuilder();
String line;
// 将网络的输入流转化到字符串当中
while ((line = reader.readLine()) != null) {
response.append(line);
}
// 返回网络的结果
return response.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
接下来是解析数据和展示数据,我们来看一下代码:
private void showData(final String jsonText) {
try {
JSONObject jsonObject = new JSONObject(jsonText);
JSONObject weatherObj = jsonObject.getJSONObject("weatherinfo");
String city = weatherObj.getString("city");
String temp = weatherObj.getString("temp");
String WD = weatherObj.getString("WD");
String text = city + temp + WD;
runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText(text);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
解析数据通过构造JSONObject
实例,然后通过get对应的类型获取出对应的数值,然后拼装成我们需要字符串。
重点看一下,当我们有展示的数据后,如何交给UI呈现出来。要记住,现在我们还处于子线程中,不能直接进行view
的setText
操作,原因是子线程别直接访问主线程。我们要通过runOnUiThread
方法,在主线程里去给视图做赋值操作。
三、总结
文中讲的两项内容HttpURLConnection
和JSONObject
都比较底层(虽然我认为这是高阶API)。
Android新人基本不用这个,因为网络框架有很多,例如Volley、OKHttp。解析框架也有很多,比如Gson、fastjson。但是,从学习的角度,我依然建议大家从底层开始学,这个底层其实也是调用Android SDK这个大框架。
可能你最终用不到,但是必须要知其然,知其所以然,这将是技术人最终的自信。
用框架很方便,没错,但是框架也是开发者写的,到某个阶段,你最终也要写框架。
我是TF男孩,关注掘金专栏《Java转Android》。每天800字,30天入门安卓开发。