基本流程:根据中国天气网服务器返回的数据,解析后存入数据库,先在数据库查询,如果没有在服务器查询将查询结果存入数据库,在进行一次数据库查询。
数据库方面
数据库创建: 单例模式,根据建表语句确定创建的实例需要哪些数据,存入数据库的信息实例化。自行创建一个(数据库类)该类中写对数据库数据的操作。
如图:
另外数据库,数据类型最好是整型,字符串转整型可以用Integer.parseInt()方法。
监测字符串是否为空 TextUtils.isEmpty(code).
数据库操作语句的正确性判断:
1.可以在adb shell
2.cd data/data/com~~~~~~~~~~~/databases
3.sqlite3 数据库名
4.输入语句进行正确性的监测。
数据解析方面
服务器数据解析:将response从服务器获取后,创建一个方法对数据进行解析(通常这个方法写在获取网络信息的接口这样就可以根据情况编写不同的解析方式),可以是正则表达式,也可以是JSON解析。通常解析下来的数据直接存到数据库中。
正则表达式:
public void handleservicecountry(String response,String city_id){
if(response!=null){
String s[]=response.split(",");
//正则表达式 切割字符串。
for(String p : s){
// Log.d("测试切割",p+"");
String ss[]=p.split("\\|");
Country country=new Country();
country.setCountry_name(ss[1]);
country.setCountry_code(ss[0]);
country.setCity_code(city_id);
db.savecountry(country);
Log.d("测试country",ss[0]+""+ss[1]);
}
}
}
JSON:
//解析JOSN数据。
public void handleweathermasege(String masege){
try{
//每一组元素都是一个JSONObject,只有一组元素 所以不用JSONarray了,如果是几组元素那么循环获取每一组元素用getJOSMObject
// JSONArray jsonArray=new JSONArray(masege);
JSONObject jsonObject=new JSONObject(masege);
JSONObject weatherinfo= jsonObject.getJSONObject("weatherinfo");
String name=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");
savaweatherdata(this, name, weathercode, temp1, temp2, weatherDesp, publishtime);
}
catch (Exception e){
}
}
josn 当发送josn消息遇到{"name":"key","ctrl":[{"0":"a",.........}]} 情况时:
jsonObjectall=new JSONObject();
jsonObject=new JSONObject();
jsonObjectall.put("name",key);
jsonObjectall.put("ctrl",jsonObject);
jsonObject.put("0",a);
这里推荐一种超级方便的 解析Josn格式数据的方式:
Gsonfomat + Gson 一秒钟解析JSON数据。。。。。。。。。。。
其他方面
载入信息的顺序:定义标记,通过对标记的不断改变和判断,按照正确的逻辑对信息载入!!
返回键:onbackPressed()重写这个方法,同样可以根据标记决定返回到哪里
public void onBackPressed() {
finish();
}
另外注意在子线程中是无法立刻对主线程进行UI更新的,不能主动更新UI
可以使用这个方式:
runOnUiThread(new Runnable() {
@Override
public void run() {
querycountry();
}
});
定时后台更新
开启服务→执行服务(设置定时任务发送广播)→广播接收者(开启服务)
如此循环则在服务中的任务就会的到定时的执行
服务:
public class AutoUpdataService extends Service {
public AutoUpdataService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//给耗时任务开启线程
new Thread(new Runnable() {
@Override
public void run() {
Log.d("后台服务在不要脸的执行了",SystemClock.elapsedRealtime()+"当前时间毫秒");
}
}).start();
//获取系统定时服务,设置执行的时间间隔,定时器需要这个参数
AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour= 30*1000;
long triggerATtime= SystemClock.elapsedRealtime()+anHour;
//PendingIntent延迟开启的意图,即将发生的意图,即时APP不在了,仍然能借助意图中的上下文执行这个意图.
Intent i=new Intent(this,AutoUpdataRecieve.class);
//PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例.
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
//AlarmManager需要一个PendingIntent去定时执行
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerATtime,pi);
//第一个参数是唤醒CUP的类型,二参是延时多长时间,三参是即将执行的意图(PendingIntent)
return super.onStartCommand(intent, flags, startId);
}
}
需要注意的是定时器!! 定时器需要一个即将执行的意图(把发送广播的意图包装成PendingIntent)和一个执行时间,作为参数。
上面程序每隔30秒就会发送一个广播
广播:
//这个广播接收用于开启服务
public class AutoUpdataRecieve extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context,AutoUpdataService.class);
context.startService(i);
}
}
最后在主程序中只要开启一次服务就可以定时的后台执行了。即时程序关闭了。