android studio 3.5.2编译
安卓api17以上。
例程:Weathervolleyjson
这个是把volley 和Json两个东西整个到一起了,但也有点不同。之前的关于volley的做法是通过按钮获取,这个是打开app后直接执行,实际两个方法是不同的。json数据解析是一样的。
一、volley给权限和加依赖。至于加权限和依赖这里就不写了,参照:
这个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的时候显示,不会自动更新,应该要是每天半夜更新一次,这才算天气预报。所以要加定时任务才算真正完成。晚点再做。