制作一个类似于今日头条的客户端,首页显示10条新闻。
使用Android的HttpURLConnection类请求一个URL,返回JSON数据,并使用自带的JSONArray类进行解析。
利用HttpURLConnection类请求网络数据(GET):
URL url = new URL(urlStr);
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setRequestProperty("accept", "*/*");
httpconn.setDoInput(true);
httpconn.setDoOutput(true);
httpconn.setConnectTimeout(5000);
httpconn.connect();
int stat = httpconn.getResponseCode();
String ss = httpconn.getRequestMethod();
Log.i("Tag", "CODE:" + stat);
String msg = "";
if (stat == 200) {
br = new BufferedReader(new InputStreamReader(httpconn.getInputStream()));
msg = br.readLine();
Log.i("Tag", "msg" + msg);
Bundle b = new Bundle();
b.putString("msg", msg);
Message m = new Message();
m.setData(b);
handler.sendMessage(m);
} else {
msg = "请求失败";
}
一开始一直抛出异常,后来了解到要使用子线程:
new Thread(new Runnable() {
@Override
public void run() {
BufferedReader br = null;
try {
URL url = new URL(urlStr);
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setRequestProperty("accept", "*/*");
httpconn.setDoInput(true);
httpconn.setDoOutput(true);
httpconn.setConnectTimeout(5000);
httpconn.connect();
//int stat = httpconn.getResponseCode();
int stat = 200;
String ss = httpconn.getRequestMethod();
Log.i("Tag", "CODE:" + stat);
String msg = "";
if (stat == 200) {
br = new BufferedReader(new InputStreamReader(httpconn.getInputStream()));
msg = br.readLine();
Log.i("Tag", "msg" + msg);
Bundle b = new Bundle();
b.putString("msg", msg);
Message m = new Message();
m.setData(b);
handler.sendMessage(m);
} else {
msg = "请求失败";
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
并用Handler捕捉返回的Message:
final android.os.Handler handler = new android.os.Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle b = msg.getData();
newsTemp = b.getString("msg");
Log.i("Tag", "handle" + b.getString("msg"));
Log.i("Tag", "newsTemp" + newsTemp);
initData(b.getString("msg"));
}
};
所以requestNews应该这样写:
public void requestNews() throws Exception {
final String urlStr = getString(R.string.get_url);
Log.i("Tag", "start");
final android.os.Handler handler = new android.os.Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle b = msg.getData();
newsTemp = b.getString("msg");
Log.i("Tag", "handle" + b.getString("msg"));
Log.i("Tag", "newsTemp" + newsTemp);
initData(b.getString("msg"));
}
};
new Thread(new Runnable() {
@Override
public void run() {
BufferedReader br = null;
try {
URL url = new URL(urlStr);
HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
httpconn.setRequestProperty("accept", "*/*");
httpconn.setDoInput(true);
httpconn.setDoOutput(true);
httpconn.setConnectTimeout(5000);
httpconn.connect();
//int stat = httpconn.getResponseCode();
int stat = 200;
String ss = httpconn.getRequestMethod();
Log.i("Tag", "CODE:" + stat);
String msg = "";
if (stat == 200) {
br = new BufferedReader(new InputStreamReader(httpconn.getInputStream()));
msg = br.readLine();
Log.i("Tag", "msg" + msg);
Bundle b = new Bundle();
b.putString("msg", msg);
Message m = new Message();
m.setData(b);
handler.sendMessage(m);
} else {
msg = "请求失败";
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
JSON数据格式如下:
[
{
“title”: “一双鞋子竟有这样的操作 被设计师的脑洞折服”,
“content”: “即便见过时尚界各种大胆的服饰设计,你也想不到一双鞋子竟然还有这样的操作——只有鞋底,没有鞋面!这双鞋子由意大利公司NakeFit推出,主要针对度假、休闲时的糟糕路况所设计,具有防水、耐磨、隔热、防滑等功能,携带方便,最关键是的足够拉风。目前这双鞋正在Kickstarter平台接受众筹,有黑、粉、蓝三种颜色可选,价格为33美元。怎么样,你有兴趣吗?”,
“pubDate”: “2017-06-16 09:10:12”,
“desc”: “即便见过时尚界各种大胆的服饰设计,你也想不到一双鞋子竟然还有这样的操作——只有鞋底,没有鞋面!这双鞋子由意大利公司NakeFit推出,主要针对度假、休闲时的糟糕路况所设计,具有防水、耐磨、隔热、防滑…”,
“img”: “http://upload.news.cecb2b.com/2017/0616/1497602230812.jpg”
},
{
“title”: “苹果也玩快充 新iPad可支持29W充电器”,
“content”: ” 苹果最新的10.5英寸iPad Pro已经发货,不少消费者也都陆续收到了新品,但有网友反映新款iPad Pro的充电速度较慢,但实际上,新品是支持快充的,只不过充电器需单独购买。 10.5英寸iPad Pro采用了USB 3.0 Lightning接口,理论上支持快充。微博网友肥威已经证实,使用苹果MacBook笔记本的29W充电器可为iPad Pro进行快速充电,但遗憾的是,10.5英寸iPad Pro自带的充电器仅为12W,因此要想对其进行快速充电的话需要单独购买29W的充电器。 有国外网友实测得知,使用29W充电器为10.5英寸iPad Pro进行快速充电,145分钟可以充满,但所有iOS设备在充电80%后都会进入涓流充电模式,因此前80%的数据更加重要,10.5英寸iPad Pro快充80%电量需要90分钟,还是非常不错的。提示:支持键盘“← →”键翻页 阅读全文”,
“pubDate”: “2017-06-16 08:50:09”,
“desc”: “苹果最新的10.5英寸iPadPro已经发货,不少消费者也都陆续收到了新品,但有网友反映新款iPadPro的充电速度较慢,但实际上,新品是支持快充的,只不过充电器需单独购买。微博网友肥威已经证实…”,
“img”: “http://ol01.tgbusdata.cn/v2/thumb/jpg/RTQ4Qyw1ODAsMTAwLDQsMywxLC0xLDAscms1MCwxOTIuMTY4LjguNjc=/u/iphone.tgbus.com/UploadFiles/201706/2017061613240442.jpg”
}
]
这样得到了一个String的新闻素材,接下来利用JSONArray解析JSON数据:
public void formatData(String msg) throws JSONException {
newsList = new ArrayList<>();
JSONArray jsonArray = new JSONArray(msg);
for(int i=0;inew News(jsonObject.getString("title"),jsonObject.getString("desc"),jsonObject.getString("img"),jsonObject.getString("content"),jsonObject.getString("pubDate")));
}
}