登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

查看: 866954|回复: 131

中国水系Android第一个版本(教程+源码)

  [复制链接]

206

主题

1622

帖子

2720

安币

Android大神

Rank: 6Rank: 6

发表于 2011-11-10 14:06:42 | 显示全部楼层 |阅读模式

写这个例子的目的是供同事和开发Android的朋友学习借鉴。

这个版本不是凭空冒出来的,就像爱因斯坦做手工的故事(不知道的见这里)一样,还有更丑的“小凳子”,它们是:

参考它们可以了解版本的演进过程。可能降低学习曲线。

这个版本的首页:

点击条目,会弹出带图片的详细信息界面:

这里的图片是从维基百科直接下载的,并会缓存在本地。

另外,就是对横竖屏使用了不同的布局:

下面介绍一下实现的要点。

异步延时加载的处理

以前我都是自己写异步加载,比如用Java concurrent编写异步加载图片功能android异步加载ListView中的图片。其实android自己有个AsyncTask,可以方便的做这个事情。这次尝试使用了一下。

我目前的基本理解是AsyncTask简化了异步开发。

因为如果自己写,需要创建线程执行后台操作,比如下载图片文件,然后还是要通过handler通知ui线程将图片文件显示到界面上。

AsyncTask提供了需要实现的方法,一些方法AsyncTask会创建线程执行,比如doInBackground,而onPostExecute方法,AsyncTask会自行调用handler通知ui线程执行。

这部分代码见DetailViewActivity的内部类:

  1. private class ShowImageTask extends AsyncTask<String, Void, Void> {

  2.     private String fileName;

  3.     @Override
  4.     protected Void doInBackground(String… params) {
  5.         fileName = params[1] + ".jpg";

  6.         File cacheFile = new File(getCacheDir(), fileName);
  7.         if (!cacheFile.exists()) {
  8.             //创建临时文件,用于下载图片使用
  9.             File tempFile = new File(getCacheDir(), "tmp");
  10.             HttpClient client = new DefaultHttpClient();
  11.             HttpGet get = new HttpGet(params[0]);
  12.             try {
  13.                 HttpResponse response = client.execute(get);
  14.                 FileOutputStream outputStream = new FileOutputStream(
  15.                         tempFile);
  16.                 InputStream inputStream = response.getEntity().getContent();
  17.                 for (int i = inputStream.read(); i != -1; i = inputStream
  18.                         .read()) {
  19.                     outputStream.write(i);
  20.                 }
  21.                 inputStream.close();
  22.                 outputStream.close();
  23.                
  24.                 /**
  25.                  * 改名临时文件,改为对应河流id的jpg文件
  26.                  * 这样做是为了防止图片下载不全的问题
  27.                  */
  28.                 tempFile.renameTo(cacheFile);
  29.             } catch (Exception e) {
  30.                 throw new RuntimeException(e);
  31.             }
  32.         }

  33.         return null;
  34.     }

  35.     @Override
  36.     protected void onPostExecute(Void result) {
  37.         try {
  38.             imageView.setImageDrawable(Drawable.createFromStream(
  39.                     new FileInputStream(new File(getCacheDir(), fileName)),
  40.                     "river.jpg"));
  41.         } catch (FileNotFoundException e) {
  42.             throw new RuntimeException(e);
  43.         }
  44.         imageLoadProgressBar.setVisibility(View.GONE);
  45.     }
复制代码
这里还需要注意的是,使用了httpclient api来下载图片,这部分如果不明白,可参见更简单的示例android编写访问http的代码。只不过这里是使字节流。下载的图片放在哪里?这里没有选择放在sd卡这样的外存中,而是放在内存里。内存可存储在两个位置:
  • 存放在应用的files目录下,不过不能直接操作目录,只能通过openFileOutput()操作文件流,当不存在的时候自动创建
  • 存放在应用的cache目录下,可操作文件目录,通过getCacheDir()方法可获取目录File对象
在这里使用cache目录的方式,因为要操作文件并且涉及到文件改名等。有关Content Provider和数据库示例使用了Content Provider,而且是:
  1. sqlite+Content Provider+CursorAdapter+Loader+ListView
复制代码
示例中详细界面是Activity,设置了dialog的theme,看上去像对话框。这样做的考虑是结构简单,两个Activity是通过intent来松散耦合的。在intent中传递的是river的id。这样,content provider需要能处理对集合的查询和对指定id的查询:
  1. switch (uriMatcher.match(uri)) {//判断是访问river集合还是指定id访问单条记录
  2. case ITEMS:
  3.     cursor = database.query("rivers", projection, selection,
  4.             selectionArgs, null, null, sortOrder);
  5.     cursor.setNotificationUri(getContext().getContentResolver(), uri);
  6.     return cursor;
  7. case ITEM:
  8.     cursor = database.query("rivers", projection, _ID + "="
  9.             + uri.getPathSegments().get(1), selectionArgs, null, null,
  10.             sortOrder);
  11.     cursor.setNotificationUri(getContext().getContentResolver(), uri);
  12.     return cursor;
  13. default:
  14.     throw new IllegalArgumentException("unknown uri: " + uri);
  15. }
复制代码
横竖屏的处理这个处理其实很简单。基本思路是针对横竖屏有不同的布局文件,android会在配置变化自动识别并加载对应文件。如图所示,可知目录的命名方法。源代码见:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

7

主题

143

帖子

171

安币

程序猿

Rank: 2

发表于 2011-11-11 22:23:18 | 显示全部楼层
不错的资料

0

主题

25

帖子

62

安币

程序猿

Rank: 2

发表于 2011-11-16 15:56:10 | 显示全部楼层
恩 谢谢lz分享。。

0

主题

25

帖子

62

安币

程序猿

Rank: 2

发表于 2011-11-16 16:04:40 | 显示全部楼层
想问下 我在导入该项目后,怎么老是提示java problem? 而且FragmentActivity等很多类都找不到,试着换了下jdk版本也不好使,求解!

0

主题

14

帖子

12

安币

初级码农

Rank: 1

发表于 2011-12-5 17:41:00 | 显示全部楼层
我多了解了解,尽量不浪费

0

主题

39

帖子

49

安币

初级码农

Rank: 1

QQ达人

发表于 2011-12-13 22:07:26 | 显示全部楼层
想问下 我在导入该项目后

1

主题

12

帖子

54

安币

程序猿

Rank: 2

发表于 2011-12-13 22:17:26 | 显示全部楼层
循序渐进。

3

主题

50

帖子

92

安币

初级码农

Rank: 1

发表于 2011-12-25 21:56:36 | 显示全部楼层
谢谢LZ分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区
联系我们
关闭
合作电话:
15618560077
Email:
805941275@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表