Android实战:CoolWeather酷欧天气(加强版数据接口)代码详解(下)

本文主要是介绍Android实战:CoolWeather酷欧天气(加强版数据接口)代码详解(下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

-----------------------------------该文章代码已停更,可参考浩比天气(更新于2019/6/25)-----------------------------------
接上篇文章(http://blog.csdn.net/MaybeForever/article/details/78497806)继续,完整文件请从我的GitHub中下载。

目录(下)

文章目录

      • 目录(下)

##四、显示天气信息

1、定义GSON实体类

首先详细分析一下和风天气返回的数据,如下图所示:

这里写图片描述
除了status之外,其余的五个内部又包含具体的内容,因此将basic、aqi、now、suggestion、daily_forecast这五个部分定义成5个实体类。在gson包下建立Basic类、AQI类、Now类、Suggestion类、Forecast类。

Basic类:

public class Basic {@SerializedName("city")public String cityName;//城市名@SerializedName("id")public String weatherId;//城市对应的天气的id@SerializedName("lat")public String cityLat;//城市的经度@SerializedName("lon")public String cityLon;//城市的纬度public Update update;public class Update{@SerializedName("loc")public String updateTime;//接口更新时间}}

AQI类:

public class AQI {public AQICITY city;public class AQICITY{public String aqi;//空气质量指数public String co;//一氧化碳指数public String no2;//二氧化氮指数public String o3;//臭氧指数public String pm10;//PM10指数public String pm25;//PM2.5指数public String qlty;//空气质量(优/良/轻度污染/中度污染/重度污染/严重污染)public String so2;//二氧化硫指数}
}

Forecast类:

public class Forecast {public Astro astro;public class Astro{public String mr;//月升时间public String ms;//月落时间public String sr;//日升时间public String ss;//日落时间}@SerializedName("cond")public More more;public class More{@SerializedName("txt_d")public String info;//白天天气状况描述@SerializedName("txt_n")public String night_info;//晚间天气状况描述}public String date;//预报日期public String pcpn;//降水量public String pop;//降水概率public String pres;//大气压强public String uv;//紫外线强度指数public String vis;//能见度public String hum;//相对湿度@SerializedName("tmp")public Temperature temperature;public class Temperature{public String max;//最高温度public String min;//最低温度}public Wind wind;public class Wind{public String dir;//风向public String sc;//风力public String spd;//风速}}

Now类:

public class Now {@SerializedName("cond")public More more;public class More{@SerializedName("txt")public String info;//天气信息}public String fl;//体感温度public String hum;//相对湿度public String pcpn;//降水量public String pres;//大气压强@SerializedName("tmp")public String temperature;//温度public String vis;//能见度public WIND wind;public class WIND{public String dir;//风向public String sc;//风力public String spd;//风速}
}

Suggestion类:

public Air air;//空气质量指数public class Air{@SerializedName("txt")public String info;}@SerializedName("comf")public Comfort comfort;//舒适度指数public class Comfort{@SerializedName("txt")public String info;}@SerializedName("cw")public CarWash carWash;//洗车指数public class CarWash{@SerializedName("txt")public String info;}public Drsg drsg;//穿衣指数public class Drsg{@SerializedName("txt")public String info;}public Flu flu;//感冒指数public class Flu{@SerializedName("txt")public String info;}public Sport sport;//运动指数public class Sport{@SerializedName("txt")public String info;}public Trav trav;//旅游指数public class Trav{@SerializedName("txt")public String info;}public Uv uv;//紫外线指数public class Uv{@SerializedName("txt")public String info;}
}

在创建五个实体类的过程中,我们使用了@SerializedName() 来命名JSON中的一些字段,由于JSON中的一些字段不适合直接用来使用,因为不好理解,所以可以使用@SerializedName()的方式 ,将JSON字段写在里面,然后在下面一行写上自己需要用的命名(可随意写,只要自己理解就可以)。至此,basic、aqi、now、suggestion、daily_forecast对应的实体类已经创建好,接下来还需要再创建一个总的实体类来引用刚刚创建的各个实体类。在gson包下新建一个Weather类,代码如下:

public class Weather {/*** Weather类作为总的实例类来引用以上各个实体类*/public String status;public Basic basic;public AQI aqi;public Now now;public Suggestion suggestion;@SerializedName("daily_forecast")public List<Forecast> forecastList;
}

在Weather类中,对Basic、AQI、Now、Suggestion、Forecast类进行了引用,由于daily_forecast包含的是一个数组,因此使用List集合来引用Forecast类。此外,除了天气信息数据还会包含一项status数据,成功获取天气数据的时候会返回ok,失败时会返回具体原因。

2、编写天气界面

首先创建一个用于显示天气信息的活动。右击com.coolweather.android包->New->Activity->Empty Activity,创建一个Weather Activity,并将布局名指定成activity_weather.xml。由于所有的天气信息在同一界面上显示会让代码很混乱,所以将界面的不同部分写在不同的布局文件里,再通过引入布局的方式集成到activity_weather.xml中。右击res/layout->New->Layout resource file,新建一个title.xml作为头布局,代码如下所示:

<android.support.percent.PercentFrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="100dp"><Buttonandroid:id="@+id/nav_button"android:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="left|top"app:layout_widthPercent="20%"app:layout_heightPercent="80%"android:background="@drawable/ic_home"/><TextViewandroid:id="@+id/title_city"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center|top"android:gravity="center"app:layout_widthPercent="60%"app:layout_heightPercent="80%"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:id="@+id/title_update_time"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="10dp"android:layout_marginTop="10dp"android:layout_gravity="right|top"app:layout_widthPercent="20%"app:layout_heightPercent="80%"android:textColor="#fff"android:textSize="16sp"/><TextViewandroid:id="@+id/lat_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="30dp"android:layout_gravity="left|bottom"app:layout_widthPercent="50%"app:layout_heightPercent="20%"android:textColor="#fff"android:textSize="16sp"/><TextViewandroid:id="@+id/lon_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="right|bottom"app:layout_widthPercent="50%"app:layout_heightPercent="20%"android:textColor="#fff"android:textSize="16sp"/></android.support.percent.PercentFrameLayout>

title.xml使用了百分比布局的方法,然后新建now.xml作为当前天气信息的布局,代码如下所示:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"android:background="#8000"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:layout_marginTop="15dp"android:text="实时天气信息"android:textColor="#fff"android:textSize="20sp"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextViewandroid:id="@+id/degree_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="温度"android:textColor="#fff" /></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextViewandroid:id="@+id/fl_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="体感温度"android:textColor="#fff" /></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/weather_info_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="天气"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/hum_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="相对湿度"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/dir_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="35sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="风向"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/sc_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="35sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="风力"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/spd_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="风速"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/pcpn_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="降水量"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/pres_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="大气压强"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/vis_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="能见度"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout></LinearLayout>

now.xml使用了相对布局和线性布局的方法,然后新建forecast.xml作为未来几天天气信息的布局,代码如下所示:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"android:background="#8000"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:layout_marginTop="15dp"android:text="预报"android:textColor="#fff"android:textSize="20sp"/><LinearLayoutandroid:id="@+id/forecast_layout"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"></LinearLayout></LinearLayout>

forecast.xml使用了线性布局,还再需要定义一个未来天气的子项布局,创建forecast_item.xml文件,代码如下所示:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><TextViewandroid:id="@+id/date_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="2"android:textColor="#fff"/><TextViewandroid:id="@+id/info_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"android:textColor="#fff" /><TextViewandroid:id="@+id/max_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="right"android:textColor="#fff"/><TextViewandroid:id="@+id/min_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="right"android:textColor="#fff"/><TextViewandroid:id="@+id/dir_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="right"android:textColor="#fff"/><TextViewandroid:id="@+id/sc_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="right"android:textColor="#fff"/>
</LinearLayout>

forecast_item.xml使用线性布局,然后新建aqi.xml作为空气质量信息的布局,代码如下所示:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"android:background="#8000"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:layout_marginTop="15dp"android:text="空气质量"android:textColor="#fff"android:textSize="20sp"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextViewandroid:id="@+id/aqi_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="空气质量指数"android:textColor="#fff" /></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextViewandroid:id="@+id/qlty_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="35sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="空气质量"android:textColor="#fff" /></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/pm25_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="PM2.5指数"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/pm10_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="PM10指数"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/co_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="CO指数"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/no2_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="NO2指数"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/o3_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="O3指数"android:textColor="#fff"/></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"><TextViewandroid:id="@+id/so2_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#fff"android:textSize="40sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="SO2指数"android:textColor="#fff"/></LinearLayout></RelativeLayout></LinearLayout></LinearLayout>

aqi.xml使用了相对布局和线性布局,然后新建suggestion.xml作为生活建议信息的布局,代码如下所示:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="15dp"android:background="#8000"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="15dp"android:layout_marginTop="15dp"android:text="生活建议"android:textColor="#fff"android:textSize="20sp"/><TextViewandroid:id="@+id/air_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/comfort_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/car_wash_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/drsg_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/flu_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/sport_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/trav_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/><TextViewandroid:id="@+id/uv_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:textColor="#fff"/></LinearLayout>

suggestion.xml使用了线性布局,接下来将已编好的每部分布局文件引入到activity_weather.xml当中,代码如下所示:

<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/colorPrimary"><ImageViewandroid:id="@+id/bing_pic_img"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"/><android.support.v4.widget.DrawerLayoutandroid:id="@+id/drawer_layout"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v4.widget.SwipeRefreshLayoutandroid:id="@+id/swipe_refresh"android:layout_width="match_parent"android:layout_height="match_parent"><ScrollViewandroid:id="@+id/weather_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none"android:overScrollMode="never"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"android:fitsSystemWindows="true"><include layout="@layout/title" /><include layout="@layout/now" /><include layout="@layout/forecast" /><include layout="@layout/aqi" /><include layout="@layout/suggestion" /></LinearLayout></ScrollView></android.support.v4.widget.SwipeRefreshLayout><fragmentandroid:id="@+id/choose_area_fragment"android:name="com.coolweather.android.ChooseAreaFragment"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="start"/></android.support.v4.widget.DrawerLayout></FrameLayout>

antivity_weather.xml使用帧布局的布局方式。至此,天气界面就编写完成了。

3、将天气显示到界面上

首先在Utility类中添加一个用于解析天气JSON数据的方法,如下图所示:

这里写图片描述

接下来的工作是再活动中请求天气数据,以及将数据展示到界面上。修改WeatherActivity代码(之前创建了WeatherActivity,会生成activity_weatehr.xml布局文件和WeatherActivity.java文件)。如下所示:

public class WeatherActivity extends AppCompatActivity {public DrawerLayout drawerLayout;private Button navButton;public SwipeRefreshLayout swipeRefresh;private String mWeatherId;private ScrollView weatherLayout;//滚动视图对象private TextView titleCity;//基本信息--城市名private TextView titleUpdateTime;//基本信息--更新时间private TextView titleLat;//基本信息--经度private TextView titleLon;//基本信息--纬度private TextView weatherInfoText;//实时天气信息--天气信息private TextView flText;//实时天气信息--体感温度private TextView humText;//实时天气信息--相对湿度private TextView pcpnText;//实时天气信息--降水量private TextView presText;//实时天气信息--大气压强private TextView degreeText;//实时天气信息--温度private TextView visText;//实时天气信息--能见度private TextView dirText;//实时天气信息--风向private TextView scText;//实时天气信息--风力private TextView spdText;//实时天气信息--风速private LinearLayout forecastLayout;//线性布局对象--预报天气private TextView aqiText;//空气质量--空气质量指数private TextView coText;//空气质量--一氧化碳指数private TextView no2Text;//空气质量--二氧化氮指数private TextView o3Text;//空气质量--臭氧指数private TextView pm10Text;//空气质量--PM10指数private TextView pm25Text;//空气质量--PM2.5指数private TextView qltyText;//空气质量--空气质量水平private TextView so2Text;//空气质量--二氧化硫指数private TextView airText;//生活建议--空气质量指数private TextView comfortText;//生活建议--舒适度指数private TextView carWashText;//生活建议--洗车指数private TextView drsgText;//生活建议--穿衣指数private TextView fluText;//生活建议--感冒指数private TextView sportText;//生活建议--运动指数private TextView travText;//生活建议--旅游指数private TextView uvText;//生活建议--紫外线指数private ImageView bingPicImg;//背景图片@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//版本控制(当系统版本大于等于21,也就是5.0以上系统时才会执行后面的代码)if(Build.VERSION.SDK_INT >= 21){View decorView = getWindow().getDecorView();decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);getWindow().setStatusBarColor(Color.TRANSPARENT);}setContentView(R.layout.activity_weather);//初始化各控件bingPicImg = (ImageView)findViewById(R.id.bing_pic_img);//背景图片weatherLayout = (ScrollView) findViewById(R.id.weather_layout);//滚动视图对象titleCity = (TextView) findViewById(R.id.title_city);//基本信息--城市titleUpdateTime = (TextView) findViewById(R.id.title_update_time);//基本信息--更新时间titleLat = (TextView) findViewById(R.id.lat_text);//基本信息--经度titleLon = (TextView) findViewById(R.id.lon_text);//基本信息--纬度weatherInfoText = (TextView) findViewById(R.id.weather_info_text);//实时天气信息--天气信息flText = (TextView) findViewById(R.id.fl_text) ;//实时天气信息--体感温度humText = (TextView) findViewById(R.id.hum_text);//实时天气信息--相对湿度pcpnText = (TextView) findViewById(R.id.pcpn_text);//实时天气信息--降水量presText = (TextView) findViewById(R.id.pres_text); //实时天气信息--大气压强degreeText = (TextView) findViewById(R.id.degree_text);//实时天气信息--温度visText = (TextView) findViewById(R.id.vis_text);//实时天气信息--能见度dirText = (TextView) findViewById(R.id.dir_text);//实时天气信息--风向scText = (TextView) findViewById(R.id.sc_text);//实时天气信息--风力spdText = (TextView) findViewById(R.id.spd_text); //实时天气信息--风速forecastLayout = (LinearLayout) findViewById(R.id.forecast_layout);//线性布局对象--预报天气aqiText = (TextView) findViewById(R.id.aqi_text);//空气质量--空气质量指数coText = (TextView) findViewById(R.id.co_text);//空气质量--一氧化碳指数no2Text = (TextView) findViewById(R.id.no2_text);//空气质量--二氧化氮指数o3Text = (TextView) findViewById(R.id.o3_text);//空气质量--臭氧指数pm10Text = (TextView) findViewById(R.id.pm10_text); //空气质量--PM10指数pm25Text = (TextView) findViewById(R.id.pm25_text);//空气质量--PM2.5指数qltyText = (TextView) findViewById(R.id.qlty_text);//空气质量--空气质量水平so2Text = (TextView) findViewById(R.id.so2_text); //空气质量--二氧化硫指数airText = (TextView) findViewById(R.id.air_text); //生活建议--空气质量指数comfortText = (TextView) findViewById(R.id.comfort_text);//生活建议--舒适度指数carWashText = (TextView) findViewById(R.id.car_wash_text);//生活建议--洗车指数drsgText = (TextView) findViewById(R.id.drsg_text);//生活建议--穿衣指数fluText = (TextView) findViewById(R.id.flu_text); //生活建议--感冒指数sportText = (TextView) findViewById(R.id.sport_text);//生活建议--运动指数travText = (TextView) findViewById(R.id.trav_text);//生活建议--旅游指数uvText = (TextView) findViewById(R.id.uv_text);//生活建议--紫外线指数drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);//DrawerLayout实例navButton = (Button) findViewById(R.id.nav_button);//Button实例swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);//获取SwipeRefreshLayout的实例swipeRefresh.setColorSchemeResources(R.color.colorPrimary);//调用setColorSchemeResources()方法来设置下拉刷新进度条的颜色SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);String weatherString = prefs.getString("weather", null);if(weatherString != null){//有缓存时直接解析天气数据Weather weather = Utility.handleWeatherResponse(weatherString);mWeatherId = weather.basic.weatherId;showWeatherInfo(weather);}else{//无缓存时去服务器查询天气mWeatherId = getIntent().getStringExtra("weather_id");//在请求数据的时候将ScrollView()隐藏weatherLayout.setVisibility(View.INVISIBLE);//从服务器请求天气数据requestWeather(mWeatherId);}//设置下拉刷新监听器swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){@Overridepublic void onRefresh() {requestWeather(mWeatherId);//请求天气信息}});String bingPic = prefs.getString("bing_pic",null);if(bingPic != null){//如果有缓存数据就直接使用Glide来加载这张图片Glide.with(this).load(bingPic).into(bingPicImg);}else{//如果没有缓存数据就调用loadBingPic()方法去请求今日的必应背景图loadBingPic();//加载每日一图}//请求新选择城市的天气信息navButton.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v) {drawerLayout.openDrawer(GravityCompat.START);}});}/*** 根据天气ID请求城市天气信息*/public void requestWeather(final String weatherId){//组装接口地址String weatherUrl = "http://guolin.tech/api/weather?cityid=" + weatherId + "&key=8518f3bef50144e39994370699b08d5e";//向组装好的地址发送请求,服务器会将相应城市的天气信息以JSON()格式返回HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() {@Overridepublic void onResponse(Call call, Response response) throws IOException {final String responseText = response.body().string();//将返回的JSON数据转换成Weather对象final Weather weather = Utility.handleWeatherResponse(responseText);//将当前线程切换到主线程runOnUiThread(new Runnable() {@Overridepublic void run() {if(weather != null && "ok".equals(weather.status)){//请求天气成功//将返回的数据缓存到SharedPreferences当中SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();editor.putString("weather", responseText);editor.apply();mWeatherId = weather.basic.weatherId;//调用showWeatherInfo()方法进行内容显示showWeatherInfo(weather);}else{Toast.makeText(WeatherActivity.this,"获取天气信息失败",Toast.LENGTH_SHORT).show();}swipeRefresh.setRefreshing(false);//刷新事件结束,将进度条隐藏起来}});//每次请求天气信息的时候也会刷新背景图片loadBingPic();}@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(WeatherActivity.this,"获取天气信息失败",Toast.LENGTH_SHORT).show();swipeRefresh.setRefreshing(false);//刷新事件结束,将进度条隐藏起来}});}});loadBingPic();//加载每日一图}/*** 加载必应每日一图*/private void loadBingPic(){String requestBingPic = "http://guolin.tech/api/bing_pic";//调用HttpUtil.sendOkHttpRequest()方法获取必应背景图的链接HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {final String bingPic = response.body().string();//将链接缓存到SharedPreferences当中SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();editor.putString("bing_pic",bingPic);editor.apply();//将线程切换到主线程runOnUiThread(new Runnable() {@Overridepublic void run() {//使用Glide来加载图片Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);}});}});}/*** 处理并展示Weather实体类中的数据*/private void showWeatherInfo(Weather weather){String cityName = weather.basic.cityName;String updateTime = "更新时间:"+weather.basic.update.updateTime.split(" ")[1];String lat = "经度:"+weather.basic.cityLat;String lon = "纬度:"+weather.basic.cityLon;titleCity.setText(cityName);titleUpdateTime.setText(updateTime);titleLat.setText(lat);titleLon.setText(lon);String weatherInfo = weather.now.more.info;String flInfo = weather.now.fl + "℃";String humInfo = weather.now.hum;String pcpnInfo = weather.now.pcpn + "mm";String presInfo = weather.now.pres + "Pa";String degree = weather.now.temperature + "℃";String visInfo = weather.now.vis;String dirInfo = weather.now.wind.dir;String scInfo = weather.now.wind.sc;String spdInfo = weather.now.wind.spd + "m/s";weatherInfoText.setText(weatherInfo);flText.setText(flInfo);humText.setText(humInfo);pcpnText.setText(pcpnInfo);presText.setText(presInfo);degreeText.setText(degree);visText.setText(visInfo);dirText.setText(dirInfo);scText.setText(scInfo);spdText.setText(spdInfo);forecastLayout.removeAllViews();for(Forecast forecast : weather.forecastList){View view = LayoutInflater.from(this).inflate(R.layout.forecast_item,forecastLayout,false);TextView dateText = (TextView)view.findViewById(R.id.date_text);TextView infoText = (TextView)view.findViewById(R.id.info_text);TextView maxText = (TextView)view.findViewById(R.id.max_text);TextView minText = (TextView)view.findViewById(R.id.min_text);TextView dirText = (TextView)view.findViewById(R.id.dir_text);TextView scText = (TextView)view.findViewById(R.id.sc_text);dateText.setText(forecast.date);infoText.setText(forecast.more.info);maxText.setText(forecast.temperature.max);minText.setText(forecast.temperature.min);dirText.setText(forecast.wind.dir);scText.setText(forecast.wind.sc);forecastLayout.addView(view);}if(weather.aqi != null){aqiText.setText(weather.aqi.city.aqi);coText.setText(weather.aqi.city.co);no2Text.setText(weather.aqi.city.no2);o3Text.setText(weather.aqi.city.o3);pm10Text.setText(weather.aqi.city.pm10);pm25Text.setText(weather.aqi.city.pm25);qltyText.setText(weather.aqi.city.qlty);so2Text.setText(weather.aqi.city.so2);}String air = "空气质量:"+weather.suggestion.air.info;String comfort = "舒适度:"+weather.suggestion.comfort.info;String carWash = "洗车指数:"+weather.suggestion.carWash.info;String drsg = "穿衣指数:"+weather.suggestion.drsg.info;String flu = "感冒指数:"+weather.suggestion.flu.info;String sport = "运动建议:"+weather.suggestion.sport.info;String trav = "旅游指数:"+weather.suggestion.trav.info;String uv = "紫外线指数:"+weather.suggestion.uv.info;airText.setText(air);comfortText.setText(comfort);carWashText.setText(carWash);drsgText.setText(drsg);fluText.setText(flu);sportText.setText(sport);travText.setText(trav);uvText.setText(uv);//在设置完所有数据后,再将ScrollView设为可见weatherLayout.setVisibility(View.VISIBLE);//激活AutoUpdateService这个服务,只要选中了某个城市并成功更新天气之后,// AutoUpdateService就会一直在后台运行,并保证每8个小时更新一次天气Intent intent = new Intent(this, AutoUpdateService.class);startService(intent);}}

这个活动的详细分析在代码注释里已给出,接下来就是从省市县列表的界面跳转到天气界面,修改ChooseAreaFragment中的代码,如下所示:

这里写图片描述
另外,还需要在MainActivity中加入一个缓存数据判断,修改MainActivity中的代码,如下所示:

这里写图片描述

4、获取必应每日一图

使用郭霖大神准备的每日一图接口:http://guolin.tech/api/bing_pic ,访问这个接口,服务器就会返回今日的必应背景图链接,然后我们再使用Glide去加载这张图片。首先修改activity_weather.xml中的代码。如下所示:

这里写图片描述

接着修改WeatherActivity中的代码,如下所示:

这里写图片描述

这里写图片描述

 /*** 加载必应每日一图*/private void loadBingPic(){String requestBingPic = "http://guolin.tech/api/bing_pic";//调用HttpUtil.sendOkHttpRequest()方法获取必应背景图的链接HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {final String bingPic = response.body().string();//将链接缓存到SharedPreferences当中SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();editor.putString("bing_pic",bingPic);editor.apply();//将线程切换到主线程runOnUiThread(new Runnable() {@Overridepublic void run() {//使用Glide来加载图片Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);}});}});}

再添加版本控制的代码,如下图所示:

这里写图片描述

##五、手动更新天气和切换城市

1、手动更新天气

采用下拉刷新的方式更新事件,首先修改activity_weather.xml中的代码,如下图:

这里写图片描述

然后修改WeatherActivity中的代码,加入更新天气的处理逻辑:

这里写图片描述

这里写图片描述

2、切换城市
将天气的布局引入碎片,再将碎片放入滑动菜单,在正常情况下,它不占据主界面的任何空间,想要切换城市的时候只需要通过滑动的方式将菜单显示出来就可以了。此外,我们在头布局添加一个切换城市的按钮。修改title.xml中的代码,如下所示:

这里写图片描述

接着修改activity_weather.xml布局来加入滑动菜单功能,如下所示:

这里写图片描述

接下来需要在WeatherActivity中加入滑动菜单的逻辑处理,修改WeatherActivity中的代码。如下所示:

这里写图片描述

打开滑动菜单后需要根据选择的不同状态来进行不同的逻辑,修改ChooseAreaFragment中的代码,如下所示:

这里写图片描述

这样就把切换城市的功能全部完成了。

##六、后台自动更新天气

首先在service包下新建一个服务,右击com.coolweather.android.service->New->Service->Service,创建一个AutoUpdateService,并将Exported和Enable这两个属性都选中,然后修改AutoUpdateService中的代码,如下所示:

public class AutoUpdateService extends Service {@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {updateWeather();updateBingPic();AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);int anHour = 8 * 60 * 60 * 1000;//8小时的毫秒数long triggerAtTime = SystemClock.elapsedRealtime() + anHour;Intent i = new Intent(this, AutoUpdateService.class);PendingIntent pi = PendingIntent.getService(this,0,i,0);manager.cancel(pi);manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);return super.onStartCommand(intent,flags,startId);}/*** 更新天气信息*/private void updateWeather(){//将更新后的数据存储在SharedPreferences文件中,打开WeatherActivity的时候会优先从SharedPreferences缓存中读取数据SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);String weatherString = prefs.getString("weather",null);if(weatherString != null){//有缓存时直接解析天气数据Weather weather = Utility.handleWeatherResponse(weatherString);String weatherId = weather.basic.weatherId;String weatherUrl = "http://guolin.tech/api/weather?cityid=?"+weatherId+"&key=8518f3bef50144e39994370699b08d5e";HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {String responseText = response.body().string();Weather weather = Utility.handleWeatherResponse(responseText);if(weather != null && "ok".equals(weather.status)){SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(AutoUpdateService.this).edit();editor.putString("weather",responseText);editor.apply();}}});}}/*** 更新必应每日一图*/private void updateBingPic(){String requestBingPic = "Http://guolin.tech/api/bing_pic";HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {String bingPic = response.body().string();SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(AutoUpdateService.this).edit();editor.putString("bing_pic",bingPic);editor.apply();}});}
}

然后激活这段代码,修改WeatherActivity中的代码,如下所示:

这里写图片描述

##七、修改图标和名称

自己准备好一张图片来作为软件图标,将这张图片命名为logo.png,放入所有以mipmap开头的目录下,然后修改AndroidManifest.xml中的代码,如下所示:

这里写图片描述

接下来修改程序名称。打开res/values/sring.xml文件,如下:

这里写图片描述

至此,软件就基本完成了。界面效果如下:
这里写图片描述

这篇关于Android实战:CoolWeather酷欧天气(加强版数据接口)代码详解(下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/249448

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为