项目需求

制作如下的界面,访问疫情实时数据,显示在界面上。界面可操作的是:选怎国家的下拉控件Spinner,该下拉控件中以疫情的获取数据中国家名称赋值,下拉选择某个国家时,将该国家的疫情数据显示在下面,以及刷新按钮。

框架

实现代码

引入

先修改AndroidMainifest.xml文件为如下格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.volley">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Volley">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

在bulid.gradle中增加为:

1
2
3
4
dependencies {
...
compile 'com.android.volley:volley:1.1.1'
}

activity_main.xml

其中spinner控件引用了array.xml的文本,需要新建一个array.xml

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/timeText"
android:layout_width="348dp"
android:layout_height="43dp"
android:gravity="center"
android:text="当前时间"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.492"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.229" />

<Spinner
android:id="@+id/spinner"
android:layout_width="113dp"
android:layout_height="49dp"

android:entries="@array/languages"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.704"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.35" />

<TextView
android:id="@+id/textView2"
android:layout_width="99dp"
android:layout_height="54dp"
android:gravity="center"
android:text="选择国家:"
android:textSize="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.269"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.353" />

<TextView
android:id="@+id/text4"
android:layout_width="75dp"
android:layout_height="29dp"
android:gravity="center"
android:text="0"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.904"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />

<TextView
android:id="@+id/textView3"
android:layout_width="78dp"
android:layout_height="31dp"
android:gravity="center"
android:text="新增确诊"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.063"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.537" />

<TextView
android:id="@+id/text2"
android:layout_width="75dp"
android:layout_height="29dp"
android:gravity="center"
android:text="0"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.345"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />

<TextView
android:id="@+id/textView"
android:layout_width="141dp"
android:layout_height="43dp"
android:gravity="center"
android:text="海外疫情"
android:textSize="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.098" />


<TextView
android:id="@+id/text1"
android:layout_width="75dp"
android:layout_height="29dp"
android:gravity="center"
android:text="0"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.062"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />

<TextView
android:id="@+id/text3"
android:layout_width="75dp"
android:layout_height="29dp"
android:gravity="center"
android:text="0"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.625"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.652" />

<TextView
android:id="@+id/textView4"
android:layout_width="89dp"
android:layout_height="31dp"
android:gravity="center"
android:text="累计治愈"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.627"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.537" />

<TextView
android:id="@+id/textView6"
android:layout_width="75dp"
android:layout_height="29dp"
android:gravity="center"
android:text="累计死亡"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.904"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.535" />

<TextView
android:id="@+id/textView5"
android:layout_width="83dp"
android:layout_height="31dp"
android:gravity="center"
android:text="累计确诊"
android:textSize="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.329"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.537" />

<Button
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="161dp"
android:layout_marginLeft="161dp"
android:layout_marginTop="655dp"
android:layout_marginEnd="162dp"
android:layout_marginRight="162dp"
android:layout_marginBottom="28dp"
android:text="刷新"
app:backgroundTint="#2196F3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

Array.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="languages">
<item>美国 </item>
<item>印度</item>
<item>巴西</item>
<item>法国</item>
<item>俄罗斯</item>
<item>英国</item>
<item>土耳其</item>
<item>意大利</item>
<item>西班牙</item>
</string-array>

</resources>

MainActivity.java

json获取的数据可以用ListView来显示,界面更美观,方便起见用了四个textView显示。

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.example.volley;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Calendar;


public class MainActivity extends AppCompatActivity {
static String url = "https://api.inews.qq.com/newsqa/v1/automation/foreign/country/ranklist";
String jsonData ;
private TextView timeText;
private TextView text1;
private TextView text2;
private TextView text3;
private TextView text4;
private Button refresh;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getData(url);
setContentView(R.layout.activity_main);
text1 = findViewById(R.id.text1);
text2 = findViewById(R.id.text2);
text3 = findViewById(R.id.text3);
text4 = findViewById(R.id.text4);
refresh = findViewById(R.id.refresh);
timeText = findViewById(R.id.timeText);
Spinner spinner = findViewById(R.id.spinner);
spinner.setClickable(false);
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
timeText.setText("当前时间:" + year + "年" + month + "月" + day + "日");


spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@SuppressLint("WrongConstant")
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// 显示选中
// String info = spinner.getItemAtPosition(pos).toString();
// Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show();
JSONObject root = null;
try {
root = new JSONObject(jsonData);
JSONArray array = root.getJSONArray("data");
if(array != null) {
//pos值代表spinner中选中的位置,若与array中排序一致,则代表国家
JSONObject data = array.getJSONObject(pos);
String str1 = data.getString("confirmAdd"); //json数据单项
String str2 = data.getString("confirm");
String str3 = data.getString("heal");
String str4 = data.getString("dead");
text1.setText(str1);
text2.setText(str2);
text3.setText(str3);
text4.setText(str4);
}
} catch (JSONException e) {
e.printStackTrace();
}
}

@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});

refresh.setOnClickListener(v -> {
//自己跳自己,刷新
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
});
}

private void getData (String url){
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
jsonData = response;
}
},
new Response.ErrorListener() {
@SuppressLint("WrongConstant")
@Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(stringRequest);
//不延时会闪退
try {
//延时时间自定义,少于0.5秒很容易闪退
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

总结

如果root = new JSONObject(jsonData);始终报空指针错误,问题很可能是jsonData没有数据,即由于网速问题,数据尚未获取,就启动了界面,这样就会闪退。简单处理就是在数据获取的时候加一个延时,再启动界面。

推荐的是,可以做一个数据判空,或初始化几个默认的数据,以免防止数据为零时闪退。