天气app开发简要流程

工程的框架结构如下:

  • activity
  • db
  • model
  • receiver:广播接收器代码
  • service:存放服务相关代码
  • util:工具相关的代码

CoolWeatherDB

常用的数据库操作封装起来。
主要功能是提供六种方法:

  • 存储省份数据,读取省份数据
  • 存储城市数据,读取城市数据
  • 存储县数据,读取县数据

遍历全国省市县数据

增加一个HttpUtil类来和服务器交互

这里面的重点是需要添加一个HttpCallbackListener接口。

数据处理类

这里再util包中新建一个Utility类

查询全国所有省

这个方法是整个app的关键,思路是优先从数据库查询,如果没有查询到再去服务器上查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void queryProvinces() {
provinceList = coolWeatherDB.loadProvinces();
if (provinceList.size() > 0) {
dataList.clear();
for (Province province : provinceList) {
dataList.add(province.getProvinceName());
}
adapter.notifyDataSetChanged();
listView.setSelection(0);
titleText.setText("中国");
currentLevel = LEVEL_PROVINCE;
} else {
queryFromServer(null, "province");
}
}

适配器的方法中通常有三个参数,第一个参数是上下文,就是当前的Activity, 第二个参数是android sdk中自己内置的一个布局,它里面只有一个TextView,这个参数是表明我们数组中每一条数据的布局是这个view,就是将每一条数据都显示在这个 view上面;第三个参数就是我们要显示的数据。listView会根据这三个参数,遍历adapterData里面的每一条数据,读出一条,显示到第二个参数对应的布局中,这样就形成了我们看到的listView.

在这里有一个notifyDataSetChanged()方法,这个方法的作用就是通知adapter 调用getview来刷新每个Item。(但是notifyDataSetChanged这个不是好办法,也尽量不要用,越多Item越耗时,getView每次取的只是可见的一部分,上千条数据,我觉得还是分页的好)。

还有一个是setSelection()方法。这里先介绍setSelectionFromTop(),它的作用是设置ListView选中的位置,同时在Y轴设置一个偏移量(padding值)。
ListView还有一个方法叫setSelection(),传入一个index整型数值,就可以让ListView定位到指定Item的位置。他们的关系大体是:

1
2
3
public void setSelection(int position) {
setSelectionFromTop(position, 0);
}

在服务器上查询数据

新建一个queryFromServer()方法

  • runOnUiThread()方法
    runOnUiThread这个会调用父类中的方法:
    1
    2
    3
    4
    5
    6
    7
    public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
    mHandler.post(action);
    } else {
    action.run();
    }
    }

首先判断是否是UI线程,不是的话就post,如果是的话就正常运行该线程。

  • ProgressDialog()方法
    该方法是防止假死的,它的执行步骤很重要,基本上遵循:在执行耗时间的操作之前弹出ProgressDialog提示用户,然后开一个新线程,在新线程里执行耗时的操作,执行完毕之后通知主程序将ProgressDialog结束。结束采用progressDialog.dismiss()方法,具体代码如下:

    1
    2
    3
    4
    5
    private void closeProgressDialog() {
    if (progressDialog != null) {
    progressDialog.dismiss();
    }
    }
  • 捕获Back键
    在这里重写了Back键方法,具体代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Override
    public void onBackPressed() {
    if (currentLevel == LEVEL_COUNTY) {
    queryCities();
    } else if (currentLevel == LEVEL_CITY) {
    queryProvinces();
    } else {
    finish();
    }
    }

更新天气

其实很简单,创建一个新的方法queryWeatherInfo(),在该方法中添加更新方法:

1
2
3
String address = "http://www.weather.com.cn/data/cityinfo/" +
weatherCode + ".html";
queryFromServer(address, "weatherCode");