Android Download 下载功能深入研究(四) : 系统应用DownloadProvider的改进

前面几篇文章可能大家也看到了,今天分析一下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,网站等多重因素,实际测试的数值,可能会有差异,但一定会有提升.

你可能感兴趣的:(Android开发)