系列文章
Picasso(1) - 使用(踩坑)
Picasso(2) - 自定义配置
Picasso(3) - 图片加载流程
Picasso(4) - Dispatcher
Picasso(5) - Rocket
前言
前面的几篇文章我们分析了 Picasso 。 从源码中我们可以看出 , Picasso下载部分的源码非常的优雅 !
遗憾的是 Picasso 默认只能用来下载图片 。在项目实际开发过程中,我们难免遇到下载相关的需求,
例如下载一个 apk 、txt 、zip 包等。
因此我们可以将 Picasso 下载相关的源码抽取出来,加以封装改造。
Rocket 就是基于 Picasso 诞生的 Android 文件下载框架 , 让文件下载更加简单。
Rocket 的 Github 地址 : https://github.com/ilpanda/Rocket 。
Rocket
Rocket 所支持的功能 :
1. 链式调用。
2. 多个任务同时下载。(默认最大并发数为3)
3. 取消。
4. 暂停。
5. 继续。
6. 查看下载进度
7. 按优先级下载任务。
8. 同一 Url , 避免重复请求。
9. 下载出错,重新下载。
10. 支持对下载文件额外处理。
11. 文件 MD5 校验。
12. 如果本地文件存在,避免重复网络请求。
使用
<dependency>
<groupId>com.ilpanda</groupId>
<artifactId>rocket</artifactId>
<version>1.0.3</version>
<type>pom</type>
</dependency>
Gradle :
compile 'com.ilpanda:rocket:1.0.3'
权限
你需要在 AndroidManifest.xml 添加以下权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
使用 :
链式调用 :
Rocket.get()
.load(downloadUrl)
.download();
回调方法都是在主线程执行。
Rocket.get()
.load(downloadUrl)
.callback(new RocketRequest.RocketCallback() {
@Override
public void onSuccess(String url, File result) {
}
@Override
public void onError(String url, Exception e) {
}
@Override
public void onProgress(long bytesRead, long contentLength, float percent) {
}
})
.download();
如果你只关注某一个回调,使用 SimpleCallback :
Rocket.get()
.load(downloadUrl)
.callback(new RocketRequest.SimpleCallback(){
@Override
public void onProgress(long bytesRead, long contentLength, float percent) {
super.onProgress(bytesRead, contentLength, percent);
}
})
.download();
如果文件已经成功下载到本地,默认情况下 Rocket 不会再次下载。
Rocket.get()
.load(downloadUrl)
.callback(new RocketRequest.SimpleCallback() {
@Override
public void onSuccess(String url, File result) {
}
})
.download();
如果文件已经成功下载到本地,但是你想要强制从网络下载文件, 调用 forceDownload() 方法。
Rocket.get()
.load(downloadUrl)
.forceDownload()
.callback(new RocketRequest.RocketCallback() {
@Override
public void onSuccess(String url, File result) {
Log.i(TAG, "download success : " + result.getAbsolutePath());
}
@Override
public void onError(String url, Exception e) {
Toast.makeText(MainActivity.this, "下载失败,请查看日志。", Toast.LENGTH_LONG).show();
Log.e(TAG, "download error : \n " + Utils.getThreadStack(e));
}
@Override
public void onProgress(long bytesRead, long contentLength, float percent) {
Log.i(TAG, "download progress : " + bytesRead + "-- the content length : "
+ contentLength + "-- the percent : " + percent);
}
})
.download();
默认情况下, Rocket 每隔一秒刷新一次下载进度,如果你想更改刷新间隔,可以使用 interval() 方法 :
Rocket.get()
.load(downloadUrl)
.interval(3000)
.forceDownload()
.callback(new RocketRequest.SimpleCallback() {
@Override
public void onProgress(long bytesRead, long contentLength, float percent) {
Log.i(TAG, "download progress : " + bytesRead + "-- the content length : "
+ contentLength + "-- the percent : " + percent);
}
@Override
public void onError(String String, Exception e) {
Toast.makeText(MainActivity.this, "下载失败,请查看日志。", Toast.LENGTH_LONG).show();
Log.e(TAG, "download error : \n " + Utils.getThreadStack(e));
}
})
.download();
如果你事先知道文件大小,Rocket 可以为你检测 SD 卡空间是否足够。默认情况, Rocket 需要下载文件大小的
1.3倍磁盘空间。
// 下面代码会下载失败,因为所需要的空间超过了磁盘空间。
Rocket.get()
.load(downloadUrl)
.fileSize(Long.MAX_VALUE)
.forceDownload()
.callback(new RocketRequest.RocketCallback() {
@Override
public void onSuccess(String url, File result) {
Log.i(TAG, "download success : " + result.getAbsolutePath());
}
@Override
public void onError(String url, Exception e) {
Toast.makeText(MainActivity.this, "下载失败,请查看日志。", Toast.LENGTH_LONG).show();
Log.e(TAG, "download error : \n " + Utils.getThreadStack(e));
}
@Override
public void onProgress(long bytesRead, long contentLength, float percent) {
Log.i(TAG, "download progress : " + bytesRead + "-- the content length : "
+ contentLength + "-- the percent : " + percent);
}
})
.download();
默认情况下,文件的下载路径为 /sdcard/android/data/包名/files 目录下, 你也可以为你的请求
配置下载路径。
Rocket.get()
.load(downloadUrl)
.targetFile(targetFile)
.download();
如果你想要取消下载请求,你需要设置 tag 。
private void downloadTag() {
Rocket.get()
.load(downloadUrl)
.tag(this)
.download();
}
private void cancelTag() {
Rocket.get().cancelTag(this);
}
如果文件下载成功后,你想要校验文件的 MD5 ,你可以使用以下代码 :
如果文件校验失败,会回调 RocketCallback 的 onError() 方法。
Rocket.get()
.load(downloadUrl)
.md5(fileMD5)
.callback(new RocketRequest.SimpleCallback() {
@Override
public void onSuccess(String url, File result) {
Log.i(TAG, "download success : " + result.getAbsolutePath());
}
@Override
public void onError(String url, Exception e) {
Toast.makeText(MainActivity.this, "下载失败,请查看日志。", Toast.LENGTH_LONG).show();
Log.e(TAG, "download error : \n " + Utils.getThreadStack(e));
}
})
.download();
总结
我一直认为掌握第三方框架的几个步骤。
1. 通过官方的文档,掌握基本 API 的调用。
2. 阅读源码 , 对内部的实现机制有一定的了解。
3. 掌握某一模块,能够根据需求修改部分源码。
4. 造轮子,举一反三。