

英语原文共 19 页,剩余内容已隐藏,支付完成后下载完整资料
第26章 HTTP与后台任务
那些占用用户大量时间的一般是互联网应用。餐桌上无人交谈,每个人都只顾低头摆弄手机。一有时间,人们就上网检查新闻推送、收发短信息,或是玩着联网游戏。
为着手学习Android网络应用的开发,我们将创建一个名为PhotoGallery的应用。 PhotoGallery是图片共享网站Flickr的客户端应用。它将获取并展示上传至Flickr网站的最新公共图片。应用的运行效果如图26-1所示。
图26-1 PhotoGallery应用运行效果图
(图26-1中的图片是我们自己准备的图片,而不是Flickr上的公共图片。 Flickr网站上的图片归上传者私人所有,未经本人许可任何人不得使用。了解更多有关Flickr上第三方内容的使用权限问题,可访问网址http://pressroom.yahoo.net/pr/ycorp/permissions.aspx。)
接下来的六章我们将学习开发PhotoGallery应用。前两章将介绍有关网络下载、 XML文件解析、图像显示等基本知识。后面的几章里,通过各种特色功能的添加,将介绍有关搜索、服务、通知、广播接收器以及网页视图等知识。
本章,我们将要学习使用Android高级别的HTTP 网络编程。当前,几乎所有网络服务的开发都是以HTTP网络协议为基础的。至本章结束时,我们要完成的任务是:获取、解析以及显示Flickr上图片的文字说明。(第27章会介绍图片获取与显示的相关内容。)
图26-2 本章完成的PhotoGallery应用效果图
26.1 创建 PhotoGallery 应用
按照图26-3所示的配置,创建一个新的Android应用项目。
图26-3 创建PhotoGallery应用
单击Next按钮,通过应用向导创建一个名为PhotoGalleryActivity的空白activity。
PhotoGallery应用将继续沿用前面一直使用的设计架构。 PhotoGalleryActivity同样设计为SingleFragmentActivity 的 子 类 , 其 视 图 为 activity_fragment.xml 中 定 义 的 容 器 视 图 。PhotoGalleryActivity负责托管PhotoGalleryFragment实例。稍后我们会创建它。
将SingleFragmentActivity.java和activity_fragment.xml从以前的项目复制到当前项目中。
在PhotoGalleryActivity.java中,删除自动产生的模板代码。然后设置PhotoGalleryActivity的父类为SingleFragmentActivity并实现它的createFragment()方法。 createFragment()方法将返回一个PhotoGalleryFragment类实例。如代码清单26-1所示。(暂时无需理会代码的错误提示,它会在PhotoGalleryFragment类创建完成后自动消失。)
代码清单26-1 activity的调整(PhotoGalleryActivity.java)
public class PhotoGalleryActivity extends Activity {
public class PhotoGalleryActivity extends SingleFragmentActivity {
/* Auto-generated template code */
@Override
public Fragment createFragment() {
return new PhotoGalleryFragment();
}
}
PhotoGallery应用将在GridView视图中显示获取的内容。而GridView由PhotoGalleryFragment的视图组成。
按照继承关系, GridView也是一个AdapterView,因此其工作方式与ListView类似。然而,不像ListView, GridView没有内置方便实用的GridFragment。这意味着我们需自己创建布局文件,并在PhotoGalleryFragment类中进行实例化。在本章的后面,我们将在PhotoGalleryFragment类中使用adapter提供图片说明文字给GridView视图显示。
为创建fragment布局,重命名layout/activity_photo_gallery.xml为layout/fragment_photo_gallery.xml。然后以图26-4所示的GridView替换原有布局内容。
图26-4 GridView视图(layout/fragment_photo_gallery.xml)
这里,我们设置列的宽度为120dp,并使用numColumns属性指示GridView创建尽可能多的列,以铺满整个屏幕。如果在列的空间分配上出现少于120dp的剩余空间,则stretchMode属性会要求GridView在全部列间均分这部分剩余空间。
最后,创建PhotoGalleryFragment类,设置其为保留fragment,实例化生成新建布局并引用GridView视图,如代码清单26-2所示。
代码清单26-2 一些代码片断 (PhotoGalleryFragment.java)
package com.bignerdranch.android.photogallery;
...
public class PhotoGalleryFragment extends Fragment {
GridView mGridView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_photo_gallery, container, false);
mGridView = (GridView)v.findViewById(R.id.gridView);
return v;
}
}
在继续学习之前,尝试运行PhotoGallery应用。如果一切正常,我们会看到一个空白视图。
26.2 网络连接基本
PhotoGallery应用中,我们需要一个处理网络连接的专用类。新建一个Java类。应用要访问连接的是Flickr网站,因此命名新建类为FlickrFetchr。
FlickrFetchr 类 一 开 始 只 有 getUrlBytes(String) 和 getUrl(String) 两 个 方 法 。getUrlBytes(String)方法从指定URL获取原始数据并返回一个字节流数组。 getUrl(String)方法则将getUrlBytes(String)方法返回的结果转换为String。
在FlickrFetchr.java中,为getUrlBytes(String)和getUrl(String)方法添加实现代码,如代码清单26-3所示。
代码清单26-3 基本网络连接代码 (FlickrFetchr.java)
package com.bignerdranch.android.photogallery;
...
public class FlickrFetchr {
byte[] getUrlBytes(String urlSpec) throws IOException {
URL url = new URL(urlSpec);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = connection.getInputStream();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return null;
}
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer)) gt; 0) {
out.write(buffer, 0, bytesRead);
}
out.close();
return out.toByteArray();
} finally {
connection.disconnect();
}
}
public String getUrl(String urlSpec) throws IOException {
return new String(getUrlBytes(urlSpec));
}
}
在getUrlBytes(String)方法中,根据传入的字符串参数,如http://www.google.com,首先创建一个URL对象。然后调用openConnection()方法创建一个指向要访问URL的连接对象。URL.openConnection()方法默认返回的是URLConnection对象,但我们要连接的是http URL,因此需将其强制类型转换为HttpURLConnection对象。 随后, 我们得以调用它的getInputStream()、getResponseCode()等方法。
HttpURLConnection对象虽然提供了一个连接,但只有在调用getInputStream()方法时(如果是POST请求,则调用getOutputStream()方法),它才会真正连接到指定的URL地址。在此之前我们无法获得有效的返回代码。
一旦创建了URL并打开了网络连接,我们便可循环调用read()方法读取网络连接到的数据,直到取完为止。只要还有数据存在, InputStream类便可不断输出字节流数据。数据全部输出后,关闭网络连接,并将读取的数据写入ByteArrayOutputStream字节数组中。
虽然getUrlBytes(String)方法完成了最重要的数据获取任务,但getUrl(String)才是本章真正需要的方法。它负责将getUrlBytes(String)方法获取的字节数据转换为String。至此,是不是想问,难道不可以在一个方法中完成全部任务?当然可以,但是处理下一章的图像数据下载时,我们需要使用两个独立的方法。
获取网络使用权限
要连接使用网络,还需完成一件事:取得使用网络的权限。正如用户不愿被偷拍照片一样,他们也不想有人偷偷下载他们的图片。
要取得网络使用权限,参照代码清单26-4,添加以下代码到AndroidManifest.xml文件中。
代码清单26-4 在配置文件中添加网络使用权限(AndroidManifest.xml)
lt;manifest xmlns:android='http://schemas.android.com/apk/res/android'
package='com.bignerdranch.android.photogallery'
android:versionCode='1'
android:versionName='1.0' gt;
lt;uses-sdk
android:minSdkVersion='8'
android:targetSdkVersion='15' /gt;
lt;uses-permission android:name='android.permission.INTERNET' /gt;
...
lt;/manifestgt;
26.3 使用 AsyncTask 在后台线程上运行代码
接下来是调用并测试新添加的网络连接代码。注意,不能直接在PhotoGalleryFragment类中调用FlickrFetchr.getURL(String)方法,我们应创建一个后台线程,然后在该线程中运行代码。
使用后台线程最简便的方式是使用AsyncTask工具类。 AsyncTask创建后台线程后,我们便可在该线程上调用doInBackground(...)方法运行代码。
lt;
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[151498],资料为PDF文档或Word文档,PDF文档可免费转换为Word
您可能感兴趣的文章
- 饮用水微生物群:一个全面的时空研究,以监测巴黎供水系统的水质外文翻译资料
- 步进电机控制和摩擦模型对复杂机械系统精确定位的影响外文翻译资料
- 具有温湿度控制的开式阴极PEM燃料电池性能的提升外文翻译资料
- 警报定时系统对驾驶员行为的影响:调查驾驶员信任的差异以及根据警报定时对警报的响应外文翻译资料
- 门禁系统的零知识认证解决方案外文翻译资料
- 车辆废气及室外环境中悬浮微粒中有机磷的含量—-个案研究外文翻译资料
- ZigBee协议对城市风力涡轮机的无线监控: 支持应用软件和传感器模块外文翻译资料
- ZigBee系统在医疗保健中提供位置信息和传感器数据传输的方案外文翻译资料
- 基于PLC的模糊控制器在污水处理系统中的应用外文翻译资料
- 光伏并联最大功率点跟踪系统独立应用程序外文翻译资料
