android开发练习:天气应用
来源:网易云课堂GeekBand第七次作业
作业要求:
做一个天气应用
- 接口参考: http://apistore.baidu.com/apiworks/servicedetail/880.html,只是参考API,可自行查找使用其他API接口
- 考察内容:获取数据,解析JSON
- 数据缓存在数据库中,使用ContentProvider来处理
- 如果不强制刷新,则使用缓存数据每隔一定时间再刷新一次
前期准备
1.选择合适的API!选择合适的API!选择合适的API!(重要的话说三遍,中途变更API严重影响效率和心情).
2.gson.如何添加依赖库 http://www.cnblogs.com/happyhacking/p/5257002.html
目录结构
UI
注意:在布局的过程中weightSum和layout_weight要慎用,尤其是在内容长度可变的情况下,使用结果往往不符合预期.
主要逻辑
主要逻辑集中在查询按钮的点击事件上
(注意:cursor.moveToFirst(),Long.valueOf()和Long.getLong()的用法.)
mQueryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//判断用户是否输入了城市名称
if (!TextUtils.isEmpty(mCityName.getText())) {
//首先查询本地数据库
Uri uri = Uri.parse("content://com.example.janiszhang.weatherdemo.provider/weatherdata");
Cursor cursor = getContentResolver().query(uri, null, "cityname = ?", new String[]{mCityName.getText() + ""}, null);
if (cursor.moveToFirst()) {// 查询成功 //这里不可以使用cursor!= null来判断!!!!
Log.i("zhangbz", cursor.getString(cursor.getColumnIndex("savetime")));
if ((System.currentTimeMillis() - Long.valueOf(cursor.getString(cursor.getColumnIndex("savetime")))) < (1000*60)) {//这里不可以使用Long.getLong(),因为它返回的是系统属性的值,其参数是被请求的系统属性的名称
//如果数据库中的数据没有过期,就从数据库中查询
updateUIfromDatabase(cursor);
} else {
//如果数据库中的数据过期了,则通过网络查询并update到数据库
shouldUpdate = true;
try {
httpArg = "city=" + URLEncoder.encode(mCityName.getText().toString(), "UTF-8");//中文需要编码
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
new MyAsyncTask().execute(httpArg);//使用asynctask
}
} else {
//网络查询并insert到数据库
shouldUpdate = false;//需要insert
try {
httpArg = "city=" + URLEncoder.encode(mCityName.getText().toString(), "UTF-8");//中文需要编码
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
new MyAsyncTask().execute(httpArg);
}
SharedPreferences sp = getSharedPreferences("last", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("cityname", mCityName.getText().toString());
editor.apply();
//开启自动更新
Intent intent = new Intent(MainActivity.this, AutoUpdateService.class);
startService(intent);
}
}
});
重点记录
使用Gson解析数据
Gson gson = new Gson();
WeatherDataStatus weatherDataStatus = gson.fromJson(s, WeatherDataStatus.class);
这里注意两个问题:
1.使用gson解析json数据时,不需要为整个json数据创建实体类,只需要为需要解析的数据定义变量和提供getter/setter方法.
2.注意区分什么是json数组:
//json数组:中括号
[{
"这是json数组": "这是json数组"
}, {
"这是json数组": "这是json数组"
}, {
"这是json数组": "这是json数组"
}]
//注意和这种情况区分开
{
"这不是json数组": [{
"这才是json数组": "这才是json数组"
}, {
"这才是json数组": "这才是json数组"
}, {
"这才是json数组": "这才是json数组"
}]
}
自动更新的实现
service需要由Activity启动,之后由service和receiver配合相互唤醒.
AutoUpdateService.class
public class AutoUpdateService extends Service{
private String mCityname;
@Nullable
@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() {
updateWeather();
}
}).start();
//使用AlarmManager实现定时任务
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour = 8 * 60 *60 * 1000;//8小时
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
//service -> receiver
Intent i = new Intent(this, AutoUpdateReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
return super.onStartCommand(intent, flags, startId);
}
//...
}
AutoUpdateReceiver.class
public class AutoUpdateReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//receiver->service
Intent i = new Intent(context, AutoUpdateService.class);
context.startService(i);
}
}
contentprovider的练习
虽然用在这里很牵强,但是目的是练习嘛.
很久没有使用contentprovider,以下为基本使用方法.
public class MyProvider extends ContentProvider{
public static final int WEATHERDATA_DIR = 0;
public static final String AUTHORITY = "com.example.janiszhang.weatherdemo.provider";
private static UriMatcher sUriMatcher;
private MyDBHelper mMyDBHelper;
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(AUTHORITY, "weatherdata", WEATHERDATA_DIR);
}
@Override
public boolean onCreate() {
mMyDBHelper = new MyDBHelper(getContext(), "weatherDataDB.db", null, 1);
return true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mMyDBHelper.getReadableDatabase();
Cursor cursor = null;
switch (sUriMatcher.match(uri)) {
case WEATHERDATA_DIR:
cursor = db.query("weatherdata", projection, selection, selectionArgs, null, null, sortOrder);
break;
}
return cursor;
}
@Nullable
@Override
public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case WEATHERDATA_DIR:
return "vnd.android.cursor.dir/vnd.com.example.janiszhang.weatherdemo.provider.weatherdata";
}
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = mMyDBHelper.getReadableDatabase();
Uri uriReturn = null;
switch (sUriMatcher.match(uri)) {
case WEATHERDATA_DIR:
long newId = db.insert("weatherdata", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/weatherdata/" + newId);
break;
}
return uriReturn;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = mMyDBHelper.getWritableDatabase();
int updateRows = 0;
switch (sUriMatcher.match(uri)) {
case WEATHERDATA_DIR:
updateRows = db.update("weatherdata", values, selection, selectionArgs);
break;
}
return updateRows;
}
}
github地址:https://github.com/zhangbz/WeatherDemo
总结:写这个demo,把四大组件都用到了,把基本用法复习了一遍,温故知新.
android开发练习:天气应用的更多相关文章
- Android经典项目开发之天气APP实例分享
原文:Android经典项目开发之天气APP实例分享 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mzc186/article/details/5 ...
- 50个Android开发人员必备UI效果源码[转载]
50个Android开发人员必备UI效果源码[转载] http://blog.csdn.net/qq1059458376/article/details/8145497 Android 仿微信之主页面 ...
- 【Mood-12】Android开发相关书籍推荐
新年伊始,找到Android进阶干货若干,2015拜读. 1.Android应用UI设计模式 目前,谷歌Android操作系统在移动市场中风头正劲,并且未来发展势不可挡.<Android应用UI ...
- Android开发中常见的设计模式
对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是非常有必要的.对于想系统的学习设计模式的 ...
- Android开发心得(转)
前言: 很早以前,就听人说过android以后会火起来,作为一个前瞻性对它有所了解会是一个转型的好机会,javaweb太成熟饱和了,现在市面上各种android手机层出不穷,网上各种android视频 ...
- Android解析中国天气网的Json数据
在Android开发中.一般的APP都是通过获取server端的数据来更新UI.从server获取到的数据能够是Json.它的数据量要比XML要小,这里解析中国天气网上获取的数据,尽管已经不再更新了. ...
- Android开发周报:反编译对抗研究、动手制作智能镜子
新闻 <Android Wear落地中国 谷歌增强安卓生态控制力> :9月8日,由摩托罗拉推出的智能手表Moto 360二代作为国内发售的第一款搭载官方Android Wear的设备,正式 ...
- Android开发周报:Android L默认加密用户数据
Android开发周报:Android L默认加密用户数据 新闻 <iCloud前车之鉴,Android L默认开启加密功能>:iCloud 艳照风波再起,第二波女星照片流出,大量女星的裸 ...
- Android开发10:传感器器及地图相关应用
前言 啦啦啦~各位小伙伴们好~经过这一学期的Android知识的学习,我们学到了很多和Android开发相关的知识,这一学期的学习也要告一段落了. 一起进入我们今天的相关内容~这次我们将一起学习使用 ...
随机推荐
- 在MVC中使用async和await的说明
首先,在mvc中如果要用纯异步请不要使用async和await,可以直接使用Task.Run. 其次,在mvc中使用async和await可以让系统开新线程处理Task的代码,同时不必等Task执行结 ...
- C# 3DES加密
最近一个项目中,因为服务端是用的java开发的,客户端是用的C#,由于通信部分采用到了3DES加密,所以做个记录,以备以后需要的时候直接用. 这是对方(java)的加密算法,和网上流传的代码也差不多( ...
- .net又一个生成缩略图的方法,不变形
生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 /// <summary> /// 为图片生成缩略图 by 何问起 /// ...
- Redis系列三之持久化
一.Redis持久化 Redis是一个支持持久化的内存数据库,redis需要经常将内存中的数据同步到磁盘来保证持久化. redis提供了不同级别的持久化方法: Snapshotting(快照,默认方式 ...
- .NET 中获取调用方法名
在写记录日志功能时,需要记录日志调用方所在的模块名.命名空间名.类名以及方法名,想到使用的是反射(涉及到反射请注意性能),但具体是哪一块儿还不了解,于是搜索,整理如下: 需要添加相应的命名空间: us ...
- 背水一战 Windows 10 (5) - UI: 标题栏
[源码下载] 背水一战 Windows 10 (5) - UI: 标题栏 作者:webabcd 介绍背水一战 Windows 10 之 UI 标题栏 示例TitleBarDemo.xaml <P ...
- Java并发编程:并发容器之CopyOnWriteArrayList(转载)
Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW ...
- 读书笔记系列之java性能优化权威指南 一 第一章
主题:java性能优化权威指南 pdf 版本:英文版 Java Performance Tuning 忽略:(0~24页)Performance+Acknowledge 1.Strategies, A ...
- 【JAVA并发编程实战】2、对象的组合
1. 设计线程安全的类 1.找出构成对象状态的所有变量 2.找出约束状态变量的不变性条件 3.建立对象状态的并发访问管理策略 package cn.xf.cp.ch04; /** * *功能:JAVA ...
- spring mvc+ELK从头开始搭建日志平台
最近由于之前协助前公司做了点力所能及的事情,居然收到了一份贵重的端午礼物,是给我女儿的一个乐高积木,整个有7大包物件,我花了接近一天的时间一砖一瓦的组织起来,虽然很辛苦但是能够从过程中体验到乐趣.这次 ...