利用 HttpURLConnection 从后端拽取数据展示在app上
1.获取数据
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//开启线程来发起网络请求获取数据
private void sendRequestWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL("www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
//对获取到的输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
response.append(line);
}
Log.e("测试","获取到的数据:"+response);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (reader != null) try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
if (connection != null){
connection.disconnect();
}
}
}
}).start();
}
|
分析:由于执行网络请求属于耗时操作,需要开启子线程执行,有关多线程常用方法点击链接跳转;url 为 后端地址,这里输入的是百度首页地址;设置最大请求时长为8秒:Timeout(8000);将获取的数据读取到 response,并使用 Log.e 调试输出。运行程序后即可看到百度首页的数据构成
2.json数据解析
我们从后端获取的数据是以字符串的形式传输的,但实际上它具有一定的数据结构,常用的形式有 xml 和 json;这里探究 json 数据的解析
首先将 response 转成字符串并传输到函数 showResponse中:在Log.e调试修改为
1
2
|
Log.e("测试","获取到的数据:"+response);
showResponse(response.toString());
|
2.1便于理解但很麻烦的方法:JSONObject
大致写一下思路:将字符串转成json数据类型,遍历所有数据获取信息并封装为 list。但是操作过于繁琐。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
private void showResponse (final String response) {
if(response!=null) {
Map<String, Object> map;
List<Map<String, Object>> list = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
map = new HashMap<>();
if (jsonObject != null) {
int id = jsonObject.optInt("id");
String name = jsonObject.optString("name");
String content = jsonObject.optString("content");
boolean favor = jsonObject.optBoolean("favor");
JSONArray son = jsonObject.getJSONArray("son");
map.put("id", id);
map.put("name", name);
map.put("content", content);
map.put("favor", favor);
}
list.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
|
2.2使用 Gson 解析工具
引入工具包
implementation 'com.google.code.gson:gson:2.8.5'
使用AS插件 GsonFormat
新建 JavaBean 类,我这里命名为 chapter,将json数据复制到 GsonFormat ,点击OK,自动根据 json 结构生成 JavaBean 类。
声明全局变量
public ArrayList<chapter> list = new ArrayList<>();
解析过程
1
2
3
4
5
6
7
8
9
10
|
//解析json传入list
private void showResponse (final String response) {
Gson gson = new Gson();
Type listType = new TypeToken<List<chapter>>() {
}.getType();
list = gson.fromJson(response, listType);
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
}
|
注:不同结构的 json 数据写法也不太相同,点击链接查看官方文档
2.3阿里的fastjson解析工具(没用过)
3.在RecyclerView中展示数据
我们已经获得一个封装好的 list,使用 handler 方法更新 ui
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//在RecycleView中展示数据,点击item页面跳转
@SuppressLint("HandlerLeak")
public Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
RecyclerView recyclerview = findViewById(R.id.recy);
if (recyclerview.getItemDecorationCount() == 0 ) {
recyclerview.addItemDecoration(new DividerItemDecoration(ChapterActivity.this, DividerItemDecoration.VERTICAL));
}
chapter_itemAdapter adapter = new chapter_itemAdapter(list,ChapterActivity.this,Word);
//设置布局格式
recyclerview.setLayoutManager(new LinearLayoutManager(ChapterActivity.this));
recyclerview.setAdapter(adapter);
break;
}
}
};
|
创建适配器 chapter_itemAdapter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class chapter_itemAdapter extends RecyclerView.Adapter<chapter_itemAdapter.ViewHolder> {
private ArrayList<chapter> list;
public Context context;
private LayoutInflater inflater;
chapter_itemAdapter(ArrayList<chapter> list, Context context){
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = inflater.inflate( R.layout.recyclerview_item , parent, false);
return new ViewHolder(view);
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
holder.recy_name.setText(Html.fromHtml(Objects.requireNonNull(list.get(position).getName())).toString());
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView recy_name;
ViewHolder(View itemView) {
super(itemView);
recy_name = itemView.findViewById(R.id.recy_name);
}
}
}
|
对应布局 recyclerview_item
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/touch_bg"
android:orientation="vertical"
tools:ignore="UselessParent">
<TextView
android:id="@+id/recy_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="5dp"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:textColor="#00BBD3"
android:textSize="17sp"/>
</LinearLayout>
</RelativeLayout>
|
有关RecyclerView更多用法点击链接跳转