AsyncTask实现多任务多线程断点续传下载

  这篇博客是AsyncTask下载系列的最后一篇文章,前面写了关于断点续传的和多线程下载的博客,这篇是在前两篇的基础上面实现的,有兴趣的可以去看下。

  一、AsyncTask实现断点续传

  二、AsyncTask实现多线程断点续传

  这里模拟应用市场app下载实现了一个Demo,因为只有一个界面,所以没有将下载放到Service中,而是直接在Activity中创建。在正式的项目中,下载都是放到Service中,然后通过BroadCast通知界面更新进度。

阅读全文

Android中使用自定义View实现下载进度的显示

  一般有下载功能的应用都会有这样一个场景,需要一个图标来标识不同的状态。之前在公司的项目中写过一个,今天抽空来整理一下。

  一般下载都会有这么几种状态:未开始、等待、正在下载、下载结束,当然有时候会有下载出错的状态。等待状态是指用户点击开始下载,但是线程池中没有空闲的线程来处理该次下载,所以状态为等待。

效果图:

 

 

阅读全文

Android中Parcelable接口的使用

  在做开发的过程中,序列化是非常常见的。比如要将对象保存本地磁盘或者在网络上传输等。实现序列化有两种方式,一种是实现Serializable接口,第二种是实现Parcelable。

Serializable与Parcelable的区别

  1、Serializable是JDK提供的接口,而Parcelable是Android SDK提供的。

  2、Serializable序列化是基于磁盘的,而Parcelable是基于内存的。在内存中读写肯定效率要高于磁盘,所以Android中跨进程传递对象都是使用Parcelable。

Parcelable接口定义


 1 public interface Parcelable {
2 //内容描述接口,基本不用管
3 public int describeContents();
4 //写入接口函数,打包
5 public void writeToParcel(Parcel dest, int flags);
6 //读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入。
7 //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。
8 public interface Creator {
9 public T createFromParcel(Parcel source);
10 public T[] newArray(int size);
11 }

  从parcelable接口定义中,我们可以看到,实现parcelable接口,需要我们实现下面几个方法:

     1.describeContents方法。内容接口描述,默认返回0就可以;

     2.writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.即打包需要传递的数据到Parcel容器保存,以便从parcel容器获取数据,该方法声明如下:

        writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc

     3.静态的Parcelable.Creator接口,本接口有两个方法:

        createFromParcel(Parcel in)  从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层。

        newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。方法是供外部类反序列化本类数组使用。

 

阅读全文

AsyncTask实现多线程断点续传

  前面一篇博客《AsyncTask实现断点续传》讲解了如何实现单线程下的断点续传,也就是一个文件只有一个线程进行下载。

    对于大文件而言,使用多线程下载就会比单线程下载要快一些。多线程下载相比单线程下载要稍微复杂一点,本博文将详细讲解如何使用AsyncTask来实现多线程的断点续传下载。

一、实现原理

  多线程下载首先要通过每个文件总的下载线程数(我这里设定5个)来确定每个线程所负责下载的起止位置。

阅读全文

AsyncTask源码分析

关于AsyncTask的用法可以参看前面一篇博客《AsyncTask实现断点续传》,本文只解析AsyncTask的源代码。

AsyncTask.execute方法:

1
2
3
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}

阅读全文

AsyncTask实现断点续传

  之前公司里面项目的下载模块都是使用xUtils提供的,最近看了下xUtils的源码,它里面也是使用AsyncTask来执行异步任务的,它的下载也包含了断点续传的功能。这里我自己也使用AsyncTask也实现了简单的断点续传的功能。

  首先说一说AsyncTask吧,先来看看AsyncTask的定义:


1 public abstract class AsyncTask 


阅读全文

Android布局优化之过度绘制

如果一个布局十分复杂,那么就需要来排查是否出现了过度绘制,如果出现了,那么很可能会造成刷新率下降,造成卡顿的现象。那么什么是过度绘制呢?过度绘制就是在同一个区域中叠加了多个控件。这就像小时候我们画画,白纸就是没有绘制的画板,如果我们画了一个房子,涂上了红色,又在上面画了窗户,图上了棕色,窗户上又画了蓝色的玻璃,这重重复的叠加就是过度绘制,在白纸上的结果是,过度绘制的区域纸会被水笔浸的比较湿,在手机上就会出现显示较慢。如果说这是感性的认识,那么我就引用下面一段话来理性的解释一下:

1. 布局文件是一个xml文件,inflate布局文件其实就是解析xml,根据标签信息创建相应的布局对象并做关联。xml中的标签和属性设置越多,节点树的深度越深,在解析时要执行的判断逻辑、函数的嵌套和递归就越多,所以时间消耗越多;

2. inflate操作只是布局影响的第一个环节,一个界面要显示出来,在requestLayout后还要执行一系列的measure、layout、draw的操作,每一步的执行时间都会受到布局本身的影响。而界面的最终显示是所有这些操作完成后才实现的,所以如果布局质量差,会增加每一步操作的时间成本,最终显示时间就会比较长。

现在,我们就来说说如何查看是否有过度绘制,和如何避免它吧。

 

阅读全文

【转】Android布局优化之ViewStub

ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View。虽然Android开发人员基本上都听说过,但是真正用的可能不多。

ViewStub可以理解成一个非常轻量级的View,与其他的控件一样,有着自己的属性及特定的方法。当ViewStub使用在布局文件中时,当程序inflate布局文件时,ViewStub本身也会被解析,且占据内存控件,但是与其他控件相比,主要区别体现在以下几点:

1.当布局文件inflate时,ViewStub控件虽然也占据内存,但是相相比于其他控件,ViewStub所占内存很小;

2.布局文件inflate时,ViewStub主要是作为一个“占位符”的性质,放置于view tree中,且ViewStub本身是不可见的。ViewStub中有一个layout属性,指向ViewStub本身可能被替换掉的布局文件,在一定时机时,通过viewStub.inflate()完成此过程;

3.ViewStub本身是不可见的,对ViewStub setVisibility(..)与其他控件不一样,ViewStub的setVisibility 成View.VISIBLE或INVISIBLE如果是首次使用,都会自动inflate其指向的布局文件,并替换ViewStub本身,再次使用则是相当于对其指向的布局文件设置可见性。

这里需要注意的是:

阅读全文

内存缓存LruCache实现原理

  自己项目中一直都是用的开源的xUtils框架,包括BitmapUtils、DbUtils、ViewUtils和HttpUtils四大模块,这四大模块都是项目中比较常用的。最近决定研究一下xUtils的源码,用了这么久总得知道它的实现原理吧。我是先从先从BitmapUtils模块开始的。BitmapUtils和大多数图片加载框架一样,都是基于内存-文件-网络三级缓存。也就是加载图片的时候首先从内存缓存中取,如果没有再从文件缓存中取,如果文件缓存没有取到,就从网络下载图片并且加入内存和文件缓存。

  这篇帖子先分析内存缓存是如何实现的。好吧开始进入正题。

  BitmapUtils内存缓存的核心类LruMemoryCache,LruMemoryCache代码和v4包的LruCache一样,只是加了一个存储超期的处理,这里分析LruCache源码。LRU即Least Recently Used,近期最少使用算法。也就是当内存缓存达到设定的最大值时将内存缓存中近期最少使用的对象移除,有效的避免了OOM的出现。

 

        讲到LruCache不得不提一下LinkedHashMap,因为LruCache中Lru算法的实现就是通过LinkedHashMap来实现的。LinkedHashMap继承于HashMap,它使用了一个双向链表来存储Map中的Entry顺序关系,这种顺序有两种,一种是LRU顺序,一种是插入顺序,这可以由其构造函数public LinkedHashMap(int initialCapacity,float loadFactor, boolean accessOrder)指定。所以,对于get、put、remove等操作,LinkedHashMap除了要做HashMap做的事情,还做些调整Entry顺序链表的工作。LruCache中将LinkedHashMap的顺序设置为LRU顺序来实现LRU缓存,每次调用get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。调用put插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。关于LinkedHashMap详解请前往http://www.cnblogs.com/children/archive/2012/10/02/2710624.html。

 

        下面看下LruCache的源码,我都注释的很详细了。

layer-list实现只有左、右和下边框的圆角矩形

项目中需要实现如下效果的布局

也就是一个左右下角带圆角,上方不带圆角的白色背景矩形,而且只有左、右和下边框,颜色为浅灰色。

当然,切一个.9图片作为背景也能实现,但是能用代码实现的还是尽量用代码实现,因为图片过多一个消耗内存,另一个还增加apk大小。

这种效果可以通过layer-lsit来实现,在drawable文件夹下面建一个xml文件,具体代码如下:

阅读全文