第7讲 Android网络与数据存储
项目要求:做一个天气应用
a) 参考接口:http://www.weather.com.cn/data/list3/city.xml
b) 考察内容:获取数据,解析JSON
c) 数据缓存在数据库中,使用SharedPreferences来处理,采用手动刷新数据。
7.1 项目总体结构
为了规范代码,进行了如下的分包。
7.2 创建数据库与表
db 包下文件分别是创建数据库和对数据库的操作:数据库结构如下图
省份表
选中的城市表
选中的区县表
对数据库常用操作封装类结构如下:
/**
* Created by Administrator on 2016/6/20.
*/
public class WeatherDB {
//定义数据库名
public static final String DB_NAME ="weather";
//定义数据库版本号
public static finalint VERSION =1;
//定义类对象
private static WeatherDB sWeatherDB;
//定义数据库对象
private SQLiteDatabase db;
//私有化构造方法
private WeatherDB(Contextcontext) {
WeatherOpenHelper dbHelper = new WeatherOpenHelper (context, DB_NAME, null, VERSION );
db = dbHelper.getReadableDatabase( );
}
//实例化类对象
public synchronizedstatic WeatherDB getInstance(Context context) {
if (sWeatherDB == null) {
sWeatherDB = new WeatherDB ( context);
}
return sWeatherDB;
}
//将province省份存储到数据库
public void saveprovince(Provinceprovince) {
if (province != null) {
ContentValues values = new ContentValues ( );
values.put ( "province_name",province.getProvinceName ( ) );
values.put ( "province_code",province.getProvinceCode ( ) );
db.insert ( "Province",null, values );
}
}
//从数据库读取全国所有的省份信息
public List<Province>loadProvinces() {
List<Province> list = new ArrayList<Province>( );
Cursor cursor = db.query ( "Province",null, null,null, null,null, null);
while (cursor.moveToNext ()) {
Province province = new Province ( );
province.setId (cursor.getInt ( cursor.getColumnIndex ( "id") ) );
province.setProvinceName(cursor.getString ( cursor.getColumnIndex ( "province_name") ) );
province.setProvinceCode (cursor.getString ( cursor.getColumnIndex ( "province_code") ) );
//Log.i("FXC","从数据库读取全国所有的省份信息"+province.getProvinceName ());
list.add ( province);
}
if (cursor != null) {
cursor.close ( );
}
return list;
}
//将city城市存储到数据库
public void savecity(City city) {
if (city != null) {
ContentValues values = new ContentValues ( );
values.put ( "city_name", city.getCityName () );
values.put ( "city_code", city.getCityCode () );
values.put ( "province_id", city.getProvinceId( ) );
db.insert ( "City",null, values );
}
}
//从数据库读取指定省份城市信息
public List<City>loadCities(intprovinceId) {
List<City> list = new ArrayList<City>( );
Cursor cursor = db.query ( "City",null, null,null, null,null, null);
while (cursor.moveToNext ()) {
City city = new City ( );
city.setId ( cursor.getInt (cursor.getColumnIndex ( "id") ) );
city.setCityName (cursor.getString ( cursor.getColumnIndex ( "city_name") ) );
city.setCityCode (cursor.getString ( cursor.getColumnIndex ( "city_code") ) );
city.setProvinceId (cursor.getInt ( cursor.getColumnIndex ( "province_id") ) );
list.add ( city );
}
if (cursor != null) {
cursor.close ( );
}
return list;
}
//将city城市下一级区县存储到数据库
public void savecounty(Countycounty) {
if (county != null) {
ContentValues values = new ContentValues ( );
values.put ( "county_name",county.getcountyName () );
values.put ( "county_code",county.getcountyCode () );
values.put ( "city_id", county.getCityId () );
db.insert ( "County",null, values );
}
}
//从数据库读取city城市下一级区县信息
public List<County>loadCounties(intcityId) {
List<County> list = new ArrayList<County>( );
Cursor cursor = db.query ( "County",null, null,null, null,null, null);
while (cursor.moveToNext ()) {
County county = new County ( );
county.setId ( cursor.getInt( cursor.getColumnIndex ( "id") ) );
county.setcountyName (cursor.getString ( cursor.getColumnIndex ( "county_name") ) );
county.setcountyCode (cursor.getString ( cursor.getColumnIndex ( "county_code") ));
county.setCityId (cursor.getInt ( cursor.getColumnIndex ( "city_id") ));
list.add ( county );
}
if (cursor != null) {
cursor.close ( );
}
return list;
}
//删除城市数据
public void delete_city(){
db.delete("City",null,null);
}
// 删除区县数据
public void delete_county(){
db.delete("County",null,null);
}
}
7.3 创建model
在该包下对数据库的每一个表创建一个实体类,主要是写一些数据库表对应字段的常用的get 或set 方法
7.4 服务器交互
全国所有省市区县的数据都是从服务器获取到的。解析的规则就是先按逗号分隔,再按单竖线分隔,接着将解析出来的数据设置到实体类中,然后调用数据库操作封装类中相应的方法存储到数据库相应表中。
部分实例如下:
if(!TextUtils.isEmpty ( response )){ String [] allProvinces=response.split ( "," ); if(allProvinces!=null && allProvinces.length>0){ for(String p:allProvinces){ String [] array=p.split ( "\\|" ); Province province=new Province (); province.setProvinceCode ( array[0] ); province.setProvinceName ( array[1] ); // Log.i("FXC","解析出来的省份是"+array[1]); weatherDB.saveprovince ( province ); } return true; } }
连接服务器代码如下:
URL url=new URL(address);
connection= (HttpURLConnection) url.openConnection ();
connection.setRequestMethod ( "GET" );
connection.setConnectTimeout ( 8000 );
connection.setReadTimeout ( 8000 );
InputStream in=connection.getInputStream ();
BufferedReader reader=new BufferedReader(new InputStreamReader ( in ));
7.5 MainActivity主活动
主要是获取列表等控件,按要求去读取本地数据库,若无数据则连接服务器。以获取城市数据为例。
//查询全国所有的市,优先从数据库查询,如果没有查询到再去服务器上查询 private void queryCities(){ if(flag==true){ if(selectprovince.getProvinceName ().equals ( selectedprovince.getProvinceName () )) { mCityList =mWeatherDB.loadCities ( selectprovince.getId () ); if(mCityList.size ()>0){ dataList.clear (); for(City city:mCityList){ dataList.add(city.getCityName ()); } mAdapter.notifyDataSetChanged (); listview.setSelection ( 0 ); titletext.setText (selectprovince.getProvinceName () ); currentLevel=LEVEL_CITY; }}}else { if(flag==false)mWeatherDB.delete_city ();//删除库中旧的数据 queryFromServer(selectprovince.getProvinceCode (),"city");//连接服务器获取新数据 flag=true; selectedprovince=selectprovince; } }
7.6 获取天气
{"weatherinfo":{"city":"吴中","cityid":"101190405","temp1":"19℃","temp2":"11℃","weather":"小雨","img1":"d7.gif","img2":"n7.gif","ptime":"08:00"}} |
JSONObject jsonObject=new JSONObject( response); JSONObject weatherInfo=jsonObject.getJSONObject ( "weatherinfo" ); String cityName=weatherInfo.getString ( "city" ); String weatherCode=weatherInfo.getString ( "cityid" ); String temp1=weatherInfo.getString ( "temp1" ); String temp2=weatherInfo.getString ( "temp2" ); String weatherDesp=weatherInfo.getString ( "weather" ); String publishTime=weatherInfo.getString ( "ptime" ); savaWeatherInfo(context,cityName,weatherCode,temp1,temp2,weatherDesp,publishTime);