一个天气预报APP至少应该具备以下功能:

  *可以罗列出全国所有的省、市、县;

  *可以查看全国任意城市的天气信息;

  *可以自由的切换城市,去查看其他城市的天气;

  *提供手动更新以及后台自动更新天气的功能;

这里使用和风天气作为天气预报来源,全国省市县的数据信息这里使用的是《第一行代码》的作者郭霖大佬架设的服务器。  

具体就是:想要罗列出中国所有的省份,只需要访问这个地址:http://guolin.tech/api/china,服务器会返回一段JSON格式的数据,其中包括了中国所有省份的名称及省份的id:

  [{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"天津"},

  {"id":4,"name":"重庆"},{"id":5,"name":"香港"},{"id":6,"name":"澳门"},
  {"id":7,"name":"台湾"},{"id":8,"name":"黑龙江"},{"id":9,"name":"吉林"},
  {"id":10,"name":"辽宁"},{"id":11,"name":"内蒙古"},{"id":12,"name":"河北"},
  {"id":13,"name":"河南"},{"id":14,"name":"山西"},{"id":15,"name":"山东"},
  {"id":16,"name":"江苏"},{"id":17,"name":"浙江"},{"id":18,"name":"福建"},
  {"id":19,"name":"江西"},{"id":20,"name":"安徽"},{"id":21,"name":"湖北"},
  {"id":22,"name":"湖南"},{"id":23,"name":"广东"},{"id":24,"name":"广西"},
  {"id":25,"name":"海南"},{"id":26,"name":"贵州"},{"id":27,"name":"云南"},
  {"id":28,"name":"四川"},{"id":29,"name":"西藏"},{"id":30,"name":"陕西"},
  {"id":31,"name":"宁夏"},{"id":32,"name":"甘肃"},{"id":33,"name":"青海"},
  {"id":34,"name":"新疆"}]

如果想要河北省有那些城市,就把id加上:http://guolin.tech/api/china/12

  [{"id":57,"name":"石家庄"},{"id":58,"name":"保定"},{"id":59,"name":"张家口"},
  {"id":60,"name":"唐山"},{"id":61,"name":"廊坊"},{"id":62,"name":"沧州"},
  {"id":63,"name":"衡水"},{"id":64,"name":"邢台"},{"id":65,"name":"邯郸"},
  {"id":66,"name":"秦皇岛"}]

如果想要知道秦皇岛有那些县,就再加上id:http://guolin.tech/api/china/12/66

[{"id":557,"name":"秦皇岛","weather_id":"CN101091101"},{"id":558,"name":"青龙","weather_id":"CN101091102"},

{"id":559,"name":"昌黎","weather_id":"CN101091103"},{"id":560,"name":"抚宁","weather_id":"CN101091104"},

{"id":561,"name":"卢龙","weather_id":"CN101091105"},{"id":562,"name":"北戴河","weather_id":"CN101091106"}]

以上是全国省市县的数据,然后是天气数据的api的使用:

https://free-api.heweather.com/v5/weather?city=yourcity&key=yourkey

这是一个免费的使用方法,一天可以访问4000次,不过要先申请。yourcity部分就填之前获取到的id即可,key的话申请就有了。

https://free-api.heweather.com/v5/weather?city=CN101091101&key=32d1c829ed7d483086f4f5b4d5947cef

这样就能查询到秦皇岛的天气情况,返回的数据就比较复杂了,官方的例子就是:

{
"HeWeather5": [
{
"alarms": [
{
"level": "蓝色",
"stat": "预警中",
"title": "山东省青岛市气象台发布大风蓝色预警",
"txt": "青岛市气象台2016年08月29日15时24分继续发布大风蓝色预警信号:预计今天下午到明天,我市北风风力海上6到7级阵风9级,陆地4到5阵风7级,请注意防范。",
"type": "大风"
}
],
"aqi": {
"city": {
"aqi": "60",
"co": "0",
"no2": "14",
"o3": "95",
"pm10": "67",
"pm25": "15",
"qlty": "良", //共六个级别,分别:优,良,轻度污染,中度污染,重度污染,严重污染
"so2": "10"
}
},
"basic": {
"city": "青岛",
"cnty": "中国",
"id": "CN101120201",
"lat": "36.088000",
"lon": "120.343000",
"prov": "山东" //城市所属省份(仅限国内城市)
"update": {
"loc": "2016-08-30 11:52",
"utc": "2016-08-30 03:52"
}
},
"daily_forecast": [
{
"astro": {
"mr": "03:09",
"ms": "17:06",
"sr": "05:28",
"ss": "18:29"
},
"cond": {
"code_d": "100",
"code_n": "100",
"txt_d": "晴",
"txt_n": "晴"
},
"date": "2016-08-30",
"hum": "45",
"pcpn": "0.0",
"pop": "8",
"pres": "1005",
"tmp": {
"max": "29",
"min": "22"
},
"vis": "10",
"wind": {
"deg": "339",
"dir": "北风",
"sc": "4-5",
"spd": "24"
}
}
],
"hourly_forecast": [
{
"cond": {
"code": "100",
"txt": "晴"
},
"date": "2016-08-30 12:00",
"hum": "47",
"pop": "0",
"pres": "1006",
"tmp": "29",
"wind": {
"deg": "335",
"dir": "西北风",
"sc": "4-5",
"spd": "36"
}
}
],
"now": {
"cond": {
"code": "100",
"txt": "晴"
},
"fl": "28",
"hum": "41",
"pcpn": "0",
"pres": "1005",
"tmp": "26",
"vis": "10",
"wind": {
"deg": "330",
"dir": "西北风",
"sc": "6-7",
"spd": "34"
}
},
"status": "ok",
"suggestion": {
"comf": {
"brf": "较舒适",
"txt": "白天天气晴好,您在这种天气条件下,会感觉早晚凉爽、舒适,午后偏热。"
},
"cw": {
"brf": "较不宜",
"txt": "较不宜洗车,未来一天无雨,风力较大,如果执意擦洗汽车,要做好蒙上污垢的心理准备。"
},
"drsg": {
"brf": "热",
"txt": "天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"
},
"flu": {
"brf": "较易发",
"txt": "虽然温度适宜但风力较大,仍较易发生感冒,体质较弱的朋友请注意适当防护。"
},
"sport": {
"brf": "较适宜",
"txt": "天气较好,但风力较大,推荐您进行室内运动,若在户外运动请注意防风。"
},
"trav": {
"brf": "适宜",
"txt": "天气较好,风稍大,但温度适宜,是个好天气哦。适宜旅游,您可以尽情地享受大自然的无限风光。"
},
"uv": {
"brf": "强",
"txt": "紫外线辐射强,建议涂擦SPF20左右、PA++的防晒护肤品。避免在10点至14点暴露于日光下。"
}
}
}
]
}

数据返回示例

首先是这次项目需要依赖的库的声明:

    compile 'org.litepal.android:core:1.6.0'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.github.bumptech.glide:glide:4.0.0'

  Litepal用于数据库操作。OkHttp用于进行网络请求,GSON用于解析获得的JSON数据,Glide用于加载展示图片

1、建立数据库和表

先建三张表,分别是省,市,县:

Province:

public class Province extends DataSupport {

    private int id;

    private String provinceName;//省的名字

    private int provinceCode;//省的代号

    public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getProvinceName() {
return provinceName;
} public void setProvinceName(String provinceName) {
this.provinceName = provinceName;
} public int getProvinceCode() {
return provinceCode;
} public void setProvinceCode(int provinceCode) {
this.provinceCode = provinceCode;
}
}

省的数据信息

City:

public class City extends DataSupport {

    private int id;

    private String cityName;//城市的名字

    private int cityCode;//城市的代号

    private int provinceId;//城市所在省的id值

    public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getCityName() {
return cityName;
} public void setCityName(String cityName) {
this.cityName = cityName;
} public int getCityCode() {
return cityCode;
} public void setCityCode(int cityCode) {
this.cityCode = cityCode;
} public int getProvinceId() {
return provinceId;
} public void setProvinceId(int provinceId) {
this.provinceId = provinceId;
}
}

市的数据信息

County:

public class County extends DataSupport {

    private int id;

    private String countyName;//县的名字

    private String weatherId;//天气的id

    private int cityId;//所属市的id

    public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getCountyName() {
return countyName;
} public void setCountyName(String countyName) {
this.countyName = countyName;
} public String getWeatherId() {
return weatherId;
} public void setWeatherId(String weatherId) {
this.weatherId = weatherId;
} public int getCityId() {
return cityId;
} public void setCityId(int cityId) {
this.cityId = cityId;
}
}

县的数据信息

然后是Litepal的建表操作,在app/src/main目录下新建assets目录,在其中新建Litepal.xml文件

<?xml version="1.0" encoding="utf-8"?>
<litepal> <dbname value = "cool_weather"></dbname> <version value = "1"></version> <list>
<mapping class = "xbt.exp20.db.Province"></mapping>
<mapping class = "xbt.exp20.db.City"></mapping>
<mapping class = "xbt.exp20.db.County"></mapping>
</list> </litepal>

再然后是配置LitepalApplication:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xbt.exp20">
...
<application
android:name="org.litepal.LitePalApplication"
...
</application> </manifest>

这样三个类加上Litepal的配置,数据库和表会在首次执行任意数据库操作的时候自动创建。

2、遍历全国省市县数据

首先是新建一个HttpUtil类:

/**
* 发起一条HTTP请求,传入地址,并注册一个回调来处理服务器响应
*/ public class HttpUtil { public static void sendOkHttpRequest(String address, okhttp3.Callback callback){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(address).build();
client.newCall(request).enqueue(callback);
}
}

然后是一个Utility类:

public class Utility {
/**
*解析和处理服务器返回的省级数据
*/
public static boolean handleProvinceResponse(String response){ if(!TextUtils.isEmpty(response)){
//如果字符序列不为空或长度为0
try{
JSONArray allProvinces = new JSONArray(response);
for(int i = 0; i < allProvinces.length(); i++){
JSONObject provinceObject = allProvinces.getJSONObject(i);
Province province = new Province();
province.setProvinceName(provinceObject.getString("name"));
province.setProvinceCode(provinceObject.getInt("id"));
province.save();
}
return true;
}catch (JSONException e){
e.printStackTrace();
}
}
return false;
} /**
*解析和处理服务器返回的市级数据
*/
public static boolean handleCityResponse(String response, int provinceId){ if(!TextUtils.isEmpty(response)){
//如果字符序列不为空或长度为0
try{
JSONArray allCities = new JSONArray(response);
for(int i = 0; i < allCities.length(); i++){
JSONObject CityObject = allCities.getJSONObject(i);
City city = new City();
city.setCityName(CityObject.getString("name"));
city.setCityCode(CityObject.getInt("id"));
city.setProvinceId(provinceId);
city.save();
}
return true;
}catch (JSONException e){
e.printStackTrace();
}
}
return false;
} /**
*解析和处理服务器返回的县级数据
*/
public static boolean handleCountyResponse(String response, int cityId){ if(!TextUtils.isEmpty(response)){
//如果字符序列不为空或长度为0
try{
JSONArray allCounties = new JSONArray(response);
for(int i = 0; i < allCounties.length(); i++){
JSONObject countyObject = allCounties.getJSONObject(i);
County county = new County();
county.setCountyName(countyObject.getString("name"));
county.setWeatherId(countyObject.getString("weather_id"));
county.setCityId(cityId);
county.save();
}
return true;
}catch (JSONException e){
e.printStackTrace();
}
}
return false;
}
}

解析处理数据

因为遍历全国省市的功能经常复用,所以写在碎片里面:

  先是一个choose_area.xml作为碎片fragment的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary">
<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#fff"
android:textSize="20sp"/>
<Button
android:id="@+id/back_button"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_back"/>
</RelativeLayout> <ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</LinearLayout>

fragment的布局

一个标题栏和一个滚动控件ListView,标题栏是一个RelativeLayout,拥有一个文字标题,一个按钮

然后是fragment的java代码

/**
* Created by xbt on 2017/9/8.
* 用于遍历省市县数据的碎片
*/ public class ChooseAreaFragment extends android.support.v4.app.Fragment { public static final int LEVEL_PROVINCE = 0; public static final int LEVEL_CITY = 1; public static final int LEVEL_COUNTY = 2; private ProgressBar progressDialog; private TextView titleText; private Button backButton; private ListView listView; private ArrayAdapter<String> adapter; private List<String> dataList = new ArrayList<>(); /**
* 省列表
*/
private List<Province> provinceList; /**
* 市列表
*/
private List<City> cityList; /**
* 县列表
*/
private List<County> countyList; /**
* 选中的省份
*/
private Province selectedProvince; /**
* 选中的城市
*/
private City selectedCity; /**
* 选中的县
*/
private County selectedCounty; /**
* 当前被选中的级别
*/
private int currentLevel; @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.choose_area,container,false);
titleText = (TextView) view.findViewById(R.id.title_text);
backButton = (Button) view.findViewById(R.id.back_button);
listView = (ListView) view.findViewById(R.id.list_view);
adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1,dataList);
listView.setAdapter(adapter);
return view;
} public void onActivityCreated( Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if(currentLevel == LEVEL_PROVINCE){
selectedProvince = provinceList.get(position);
queryCities();
}else if(currentLevel == LEVEL_CITY){
selectedCity = cityList.get(position);
queryCounties();
}
}
});
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(currentLevel == LEVEL_COUNTY){
queryCities();
}else if(currentLevel == LEVEL_CITY){
queryProvinces();
}
}
});
queryProvinces();
} /**
* 查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
*/
private void queryProvinces(){
titleText.setText("中国");
backButton.setVisibility(View.GONE);
provinceList = DataSupport.findAll(Province.class);
if(provinceList.size() > 0){
dataList.clear();
for (Province province : provinceList){
dataList.add(province.getProvinceName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_PROVINCE;
}else {
String address = "http://guolin.tech/api/china";
queryFromServer(address, "province");
}
} /**
* 查询全国所有的市,优先从数据库查询,如果没有查到再去服务器上查询
*/
private void queryCities(){
titleText.setText(selectedProvince.getProvinceName());
backButton.setVisibility(View.VISIBLE);
cityList = DataSupport.where("provinceid = ?", String.valueOf(selectedProvince.getId())).find(City.class);
if(cityList.size() > 0){
dataList.clear();
for (City city : cityList){
dataList.add(city.getCityName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_CITY;
}else {
int provinceCode = selectedProvince.getProvinceCode();
String address = "http://guolin.tech/api/china/" + provinceCode;
queryFromServer(address, "city");
}
} /**
* 查询全国所有的县,优先从数据库查询,如果没有查到再去服务器上查询
*/
private void queryCounties(){
titleText.setText(selectedCity.getCityName());
backButton.setVisibility(View.VISIBLE);
countyList = DataSupport.where("cityid = ?", String.valueOf(selectedCity.getId())).find(County.class);
if(countyList.size() > 0){
dataList.clear();
for (County county : countyList){
dataList.add(county.getCountyName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
currentLevel = LEVEL_COUNTY;
}else {
int cityCode = selectedCity.getCityCode();
int provinceCode = selectedProvince.getProvinceCode();
String address = "http://guolin.tech/api/china/" + provinceCode + "/" + cityCode;
queryFromServer(address, "county");
}
} /**
* 根据传入的地址和类型从服务器上查询省市县的数据
*/
private void queryFromServer(String address, final String type){
HttpUtil.sendOkHttpRequest(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//通过runOnUiThread回到主线程处理逻辑
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(),"加载失败",Toast.LENGTH_SHORT).show();
}
});
} @Override
public void onResponse(Call call, Response response) throws IOException {
String responseText = response.body().string();
boolean result = false;
if("province".equals(type)){
result = Utility.handleProvinceResponse(responseText);
}else if("city".equals(type)){
result = Utility.handleCityResponse(responseText, selectedProvince.getId());
}else if("county".equals(type)){
result = Utility.handleCountyResponse(responseText,selectedCity.getId());
}
if(result){
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if("province".equals(type)){
queryProvinces();
}else if("city".equals(type)){
queryCities();
}else if("county".equals(type)){
queryCounties();
}
}
});
}
}
});
}
}

遍历全国省市县的碎片java代码

这段代码的大概逻辑就是其中的这个方法:注释写的格外仔细了些

    public void onActivityCreated( Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); //列表的点击事件响应
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
//如果当前级别是省,那点击选取的就是某个省,而想要查询的是选中省有那些城市,市同理 ,想要查询这个城市有那些县
if(currentLevel == LEVEL_PROVINCE){
selectedProvince = provinceList.get(position);
queryCities();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}else if(currentLevel == LEVEL_CITY){
selectedCity = cityList.get(position);
queryCounties();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}
}
}); //返回按钮响应
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//如果当前级别是市,点击返回就是想重新选省,县同理,想重新选市
if(currentLevel == LEVEL_COUNTY){
queryCities();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}else if(currentLevel == LEVEL_CITY){
queryProvinces();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}
}
});
queryProvinces();//活动刚启动,没有选取省市县就直接展示全国34个省
}

结果:

天气预报APP(1)的更多相关文章

  1. 毕业设计--天气预报App

    9月中旬,开始动手做我的毕业设计了,之前一直在纠结做啥,后来想想,既然是做毕业设计,那就大胆地做点自己没接触过的东西吧.然后网上查找资料得知做天气预报需要用到开放的API,而且要用那种现在还在维护的, ...

  2. android入门学习-天气预报app(一)

    引言 学习<android第一行代码>根据书本开发的天气预报app,主要用于熟练操作android开发(android studio3.0平台). 今天主要分享一下从服务器上获取天气信息, ...

  3. 用Swift实现一款天气预报APP(三)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 通过前面的学习,一个天气预报的APP已经基本可用了.至少 ...

  4. 用Swift实现一款天气预报APP(二)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 上篇中主要讲了界面的一些内容,这篇主要讨论网络请求,获得 ...

  5. 用Swift实现一款天气预报APP(一)

    这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) Swift作为现在苹果极力推广的语言,发展的非常快.这个 ...

  6. 基于Android开发的天气预报app(源码下载)

    原文:基于Android开发的天气预报app(源码下载) 基于AndroidStudio环境开发的天气app -系统总体介绍:本天气app使用AndroidStudio这个IDE工具在Windows1 ...

  7. 69.Android之天气预报app

    最近买了本书<Android第一行代码>,通篇看了下感觉不错,书本最后有个实战项目酷欧天气,闲来无事就照着敲了一遍代码,主要在请求天气接口和背景优化做了些小改动,现在来记录下. (1) a ...

  8. 2.15 学习总结 之 天气预报APP volley(HTTP库)之StringRequest

    一.说在前面   昨天 学习了序列化的相关知识   今天 1.学习 volley(HTTP库)的 StringRequest请求 2.使用序列化完成相关案例 遇到问题 请求到的参数的出现中文乱码问题 ...

  9. 天气预报APP(2)

    之前实现了能够罗列可以罗列出全国所有的省.市.县,然后就是查询全国任意城市的天气信息.查询天气信息使用的是和风天气的api,这个api获得的天气信息是JSON格式的. 使用GSON库解析JSON数据的 ...

随机推荐

  1. 浅入深出Vue:第一个页面

    今天正式开始入门篇,也就是实战了~ 首先我们是要做一个博客网站,UI 框架采用江湖传闻中的 ElementUI,今天我们就来利用它确定我们博客网站的基本布局吧. 准备工作 新建一个vue项目(可以参考 ...

  2. (ps2018)Adobe Photoshop CC 2018 中文版破解版

    ps2018新功能 1.更紧密连接的 Photoshop.全新的智慧型锐利化. 2.智慧型增加取样.内含 Extended 功能.Camera RAW 8 和图层支援 3.可编辑的圆角矩形.多重形状和 ...

  3. Java学习笔记之---构造方法

    Java学习笔记之---构造方法 (一)构造方法的特性 构造方法不能被对象单独调用 构造方法与类同名且没有返回值 构造方法只能在对象实例化的时候被调用 当没有指定构造方法时,系统会自动添加无参的构造方 ...

  4. 新手上路——it人如何保持竞争力

    新手上路——如何保持竞争力 JINGZHENGLI 套用葛大爷的一句名言:21世纪什么最贵,人才.哪你是人才还是人材?还是人财或人裁?相信大家都不是最后一种.何如保持住这个光环呢?就需要我们保持我们独 ...

  5. Oracle修改字段类型报错:“ORA-01439:要更改数据类型,则要修改的列必须为空”

    在oracle修改user表字段name类型时遇到报错:“ORA-01439:要更改数据类型,则要修改的列必须为空”,是因为要修改字段的新类型和原来的类型不兼容. 如果要修改的字段数据为空时,则不会报 ...

  6. PostgreSQL 窗口函数 ( Window Functions ) 如何使用?

    一.为什么要有窗口函数 我们直接用例子来说明,这里有一张学生考试成绩表testScore: 现在有个需求,需要查询的时候多出一列subject_avg_score,为此科目所有人的平均成绩,好跟每个人 ...

  7. I/O:Writer

    Writer: Writer append(char c) :将指定字符添加到此 writer. Writer append(CharSequence csq) :将指定字符序列添加到此 writer ...

  8. 快速掌握mongoDB(五)——通过mongofiles和C#驱动操作GridFS

    1 GridFS简介 当前Bson能存储的最大尺寸是16M,我们想把大于16M的文件存入mongoDB中怎么办呢?mongoDB提供的GridFS就是专门做这个的.使用GridFS存储大文件时,文件被 ...

  9. python基础-python解释器多版本共存-变量-常量

    一.编程语言的发展史 机器语言-->汇编语言-->高级语言,学习难度及执行效率由高到低,开发效率由低到高 机器语言:二进制编程,0101 汇编语言:用英文字符来代替0101编程 高级语言: ...

  10. flex布局知识总结

    flex-direction:决定主轴的排列方向flex-wrap:项目都排列在一条轴线上,若排不下,如何换行flex-flow=flex-direction+flex-wrap align-item ...