Android教程10 亚当的诞生

上一讲介绍了用WebView来抓取一个网页内容。这一讲我将介绍如何在安卓内部直接进行HTTP通信。

《亚当的诞生》,西斯廷礼拜堂的吊顶画,米开朗基罗之作。当时的教皇强迫沉迷于雕塑的米开朗基罗画巨幅壁画。米开朗基罗认为这是在浪费自己的才华,充满愤怒的作画。当然,他又成功了。

描述

这一讲中,我将使用JSON,将数据库备份到远程的数据库中。反过来我也将从远程数据库中抓取条目,并放入安卓的数据库。相关的安卓知识点包括:

  • 线程
  • HTTP通信
  • JSON

增加ActionBar

我首先在首页上增加一菜单,用于触发下载和上传功能。这是通过ActionBar实现的。ActionBar在页面的顶端增加一个横幅。这个横幅上可以有应用的图标、文字信息和选项菜单(OptionMenu)。

我在布局文件res/menu/main.xml中定义ActionBar的菜单:

现在,修改之前的MainActivity.java。MainActivity将继承 ActionBarActivity。这样,MainActivity页面的顶端将增加一条ActionBar。接下来,我要覆盖ActionBarActivity的两个方法。一个是onCreateOptionsMenu() 方法。在这个方法中,我绑定上面的视图文件到ActionBar上。另一个方法onOptionsItemSelected() ,主要用于说明菜单各个选项被点击后的动作。代码如下:

在上面,我的onOptionsItemSelected()方法还没有包含具体的功能。我将在下一部分为该方法增加功能。 运行应用后效果如下:

HTTP获得数据

下一步,我将增加"Download"按钮点击后的功能。按钮点击后,应用将访问互联网,并获得URL指向的.js文件。获得.js文件后,我从该文件中提取JSON对象,这个对象中包含一些新的Category名字。最后,我在数据库中增加Category条目:

注意到,上面的网络访问部分启动了一个新线程 Thread 。为了确保界面的流畅,安卓规定网络访问不能在负责图画界面的主线程中进行。所以,我们必须把网络访问放在一个新的线程中。我们通过异步的方式进行网络访问,将在下一部分介绍。

程序中的JSONObject和JSONArray用于解析接收到的JSON字符串。

使用AsyncTask

AsyncTask在背景进程中工作。AsyncTask分为工作准备、工作进行和工作完成三个部分。AsyncTask有三个方法,onPreExecute(),doInBackground(), onPostExecute()分别代表这三个部分的任务。其中,doInBackground在背景进程中进行,因此可以把网络访问放入其中。此外,在doInBackground中,可以通过调用publishProgress(),来更新任务的进度。进度更新后,AsyncTask将调用onProgressUpdate()方法。

AsyncTask有三个类型<X, Y, Z>。它们分别是doInBackground(X), onProgressUpdate(Y)和onPostExecute(Z)的参数类型。此外,doInBackground()方法的返回值将成为onPostExecute()的参数,因此doInBackground()方法的返回值类型也是Z。

当工作完成,AsyncTask会通知主线程。AsyncTask与Thread的目的相同,但它 异步 的调用方式更方便编写,也更容易实现主线程和背景线程之间的信息传递。我下面会实现Upload的对应功能,即把Category表转成JSON,再把该JSON字符串发送到特定的URL。

这里的URL并不能处理POST方法。如果有兴趣,可以使用上一部分的Play框架,自制接受POST的服务器,并处理这里上传的JSON。

总结

ActionBarActivity

Thread, AsyncTask

JSONObject, JSONArray

Http, get and post

「Android教程」系列文章

文/ Vamei

0 Likes