android studio 3.5.2编译
安卓api17以上。
例程:Weathervolleyjson
这个是把volley 和Json两个东西整个到一起了,但也有点不同。之前的关于volley的做法是通过按钮获取,这个是打开app后直接执行,实际两个方法是不同的。json数据解析是一样的。
一、volley给权限和加依赖。至于加权限和依赖这里就不写了,参照:
android volley实现API获取和风天气之一(Json数据获取)(备忘)
这个app里面主要三部分,也就是三个函数:
initview()、getjson()和analyzeJSONArray(String json) .
第一个是初始化,就是把原来写在Oncreate里面的部分东西变成一个函数,看网上有人说,这样写规矩一点,那就跟别人学呗。
第二个是获取json数据的函数,并调用第三个函数进行数据解析和显示。
第三个是解析json数据的函数。
二、获取json数据。
关于第二个函数详细说一下,做为备忘,代码如下:
public void getjson()
{
//1、获取json数据
//创建一个请求队列
RequestQueue requestQueue=Volley.newRequestQueue(MainActivity.this);
//创建一个请求
String url="https://devapi.qweather.com/v7/weather/3d?lang=zh&location=101280603&key=e8ac8fde2f6e479b9ca61e85fd04b81b&gzip=n ";
StringRequest stringRequest=new StringRequest(Request.Method.GET,url, new Response.Listener<String>() {
//正确接受数据之后的回调
@Override
public void onResponse(String response) {
analyzeJSONArray(response);//解析response json数据
}
}, new Response.ErrorListener() {//发生异常之后的监听回调
@Override
public void one rrorResponse(VolleyError error) {
textView1.setText("加载错误"+error);
}
});
//将创建的请求添加到请求队列当中
requestQueue.add(stringRequest);
}
volley获取网上内容标准步骤如下:
1.创建请求队列(this 指Activity上下文环境)
RequestQueue requestQueue = Volley.newRequestQuene(this);
2.请求url:
String url="https://devapi.qweather.com/v7/weather/3d?lang=zh&location=城市代码&key=和风key&gzip=n ";" //zip=n表示不压缩。
3.创建json请求对象(核心)(此方法包含4个参数 分别表示:请求方式(get/post),请求url,成功后返回监听,失败返回监听)
JsonObjectRequest jsonObjectRequest = new JsonOjbectRequest(Request.Method.GET,url,new Respose.Listener<JSONObject obj>(){
public void onResponse(JSONObject obj){
// 此处为成功获取json 内容 本例直接把函数三(解析的数据)放在此处。
}
},new Response.ErrorListener(VolleyError volleyError){
// 此处为处理返回失败情况
});
4.向请求队列中添加请求对象
requestQuene.add(jsonObjectRequest);
而在之前的那个app里面,那个get.setOnClickListener(new View.OnClickListener() {...},StringRequest里面却没有get,我不知道是怎么回事,还没搞明白。
public void initListener()
{
get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建一个请求队列
RequestQueue requestQueue=Volley.newRequestQueue(MainActivity.this);
//创建一个请求
String url="https://devapi.qweather.com/v7/weather/3d?lang=zh&location=101280603&key=e8ac8fde2f6e479b9ca61e85fd04b81b&gzip=n ";
StringRequest stringRequest=new StringRequest(url, new Response.Listener<String>() {
//正确接受数据之后的回调
@Override
public void onResponse(String response) {
tv_volley_result.setText(response);
}
}, new Response.ErrorListener() {//发生异常之后的监听回调
@Override
public void one rrorResponse(VolleyError error) {
tv_volley_result.setText("加载错误"+error);
}
});
//将创建的请求添加到请求队列当中
requestQueue.add(stringRequest);
}
});
三、解析json数据。
public void analyzeJSONArray(String json) {
try{
/**
* JSON数组在牛逼,一旦有了 key person 这样的标记,就必须先是个 JSON对象
* 最外层的JSON对象,最大的哪个 { ... }
*/
JSONObject jsonObjectALL = new JSONObject(json);
// 通过标识(person),获取JSON数组
JSONArray jsonArray = jsonObjectALL.getJSONArray("daily");
JSONObject jsonObject = jsonArray.getJSONObject(0);
String date = jsonObject.getString("fxDate");
String subdate= date.substring(date.length()-2);
String tianqi=jsonObject.getString("textDay");
String qiwenmax=jsonObject.getString("tempMax");
String qiwenmin=jsonObject.getString("tempMin");
String fengxiang = jsonObject.getString("windDirDay");
String fengli= jsonObject.getString("windScaleDay");
textView1.setText(subdate+"日");
textView2.setText(tianqi+" "+qiwenmin+"-"+qiwenmax+"℃");
textView3.setText(fengxiang+" "+fengli+"级");
JSONObject jsonObject1 = jsonArray.getJSONObject(1);
String date2 = jsonObject1.getString("fxDate");
String subdate2= date2.substring(date2.length()-2);
String tianqi2=jsonObject1.getString("textDay");
String qiwenmax2=jsonObject1.getString("tempMax");
String qiwenmin2=jsonObject1.getString("tempMin");
String fengxiang2 = jsonObject1.getString("windDirDay");
String fengli2= jsonObject1.getString("windScaleDay");
textView4.setText(subdate2+"日");
textView5.setText(tianqi2+" "+qiwenmin2+"-"+qiwenmax2+"℃");
textView6.setText(fengxiang2+" "+fengli2+"级");
JSONObject jsonObject2 = jsonArray.getJSONObject(2);
String date3 = jsonObject2.getString("fxDate");
String subdate3= date3.substring(date3.length()-2);
String tianqi3=jsonObject2.getString("textDay");
String qiwenmax3=jsonObject2.getString("tempMax");
String qiwenmin3=jsonObject2.getString("tempMin");
String fengxiang3 = jsonObject2.getString("windDirDay");
String fengli3= jsonObject2.getString("windScaleDay");
textView7.setText(subdate3+"日");
textView8.setText(tianqi3+" "+qiwenmin3+"-"+qiwenmax3+"℃");
textView9.setText(fengxiang3+" "+fengli3+"级");
} catch (Exception e) {
e.printStackTrace();
}
这里面textview很多,可以用更好的方法动态加,代码会简单的多,但还没学会。反正是能正常显示。这个函数要放在getjson里面执行。
其实解析这个json我觉得会了之后也不复杂。原json数据如下:
最外层就是一个json对象,里面的daily就是列表,有三天的天气数据。下面的refer没用,不用解析。所以只要两层就可以了。是不是一下这要放在try{}catch{}里面捕捉异常我也不知道,反正都这么写:
try{ } catch (Exception e) { e.printStackTrace(); }
然后就是一层层解析:
第一层:JSONObject jsonObjectALL = new JSONObject(json);
这层里没有我们要的数据,所以写完就行,不用管。如果要判断获取数据是否成功,那就要用到是不是200这个判断。
第二层是我们要的:JSONArray jsonArray = jsonObjectALL.getJSONArray("daily");
即从daily开始,里面的都是我们要的数据。一共有三天的数据,每一个是一个对象JSONObject,还有里面的数据名字都一样,但做为变量一家要起不同的名字。所以有JSONObject1、JSONObject、date2,date3,不同的名字。其他没啥可说的。
全部MainActivity.java代码(和风key已去掉,要填入你自己的):
package com.example.weathervolleyjson;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
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.JsonObjectRequest;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONObject;
import static java.sql.DriverManager.println;
public class MainActivity extends AppCompatActivity {
private TextView textView1;
private TextView textView2;
private TextView textView3;
private TextView textView4;
private TextView textView5;
private TextView textView6;
private TextView textView7;
private TextView textView8;
private TextView textView9;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initview();
getjson();
}
public void initview()//把需要初始化的控件的逻辑都写在这里是一个很好的编程范式
{
textView1=findViewById(R.id.textView1);
textView2=findViewById(R.id.textView2);
textView3=findViewById(R.id.textView3);
textView4=findViewById(R.id.textView4);
textView5=findViewById(R.id.textView5);
textView6=findViewById(R.id.textView6);
textView7=findViewById(R.id.textView7);
textView8=findViewById(R.id.textView8);
textView9=findViewById(R.id.textView9);
}
public void getjson()
{
//1、获取json数据
//创建一个请求队列
RequestQueue requestQueue=Volley.newRequestQueue(MainActivity.this);
//创建一个请求
String url="https://devapi.qweather.com/v7/weather/3d?lang=zh&location=101280603&key=替换你的key&gzip=n ";
StringRequest stringRequest=new StringRequest(Request.Method.GET,url, new Response.Listener<String>() {
//正确接受数据之后的回调
@Override
public void onResponse(String response) {
analyzeJSONArray(response);//解析response json数据
}
}, new Response.ErrorListener() {//发生异常之后的监听回调
@Override
public void one rrorResponse(VolleyError error) {
textView1.setText("加载错误"+error);
}
});
//将创建的请求添加到请求队列当中
requestQueue.add(stringRequest);
}
//2、解析json数据
public void analyzeJSONArray(String json) {
try{
/**
* JSON数组在牛逼,一旦有了 key person 这样的标记,就必须先是个 JSON对象
* 最外层的JSON对象,最大的哪个 { ... }
*/
JSONObject jsonObjectALL = new JSONObject(json);
// 通过标识(person),获取JSON数组
JSONArray jsonArray = jsonObjectALL.getJSONArray("daily");
JSONObject jsonObject = jsonArray.getJSONObject(0);
String date = jsonObject.getString("fxDate");
String subdate= date.substring(date.length()-2);
String tianqi=jsonObject.getString("textDay");
String qiwenmax=jsonObject.getString("tempMax");
String qiwenmin=jsonObject.getString("tempMin");
String fengxiang = jsonObject.getString("windDirDay");
String fengli= jsonObject.getString("windScaleDay");
textView1.setText(subdate+"日");
textView2.setText(tianqi+" "+qiwenmin+"-"+qiwenmax+"℃");
textView3.setText(fengxiang+" "+fengli+"级");
JSONObject jsonObject1 = jsonArray.getJSONObject(1);
String date2 = jsonObject1.getString("fxDate");
String subdate2= date2.substring(date2.length()-2);
String tianqi2=jsonObject1.getString("textDay");
String qiwenmax2=jsonObject1.getString("tempMax");
String qiwenmin2=jsonObject1.getString("tempMin");
String fengxiang2 = jsonObject1.getString("windDirDay");
String fengli2= jsonObject1.getString("windScaleDay");
textView4.setText(subdate2+"日");
textView5.setText(tianqi2+" "+qiwenmin2+"-"+qiwenmax2+"℃");
textView6.setText(fengxiang2+" "+fengli2+"级");
JSONObject jsonObject2 = jsonArray.getJSONObject(2);
String date3 = jsonObject2.getString("fxDate");
String subdate3= date3.substring(date3.length()-2);
String tianqi3=jsonObject2.getString("textDay");
String qiwenmax3=jsonObject2.getString("tempMax");
String qiwenmin3=jsonObject2.getString("tempMin");
String fengxiang3 = jsonObject2.getString("windDirDay");
String fengli3= jsonObject2.getString("windScaleDay");
textView7.setText(subdate3+"日");
textView8.setText(tianqi3+" "+qiwenmin3+"-"+qiwenmax3+"℃");
textView9.setText(fengxiang3+" "+fengli3+"级");
} catch (Exception e) {
e.printStackTrace();
}
}
}
全部activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:background="@color/colorPrimary"
android:orientation="vertical"
tools:context=".MainActivity">
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="150dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="26日"
android:textColor="#FFFFFF"
android:textSize="30dp" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="27日"
android:textColor="#FFFFFF"
android:textSize="30dp" />
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="28日"
android:textColor="#FFFFFF"
android:textSize="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="180dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="小雨 23-26℃"
android:textColor="#FFEB3B"
android:textSize="30dp" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="小雨 23-26℃"
android:textColor="#FFEB3B"
android:textSize="30dp" />
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="小雨 23-26℃"
android:textColor="#FFEB3B"
android:textSize="30dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="210dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="西北风 2-3级"
android:textColor="#FF9800"
android:textSize="30dp" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="西北风 2-3级"
android:textColor="#FF9800"
android:textSize="30dp" />
<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="西北风 2-3级"
android:textColor="#FF9800"
android:textSize="30dp" />
</LinearLayout>
</RelativeLayout>
执行结果:
目前存在问题,这个只能运行app的时候显示,不会自动更新,应该要是每天半夜更新一次,这才算天气预报。所以要加定时任务才算真正完成。晚点再做。