介绍总结的一些android公共库,包含缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、滑动一页Gallery)、及Android常用工具类(网络、下载、shell、文件、json等等)。
TrineaAndroidCommon已开源,地址为TrineaAndroidCommon@Github,欢迎Star或Fork^_*
Demo APK 可以方便的查看效果,在各大应用商店搜索 trinea android 下载即可,如:Google Play。
PS:这是准备分享的三个系列之一,暂时告一段落,后续准备开始Android性能优化系列以及Java多线程系列。
一. 缓存类
1. 图片缓存
使用见:图片缓存的使用
适用:获取图片较多的应用,如新浪微博、twitter、微信头像、美丽说、蘑菇街、花瓣、淘宝等等。
主要特性:(1). 使用简单 (2). 轻松获取及预取新图片 (3). 包含二级缓存 (4). 可选择多种缓存算法(FIFO、LIFO、LRU、MRU、LFU、MFU等13种)或自定义缓存算法 (5). 可方便的保存及初始化恢复数据 (6). 省流量性能佳(有且仅有一个线程获取图片) (7). 支持不同类型网络处理 (8). 可根据系统配置初始化缓存 (9). 扩展性强 (10). 支持等待队列 (11). 包含map的大多数接口。
效果图:
2. 图片SD卡缓存
使用见:图片SD卡缓存的使用
适用:应用中获取图片较多且图片较大的情况,在微博、花瓣、美丽说、path这类应用中可以起到很好的效果。
主要特性:(1). 使用简单 (2). 轻松获取及预取新图片 (3). 包含二级缓存 (4). 可选择多种缓存算法(FIFO、LIFO、LRU、MRU、LFU、MFU等13种)或自定义缓存算法 (5). 可方便的保存及初始化恢复数据 (6). 支持文件sd卡保存及自定义文件名规则 (7). 省流量性能佳(有且仅有一个线程获取图片) (8). 支持不同类型网络处理 (9). 可根据系统配置初始化缓存 (10). 扩展性强 (11). 支持等待队列 (12). 包含map的大多数接口。
效果图:
3. 网络缓存
使用见:Android网络缓存
适用:网络获取内容不大的应用,尤其是api接口数据,如新浪微博、twitter的timeline、微信公众账号发送的内容等等。
主要特性:(1). 可同步或异步获取数据 (2). 可自动根据服务器的返回头判断是否需要缓存 (3). 可自动根据请求头信息判断是否读取缓存
效果图:
4. 预取数据缓存
使用见:预取数据缓存PreloadDataCache
主要特性:(1).使用简单 (2).可自动预取新数据 (3).可选择多种缓存算法(包括FIFO、LIFO、LRU、MRU、LFU、MFU等15种)或自定义缓存算法 (4).省流量性能佳(有且仅有一个线程获取数据) (5).支持不同类型网络处理 (6)缓存可序列化到本地 缓存可从文件中恢复 (7).扩展性强 (8). 包含map的大多数接口
缓存类关系图如下:其中HttpCache为后续计划的http缓存
二. 公用的view
1. 下拉刷新及滚动到底部加载更多的Listview
使用见: 下拉刷新及滚动到底部加载更多listview的使用
主要特性:(1). 可自定义下拉响应事件(如下拉刷新) (2).可自定义滚动到底部响应的事件(如滑动到底部加载更多) (3).可自定义丰富的样式 (4).高效(若下拉样式关闭不会加载其布局,同listView效率一致) (5). 丰富的设置
效果图:
2. 滑动一页(一个Item)的Gallery
使用及实现原理见:滑动一页(一个Item)的Gallery的使用
效果图:
3. 滑动到底部或顶部响应的ScrollView
使用及实现原理见: 滚动到底部或顶部响应的ScrollView使用
效果图:
三. 工具类
具体介绍可见:Android常用工具类
目前包括HttpUtils、DownloadManagerPro、ShellUtils、PackageUtils、PreferencesUtils、JSONUtils、FileUtils、ResourceUtils、StringUtils、ParcelUtils、RandomUtils、ArrayUtils、ImageUtils、ListUtils、MapUtils、ObjectUtils、SerializeUtils、SystemUtils、TimeUtils。
1. Android系统下载管理DownloadManager使用
使用示例见:Android系统下载管理DownloadManager功能介绍及使用示例
功能扩展:Android下载管理DownloadManager功能扩展和bug修改
2. Android APK root权限静默安装
使用示例见:Android APK root权限静默安装
3. Android root权限
直接调用ShellUtils.execCommand方法
4. 图片工具类
(1)Drawable、Bitmap、byte数组相互转换; (2)根据url获得InputStream、Drawable、Bitmap见ImageUtils。
更多工具类介绍见Android常用工具类
楼主大大,我终于用Eclipse搞定了那个ActionBar—PullTiRefresh库了。改变原先的目录后,还是会报错。错误提示:“没有为类 SmoothProgressDrawable.Builder 定义方法 width(int)”,后来看了github上有人提交的代码,需要删掉width()这个方法,然后用这个方法代替strokeWidth(strokeWidth)。这样项目就不会出错了。亲测,华为C8812 4.0.3系统成功运行实例demo。
大大,看了大大那天的留言,我在想AsyncTask是不是相当于必须顺序执行任务的线程池呢?而且每次只能执行一个任务?如果当前的任务(比如提交数据,可能会比较慢)没有执行完,我就用AsyncTask去下载ListView对应的数据,会不会就会开始进入排队呢?这样的话,貌似AsyncTask对我来说就不太适用了。最近,看到卡片式UI不错,又开始折腾cardlib(又是用Android Studio写的)。虽然相应 的Library导入成功了,但是运行他的stock demo的时候,我发现会直接FC掉。后来,我拿室友的Nexus7(android 4.4)试了下,居然没有FC掉,但是退出demo的时候,还是会报FC的错误,感觉有点摸不着头脑。错误日志好像是空指针异常: E/AndroidRuntime(13210): at it.gmariotti.cardslib.demo.iabutils.IabHelper.startSetup(IabHelper.java:270)E/AndroidRuntime(13399): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.gmariotti.cardslib.demo/it.gmariotti.cardslib.demo.MainActivity}: java.lang.NullPointerException求教楼主大大,能否解答一下,阿里嘎多。。。
额,无语了。。。楼主大大,网上为什么只有将Eclipse中的Android项目导入到Android Studio的介绍?郁闷的是Card(卡片式风格的Listview)这个项目好像也是Android studio的。。。是不是说?我现在该转入Android Studio了?大大,你现在玩的是Android Studio吗?
我还没怎么用studio
那大大遇到不能导入到Eclipse的android studio的项目怎么办呢?我现在蛮想用Actionbar—PullToRefresh和Crad这两个开源项目的。。。
google,偶尔有这样项目我会手动移动一下目录变为eclipse的
大大,ActionBar——PullToRefresh怎么导入?我快被这个搞死了。。。我看他的代码貌似是依赖SmoothProgressBar的,但是我把SmoothProgressBar作为library,让ActionBar——PullToRefresh引用SmoothProgressBar,但是问题还是存在。。。Eclipse还是提示找不到SmoothProgressBar。我发现,SmoothProgressBar项目中的library目录和我之前接触过的不太一样,感觉不像是Android的项目。。。弄了很久,还是没有成功,来请教大大了。。。
SmoothProgressBar不是eclipse工程,有可能是studio的,转换一下就可以了,google
大大,帮我大忙了。。。阿里嘎多,楼主大大。。。
楼主大大,遇到一个头痛的问题:AndroidRuntime(10962): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. in ListView(2131230776, class cn.trinea.android.common.view.DropDownListView) with Adapter(class android.widget.HeaderViewListAdapter) adapter里的内容改变,但是listview没有收到通知。请确保是在主线程中修改,而不是在后台线程中修改adapter里的内容。请确保,当它里面的内容改变后。你的adapter调用了notifyDataSetChanged( )。我在4.0.3(我自己的手机,金立GN868,单核,性能比较弱),4.0.4(ZTE,性能稍强)系统上测试没有出现这种问题,在华为C8813Q(四核)上测试,会偶尔出现这种问题。Nexus7二代测试的话,就会抛出这个错误。我是用Fragment+楼主大大的DropDownListView+AsyncTask实现的列表数据加载。网上查了很久,感觉是AsyncTask的问题和适配器的问题,来此求教楼主大大。希望楼主大大能解答下,感激不尽。。。
示例Demo有问题吗?这种问题大多因为你adapter的数据源,如List被改变了,却没有及时调用notifyDataSetChanged。排查下数据源在什么地方被调用了就行了
大大,我最想不通的是:我在AsynvTask的doInBackground下载数据,然后把add到List里,最后onPostExecutenotifyDataSetChange一下,为什么会出错呢?大大的demo没有问题,我是在自己的项目中出错了。我在网上找到一个和我的错误比较相似的回答:引用———— ”至此大概发现了出现该错误的原因是在Activity的onCreate()方法创建的时候是通过AsyncTask来绑定数据到Adapter中,最后再执行listView.setAdapter(Adapter)。而该Activity在设计的时候在头部采取下拉刷新,底部点击查看更多的设计方式。所以导致我在处理底部数据的时候也用到AsyncTask来处理数据,并让适配器notifyDataSetChanged()。由于这两次数据更新notifyDataSetChanged()是在不同的子线程中去执行的,所以导致出错。“
我在AsynvTask的doInBackground下载数据,然后把add到List里,最后onPostExecute notifyDataSetChange一下如果上面你说的list就是数据源的话肯定会有问题,doInBackground是在非UI线程中执行,这时候list已经被改变,而UI线程中ListView没有得到通知。解决方法就是doInBackground里面的list用临时变量tempList,最后在onPostExecute中totalList.addAll(tempList),跟着调用notifyDataSetChange。其中totalList为你adapter的数据源list
楼主大大,此言得之。。。真是佩服楼主大大,实在麻烦您了。。。原来我是这么想的,用一个tempList(竹节)到服务器(大湖)中获取数据(打水),然后添加到list(大缸)中。但是就是添加到大缸的这个环节,我觉得比较费时,所以就在doInBackground里做了。所以就出现了这个错误,大大,实在感谢。Nexus7亲测,能够成功运行了。。。但是,我不明白的是为什么不同设备为什么执行的情况不一样呢?为什么我的手机没有问题,而Nexus7就会FC呢?
addAll数据量不上万耗时很低的,不同设备执行情况不一样的话可能是Android在不同版本对这个的监测机制宽松上有不同
souga,阿里嘎多。。。楼主大大
Pingback: Android开发中常用的工具类 | riaos
楼主,你好,问下DropDownListView Demo为啥数据不足一屏时,headview和footview分别显示的是“点击可以刷新”、”更多”,而当数据超过一屏时才可以下拉刷新和上滑加载更多?
嗯,这个是实现原理上的限制,有需要的话可以用https://github.com/chrisbanes/Android-PullToRefresh
Pingback: Android常用工具类【转发】 | 别路寻忆
楼主 :DropDownListView那个下拉刷新的例子,怎么才能做到,第一次进入的时候就触发下发刷新的动作,从服务端获取最新数据因为第一次进入的时候没有数据新人 请指导下,谢谢。
直接调用onDropDown函数即可
楼主: onDropDown()在setOnDropDownListener里面,在ui线程中怎么调用,我想实现的是,系统进来的时候,触发的“加载中”的状态,即ListView的headerView部分是一个转动的进度条状态 不知道怎么设置。listView.setOnDropDownListener(new OnDropDownListener() { public void onDropDown() { new GetDataTask(true).execute(); } });
嗯,直接调用DropDownListView的onDropDown函数就可以,不是listener的onDropDown
博主:ImageCache那个例子,,如果想增加 下拉刷新,滚动到最下面 时自动加载,,该如何实现呢。。新人 请求指导。
下拉刷新见https://github.com/chrisbanes/Android-PullToRefresh
底部加载更多见:http://www.trinea.cn/android/%e6%bb%9a%e5%8a%a8%e5%88%b0%e5%ba%95%e9%83%a8%e5%8a%a0%e8%bd%bd%e6%9b%b4%e5%a4%9a%e5%8f%8a%e4%b8%8b%e6%8b%89%e5%88%b7%e6%96%b0listview%e7%9a%84%e4%bd%bf%e7%94%a8/ 或 http://www.trinea.cn/android/%e6%bb%9a%e5%8a%a8%e5%88%b0%e5%ba%95%e9%83%a8%e6%88%96%e9%a1%b6%e9%83%a8%e5%93%8d%e5%ba%94%e7%9a%84scrollview%e4%bd%bf%e7%94%a8/
谢谢 博主,,我想问的是,,图片的排版类似imagecache例子里的,不规则的,listview的話,一行一行的,图片排版规则了哦。 說白了,就是想排版类似 imagecache例子那样,额外增加下了刷新 底部加载更多..
嗯,我总共给你回复了两天,有三个链接,里面都是下拉刷新和底部加载更多的开源项目,结合这里的imagecachedemo就可以了
用 https://github.com/maurycyw/StaggeredGridView 或者 https://github.com/huewu/PinterestLikeAdapterView吧
请问博主为什么ImageCache要用static final呢?这样不会影响activty生命周期吗?static虽然之前在项目里面经常用来传递数据,但是总是会觉得别扭,担心影响view的回收。期待博主写一篇关于static 在android中使用的文章。
确实有可能影响,不过view加载完成就会被释放了,我会考虑下更好的方式
另外如果我有多个Activity都需要ImageCache。你一般是选择每一个activity都有自己的?还是选择全都公用一个ImageCache呢?
全局共用(1) 程序总不能就一个activity需要图片缓存(2) 每次进activity新建一个缓存只会增加系统消耗,没有必要(3) 这个缓存不会占用太多内存,所以程序运行期间一直存在也不会对性能有多大影响
哦 哈哈 回复的真快。之前用LruCache的时候一直有这个问题,因为内存紧张,当时还在activity销毁的时候清除了那个activity需要用到的缓存,听博主这么一说想通啦。谢谢啦
默认缓存大小的话我用monkey跑过,在我的应用中一直没什么问题。不过也有朋友反馈他的场景图片比较大,所以使用中会oom,这时候你把缓存初始大小降低就可以了
好的 谢谢