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

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

源码:github

简述

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

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

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

注意

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

接着,访问此url结果如图,一长串的json数据
json数据如果你的浏览器支持转为json格式,那么会得到更清晰的数据格式,方便后续对其进行封装,也可百度在线json格式化工具,复制原始数据进去,得到格式化jsn数据
json格式1观察上图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" />

andxml

布局文件

接着就是布局,随意,怎么好看怎么来,无非就是接受几个数据传给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

  • 12
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roydon_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值