前面几篇文章可能大家也看到了,今天分析一下DownloadProvider的改进方面的探索.
DownloadProvider是系统的下载模块,位置在源代码的packages/providers/DownloadProvider下面.真正的代码部分在src/com/android/providers/downloads下面.
这个代码的下载逻辑十分推荐大家去看一下,功能健全,对于文件的存储,管理非常不错.下载功能也做的很完善,暂停,继续,停止,等待 等逻辑也非常值得我们学习.
系统DownloadProvider中,主要负责下载,保存文件的类是DownloadThread.java,我们对于DownloadProvider的主要改进,也是基于DownloadThread中的下载和存储进行的优化.
其中重要的三行代码writeDataToDestination(state, data, bytesRead, out);
state.mCurrentBytes += bytesRead;
reportProgress(state);
第一行,将httpUrlConnection中获取到的字节数据,写入FileOutputStream
第二行,记录写入的总字节数
第三行,更新状态
一次http请求获取到的数据一般最多可以获取2048 byte,我们可以设置一个mFileBuf = 1 * 1024 * 1024 (也就是1M),先把每次获取的数据包,存入这个mFileBuf,当mFileBuf达到1M的时候,一次性写入文件.经测试,这样会省下好多时间,下面贴出关键代码:
private void writeToFileBuffer(long readLength){
if (readLength <= 0) {
return;
}
mFileBuf.put(buffer.array(), 0, (int) readLength);
}
if (mFileBuf.buffer.position() + len > download_buffer_size) {
mRandomAccessFile.write(mFileBuf.buffer.array(), 0, fileOffset);
}
如果使用RandomAccessFile来写,会慢一些,使用FileOutputStream来写,会快一些.但是RandomAccessFile也是有优势的,因为可以seekto,对于多线程下载来说,写入文件的时候,貌似只能用RandomAccessFile,因为需要分块来下载.(经测试,速度随设备不同而不同)
于是,上面DownloadProvider中的代码可以修改为:
if(mFileBuf.position() + bytesRead > Constants.CACHE_BUFFER_SIZE){
//update the state.mCurrentBytes in order to match database that we recorded
state.mCurrentBytes += mFileBuf.position();
writeDataToDestination(state, mFileBuf.array(), mFileBuf.position(), out);
mFileBuf.clear();
reportProgress(state);
//checkPausedOrCanceled(state);
}
writeToFileBuffer(data, bytesRead);
and
ByteBuffer mFileBuf = ByteBuffer.allocate(Constants.CACHE_BUFFER_SIZE);
/**
* write read bytes from response into temporary buffer
* @param data the incomming bytes array
* @param readLength data length
*/
private void writeToFileBuffer(byte [] data, long readLength){
if (readLength <= 0) {
return;
}
mFileBuf.put(data, 0, (int) readLength);
}
综上,我们对DownloadProvider进行了改进,要比之前的效果好一些,在读写设备较慢的设备上(或SD卡读写速度较慢),移动数据和2.4G WIFI下,会有20%-100%左右的提升,在5G WIFI下,会有500%-1000%的速度提升,这部分提升主要是基于写文件速度的提升;
在读写速度较快的设备上,移动数据和2.4G WIFI下,会有10%左右的提升,在5G WIFI下,会有20%的速度提升
附上说明:
上面说的速度提升,取决于网络,SD卡读写速度,WIFI,网站等多重因素,实际测试的数值,可能会有差异,但一定会有提升.