irpas技术客

简易的安卓天气app(一)——解析Json数据、数据类封装_roydon_Guo

大大的周 3598

📌简易的安卓天气app(一)——解析Json数据、数据类封装 ?简易的安卓天气app(二)——适配器、每小时数据展示 ?简易的安卓天气app(三)——城市管理、数据库操作 ?简易的安卓天气app(四)——搜索城市、完善页面

简述

不罗嗦那么多没用的;;; 既然是简易的天气app,那么本demo就没有那麽多复杂的交互,页面跳转,只包括了针对api获取和解析数据放到app主页面,由于配置定位服务太繁琐,本次测试没有使用定位功能。 项目只包含一个主要activity_main.xml,两个封装的实体用来存数据 用到的天气api可前往官网注册账号获取:天气api

例如我这里注册好了我的账号,进入主页面得到下图的appid和appsecret 然后把这两个东西复制粘贴到下面的api中

//里面的括号中的两个参数值换成你的,包括括号 https://tianqiapi.com/api?version=v1&appid=(你的appid)&appsecret=(你的appsecret)

注意:

慎用此接口,每天有免费使用上限(如果你不想充钱) 地址栏搜索默认是当前所在城市,若是指定城市url后面加上&city=城市名,就行

接着,访问此url结果如图,一长串的json数据 如果你的浏览器支持转为json格式,那么会得到更清晰的数据格式,方便后续对其进行封装,也可百度在线json格式化工具,复制原始数据进去,得到格式化jsn数据 观察上图json数据,里面的嵌套关系决定了我们封装一个实体类肯定不能拿到全部信息,因为上图data,是一个json数组(JsonArray),里面包含了今天加上未来六天共七天的天气数据(JsonObject),所以data要单独封装成一个实体叫做DayWeatherBean,用来接受每天的数据。

项目结构

api请求工具包

那么既然是请求api解析数据,自然离不开HttpUrlConnection,如果学的不是HttpUrlConnection请自行根据更改。 首先封装一个工具包,表示根据指定地址网络请求得到数据,得到的是string字符串,实是json数据

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class NetworkUtil { // 一天测试次数有限,慎用 public static final String URL_WEATHER = "https://tianqiapi.com/api?version=v1&appid=(你的appid)&appsecret=(你的appsecret)"; public static String getWeather() { String result = ""; HttpURLConnection connection = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; // 连接网络 try { URL urL = new URL(URL_WEATHER); connection = (HttpURLConnection) urL.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 从连接中读取数据(二进制) InputStream inputStream = connection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); // 二进制流送入缓冲区 bufferedReader = new BufferedReader(inputStreamReader); // 容器 StringBuilder stringBuilder = new StringBuilder(); String line = ""; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line); } result = stringBuilder.toString(); } catch (Exception e) { e.printStackTrace(); }finally { if (connection != null) { connection.disconnect(); } if (inputStreamReader != null) { try { inputStreamReader.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; }

既然是网络请求,注意

AndroidManifest中别忘了加 <uses-permission android:name="android.permission.INTERNET" />

布局文件

接着就是布局,随意,怎么好看怎么来,无非就是接受几个数据传给TextView

<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:alpha="0.8" android:background="@mipmap/bg" android:gravity="center_horizontal" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="郑州" android:textSize="25sp" android:layout_gravity="center" android:gravity="center" android:textColor="@color/white" android:id="@+id/tv_city"/> <ImageView android:id="@+id/iv_weather" android:layout_width="125dp" android:layout_height="95dp" android:src="@drawable/weather_yin" /> <TextView android:id="@+id/tv_weather" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="阴转多云" android:textColor="@color/white" android:textSize="20sp" /> <TextView android:id="@+id/tv_week" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="星期二" android:textColor="@color/white" android:textSize="16sp" /> <TextView android:id="@+id/tv_tem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="31°C" android:textColor="@color/white" android:textSize="100sp" /> <TextView android:id="@+id/tv_tem_low_high" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="25°C/33°C" android:textColor="@color/white" android:textSize="20sp" /> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="更新时间:2022-06-15 08:22:23" android:textColor="@color/white" android:textSize="17sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:alpha="0.7" android:background="@drawable/blackground" android:orientation="horizontal" > <LinearLayout android:layout_width="120dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="5dp" android:gravity="center" android:orientation="vertical"> <ImageView android:layout_width="105dp" android:layout_height="65dp" android:src="@drawable/fengli" /> <TextView android:id="@+id/tv_win" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="南风3~4级" android:textColor="@color/white" android:textSize="16sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:layout_marginLeft="10dp" android:orientation="horizontal"> <TextView android:id="@+id/tv_air" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:gravity="center" android:text="空气:43 | 优\n空气好,适宜外出" android:textColor="@color/white" android:textSize="18sp" /> </LinearLayout> </LinearLayout> </LinearLayout>

效果图(上图有个阴转多云图,下方有源码,可自行了解,此次只拿数据传数据,不包括图片)

实体类

两个实体类 一个WeatherBean是最上层json封装,一个是DayWeatherBean封装的data(前面已经解答过)

WeatherBean

没什么好说的,就下面几个属性,学爬虫的应该更了解 其他的属性String就行,挑重要信息拿,data就是··List<DayWeatherBean>

此处命名不规范问题,由于使用的是Gson包封装,所以有一个实现类可用 public class WeatherBean implements Serializable 每个属性再加上序列化注解指定原始数据,就可解决,自行补充

import java.util.List; /** * TextView tv_city,tv_time,tv_weather,tv_week,tv_tem,tv_tem_low_high,tv_win,tv_air;7个 * ImageView iv_weather;//天气图标 */ public class WeatherBean { private String cityid; private String city;//城市名称 private String update_time;//更新时间 private List<DayWeatherBean> data;//获取今日天气,get[0] //toString(),get,set自行设置 } DayWeatherBean

接着根据api中data中的属性名选择性封装DayWeatherBean

import java.util.Arrays; /** * TextView tv_city,tv_time,tv_weather,tv_week,tv_tem,tv_tem_low_high,tv_win,tv_air;7个 * ImageView iv_weather;//天气图标 */ public class DayWeatherBean { private String wea;//天气 private String wea_img;//天气图标 private String week;//周几 private String tem;//温度 //tv_tem_low_high=tem2+tem1拼接一起 private String tem2;//低温 private String tem1;//高温 //tv_win=win+win_speed private String[] win;//风力 private String win_speed;//风力等级 //tv_air=air+air_level+air_tips拼接一起 private String air;// private String air_level;// private String air_tips;// //toString(),get,set自行设置 MainActivity

使用handler来异步处理 首先开辟一个子线程,拿到网页数据传给handler

private void getWeather() { // 开启子线程,请求网络 new Thread(new Runnable() { @Override public void run() { // 请求网络 String weatherJson = NetworkUtil.getWeather(); // 使用handler将数据传递给主线程 Message message = Message.obtain(); message.what = 0; message.obj = weatherJson; mHandler.sendMessage(message); } }).start(); }

使用Gson序列化工具前别忘记添加依赖包 implementation 'com.google.code.gson:gson:2.8.5' 添加代码后别忘了构建一下,右上角点一下

private Handler mHandler = new Handler(Looper.myLooper()) { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); if (msg.what == 0) { String weather = (String) msg.obj; Log.d("Main", ">>>>>>原始数据--weather---" + weather); if (TextUtils.isEmpty(weather)) { Toast.makeText(MainActivity.this, "天气数据为空!", Toast.LENGTH_LONG).show(); return; } Gson gson = new Gson();//Gson序列化工具,JsonObject也行,方法不同 WeatherBean weatherBean = gson.fromJson(weather, WeatherBean.class); if (weatherBean != null) { Log.d("Main", ">>>>>>封装数据--weather---" + weatherBean.toString()); } tvCity.setText(weatherBean.getCity()); tvTime.setText(weatherBean.getUpdate_time()); /** * 当天天气 */ dayWeather = weatherBean.getData().get(0); tvWeather.setText(dayWeather.getWea()); tvTem.setText(dayWeather.getTem()); tvTemLowHigh.setText(dayWeather.getTem2()+"/"+dayWeather.getTem1()); tvWeek.setText(dayWeather.getWeek()); tvWin.setText(dayWeather.getWin()[0]+dayWeather.getWin_speed()); tvAir.setText("空气:"+dayWeather.getAir()+" | "+dayWeather.getAir_level()+"\n"+dayWeather.getAir_tips()); ivWeather.setImageResource(WeatherImgUtil.getImgResOfWeather(dayWeather.getWea_img())); //此工具和图片源码中给出 } } };

查看是否获取到数据

源码自取:gitee


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #简易天气app