volley Json数据获取及解析(备忘)

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数据如下:

volley 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>

 执行结果:

volley Json数据获取及解析(备忘)

 目前存在问题,这个只能运行app的时候显示,不会自动更新,应该要是每天半夜更新一次,这才算天气预报。所以要加定时任务才算真正完成。晚点再做。

上一篇:如何在Log4j2中将追加器添加到Logger


下一篇:dart系列之:浏览器中的舞者,用dart发送HTTP请求