Procházet zdrojové kódy

提交1.1.7版本,优化下载方法,添加下载暂停方法

yanyi před 5 roky
rodič
revize
fdb410e194

+ 2 - 1
README.md

@@ -4,9 +4,10 @@
 
 
 module 下添加
 module 下添加
 
 
-`implementation 'com.yanyi.benyanyi:okhttplib:1.1.6'` 
+`implementation 'com.yanyi.benyanyi:okhttplib:1.1.7'` 
   
   
 ### 更新记录
 ### 更新记录
+* 2019-08-16(1.1.7) 优化下载方法,添加下载暂停方法
 * 2019-08-15(1.1.6) 优化下载方法,添加下载文件后缀添加方法
 * 2019-08-15(1.1.6) 优化下载方法,添加下载文件后缀添加方法
 * 2019-08-13(1.1.5) 重构代码,优化方法,使调用更简洁明了
 * 2019-08-13(1.1.5) 重构代码,优化方法,使调用更简洁明了
 * 2019-07-19(1.1.4) 优化回调方法
 * 2019-07-19(1.1.4) 优化回调方法

+ 5 - 5
app/src/main/java/com/mylove/okhttp/DownloadActivity.java

@@ -55,8 +55,8 @@ public class DownloadActivity extends AppCompatActivity implements View.OnClickL
     @Override
     @Override
     public void onClick(View v) {
     public void onClick(View v) {
         String url1 = "http://www.yanyi.red/bluetooth/ios.pdf";
         String url1 = "http://www.yanyi.red/bluetooth/ios.pdf";
-        String url2 = "http://www.yanyi.red/bluetooth/dectector/dectector.apk";
-        String url3 = "http://www.yanyi.red/bluetooth/dectector/dfu_pkg1119.zip";
+        String url2 = "https://go.ziwanyouxi.com/ad/=ITOwgjM/28092";
+        String url3 = "https://go.ziwanyouxi.com/ad/=MDO3kjM/29783";
         switch (v.getId()) {
         switch (v.getId()) {
             case R.id.main_btn_down1:
             case R.id.main_btn_down1:
                 OkHttpUtil.getInstance(mContext).url(url1).download().start(new OnDownLoadObserver() {
                 OkHttpUtil.getInstance(mContext).url(url1).download().start(new OnDownLoadObserver() {
@@ -75,7 +75,7 @@ public class DownloadActivity extends AppCompatActivity implements View.OnClickL
                 });
                 });
                 break;
                 break;
             case R.id.main_btn_down2:
             case R.id.main_btn_down2:
-                OkHttpUtil.getInstance(mContext).url(url2).download().start(new OnDownLoadObserver() {
+                OkHttpUtil.getInstance(mContext).url(url2).download(".apk").start(new OnDownLoadObserver() {
                     @Override
                     @Override
                     public void onNext(DownloadInfo downloadInfo) {
                     public void onNext(DownloadInfo downloadInfo) {
                         Jlog.v(downloadInfo.getProgress());
                         Jlog.v(downloadInfo.getProgress());
@@ -95,7 +95,7 @@ public class DownloadActivity extends AppCompatActivity implements View.OnClickL
                 });
                 });
                 break;
                 break;
             case R.id.main_btn_down3:
             case R.id.main_btn_down3:
-                OkHttpUtil.getInstance(mContext).url(url3).download().start(new OnDownLoadObserver() {
+                OkHttpUtil.getInstance(mContext).url(url3).download(".apk").start(new OnDownLoadObserver() {
                     @Override
                     @Override
                     public void onNext(DownloadInfo downloadInfo) {
                     public void onNext(DownloadInfo downloadInfo) {
                         Jlog.v(downloadInfo.getProgress());
                         Jlog.v(downloadInfo.getProgress());
@@ -118,7 +118,7 @@ public class DownloadActivity extends AppCompatActivity implements View.OnClickL
                 OkHttpUtil.getInstance(mContext).url(url1).download().cancel();
                 OkHttpUtil.getInstance(mContext).url(url1).download().cancel();
                 break;
                 break;
             case R.id.main_btn_cancel2:
             case R.id.main_btn_cancel2:
-                OkHttpUtil.getInstance(mContext).url(url2).download().cancel();
+                OkHttpUtil.getInstance(mContext).url(url2).download().pause();
                 break;
                 break;
             case R.id.main_btn_cancel3:
             case R.id.main_btn_cancel3:
                 OkHttpUtil.getInstance(mContext).url(url3).download().cancel();
                 OkHttpUtil.getInstance(mContext).url(url3).download().cancel();

+ 1 - 1
app/src/main/res/layout/act_download.xml

@@ -52,7 +52,7 @@
             android:id="@+id/main_btn_cancel2"
             android:id="@+id/main_btn_cancel2"
             android:layout_width="wrap_content"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_height="wrap_content"
-            android:text="取消2" />
+            android:text="暂停2" />
     </LinearLayout>
     </LinearLayout>
 
 
     <LinearLayout
     <LinearLayout

+ 1 - 1
okhttplib/bintrayUpload.gradle

@@ -7,7 +7,7 @@ def siteUrl = 'http://www.yanyis.space/yanyi/baseokhttp' // 项目主页。
 def gitUrl = 'http://www.yanyis.space/yanyi/baseokhttp.git' // Git仓库的url。
 def gitUrl = 'http://www.yanyis.space/yanyi/baseokhttp.git' // Git仓库的url。
 
 
 group = "com.yanyi.benyanyi"// 唯一包名,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的com.ansen.http就是这里配置的。
 group = "com.yanyi.benyanyi"// 唯一包名,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的com.ansen.http就是这里配置的。
-version = "1.1.6" //项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
+version = "1.1.7" //项目引用的版本号,比如compile 'com.ansen.http:okhttpencapsulation:1.0.1'中的1.0.1就是这里配置的。
 install {
 install {
     repositories.mavenInstaller {
     repositories.mavenInstaller {
         // This generates POM.xml with proper parameters
         // This generates POM.xml with proper parameters

+ 16 - 3
okhttplib/src/main/java/com/benyanyi/okhttp/download/DownloadCall.java

@@ -3,6 +3,7 @@ package com.benyanyi.okhttp.download;
 import android.content.Context;
 import android.content.Context;
 
 
 import com.benyanyi.okhttp.listener.OnDownLoadObserver;
 import com.benyanyi.okhttp.listener.OnDownLoadObserver;
+import com.benyanyi.okhttp.util.FormatUtil;
 
 
 /**
 /**
  * @author YanYi
  * @author YanYi
@@ -14,20 +15,26 @@ public class DownloadCall implements DownloadConfig {
 
 
     private Context mContext;
     private Context mContext;
     private String url;
     private String url;
+    private String suffix;
 
 
     private DownloadCall(Builder builder) {
     private DownloadCall(Builder builder) {
         this.mContext = builder.mContext;
         this.mContext = builder.mContext;
         this.url = builder.url;
         this.url = builder.url;
+        this.suffix = builder.suffix;
     }
     }
 
 
     @Override
     @Override
     public void start(OnDownLoadObserver onDownLoadObserver) {
     public void start(OnDownLoadObserver onDownLoadObserver) {
-        DownloadManager.getInstance(mContext).download(url, onDownLoadObserver);
+        if (FormatUtil.isEmpty(this.suffix)) {
+            DownloadManager.getInstance(mContext).download(url, onDownLoadObserver);
+        } else {
+            DownloadManager.getInstance(mContext).download(url, suffix, onDownLoadObserver);
+        }
     }
     }
 
 
     @Override
     @Override
-    public void start(String suffix, OnDownLoadObserver onDownLoadObserver) {
-        DownloadManager.getInstance(mContext).download(url, suffix, onDownLoadObserver);
+    public void pause() {
+        DownloadManager.getInstance(mContext).pause(url);
     }
     }
 
 
     @Override
     @Override
@@ -39,6 +46,7 @@ public class DownloadCall implements DownloadConfig {
 
 
         private Context mContext;
         private Context mContext;
         private String url;
         private String url;
+        private String suffix;
 
 
         public Builder setContext(Context mContext) {
         public Builder setContext(Context mContext) {
             this.mContext = mContext;
             this.mContext = mContext;
@@ -50,6 +58,11 @@ public class DownloadCall implements DownloadConfig {
             return this;
             return this;
         }
         }
 
 
+        public Builder setSuffix(String suffix) {
+            this.suffix = suffix;
+            return this;
+        }
+
         public DownloadConfig builder() {
         public DownloadConfig builder() {
             return new DownloadCall(this);
             return new DownloadCall(this);
         }
         }

+ 1 - 1
okhttplib/src/main/java/com/benyanyi/okhttp/download/DownloadConfig.java

@@ -12,7 +12,7 @@ public interface DownloadConfig {
 
 
     void start(OnDownLoadObserver onDownLoadObserver);
     void start(OnDownLoadObserver onDownLoadObserver);
 
 
-    void start(String suffix, OnDownLoadObserver onDownLoadObserver);
+    void pause();
 
 
     void cancel();
     void cancel();
 
 

+ 141 - 36
okhttplib/src/main/java/com/benyanyi/okhttp/download/DownloadManager.java

@@ -2,7 +2,6 @@ package com.benyanyi.okhttp.download;
 
 
 import android.content.Context;
 import android.content.Context;
 
 
-
 import com.benyanyi.okhttp.listener.OnDownLoadObserver;
 import com.benyanyi.okhttp.listener.OnDownLoadObserver;
 
 
 import java.io.File;
 import java.io.File;
@@ -37,6 +36,7 @@ class DownloadManager {
      * 用来存放各个下载的请求
      * 用来存放各个下载的请求
      */
      */
     private HashMap<String, Call> downCalls;
     private HashMap<String, Call> downCalls;
+    private HashMap<String, DownloadInfo> downInfos;
     /**
     /**
      * OKHttpClient;
      * OKHttpClient;
      */
      */
@@ -66,6 +66,7 @@ class DownloadManager {
 
 
     private DownloadManager(Context mContext) {
     private DownloadManager(Context mContext) {
         downCalls = new HashMap<>();
         downCalls = new HashMap<>();
+        downInfos = new HashMap<>();
         mClient = new OkHttpClient.Builder().build();
         mClient = new OkHttpClient.Builder().build();
         this.mContext = mContext;
         this.mContext = mContext;
     }
     }
@@ -89,44 +90,95 @@ class DownloadManager {
      * @param onDownLoadObserver 用来回调的接口
      * @param onDownLoadObserver 用来回调的接口
      */
      */
     void download(String url, OnDownLoadObserver onDownLoadObserver) {
     void download(String url, OnDownLoadObserver onDownLoadObserver) {
-        Observable.just(url)
-                //call的map已经有了,就证明正在下载,则这次不下载
-                .filter(new Predicate<String>() {
-                    @Override
-                    public boolean test(String s) throws Exception {
-                        return !downCalls.containsKey(s);
-                    }
-                })
-                .flatMap(new Function<String, ObservableSource<?>>() {
-                    @Override
-                    public ObservableSource<?> apply(String s) throws Exception {
-                        return Observable.just(createDownInfo(s));
-                    }
-                })
-                //检测本地文件夹,生成新的文件名
-                .map(new Function<Object, DownloadInfo>() {
-                    @Override
-                    public DownloadInfo apply(Object o) throws Exception {
-                        return getRealFileName((DownloadInfo) o);
-                    }
-                })
-                //下载
-                .flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() {
-                    @Override
-                    public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) throws Exception {
-                        return Observable.create(new DownloadSubscribe(downloadInfo));
-                    }
-                })
-                //在主线程回调
-                .observeOn(AndroidSchedulers.mainThread())
-                //在子线程执行
-                .subscribeOn(Schedulers.io())
-                //添加观察者
-                .subscribe(onDownLoadObserver);
+        if (!downCalls.containsKey(url)) {
+            Observable.just(url)
+                    //call的map已经有了,就证明正在下载,则这次不下载
+                    .filter(new Predicate<String>() {
+                        @Override
+                        public boolean test(String s) throws Exception {
+                            return !downCalls.containsKey(s);
+                        }
+                    })
+                    .flatMap(new Function<String, ObservableSource<?>>() {
+                        @Override
+                        public ObservableSource<?> apply(String s) throws Exception {
+                            return Observable.just(createDownInfo(s));
+                        }
+                    })
+                    //检测本地文件夹,生成新的文件名
+                    .map(new Function<Object, DownloadInfo>() {
+                        @Override
+                        public DownloadInfo apply(Object o) throws Exception {
+                            return getRealFileName((DownloadInfo) o);
+                        }
+                    })
+                    //下载
+                    .flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() {
+                        @Override
+                        public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) throws Exception {
+                            return Observable.create(new DownloadSubscribe(downloadInfo));
+                        }
+                    })
+                    //在主线程回调
+                    .observeOn(AndroidSchedulers.mainThread())
+                    //在子线程执行
+                    .subscribeOn(Schedulers.io())
+                    //添加观察者
+                    .subscribe(onDownLoadObserver);
+        } else {
+//            Call call = downCalls.get(url);
+//            if (call != null) {
+//                call.cancel();
+//            }
+            Observable.just(url)
+                    .flatMap(new Function<String, ObservableSource<DownloadInfo>>() {
+                        @Override
+                        public ObservableSource<DownloadInfo> apply(String s) throws Exception {
+                            return Observable.create(new DownloadingSubscribe(s));
+                        }
+                    })
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(onDownLoadObserver);
+        }
+    }
 
 
+    /**
+     * 暂停
+     *
+     * @param url
+     */
+    void pause(String url) {
+        remove(url);
+        downInfos.remove(url);
     }
     }
 
 
+    /**
+     * 取消
+     *
+     * @param url
+     */
     void cancel(String url) {
     void cancel(String url) {
+        remove(url);
+        SecurityManager checker = new SecurityManager();
+        DownloadInfo downloadInfo = downInfos.get(url);
+        if (downloadInfo != null && downloadInfo.getFile() != null) {
+            File file = downloadInfo.getFile();
+            if (file.exists()) {
+                checker.checkDelete(file.toString());
+                if (file.isFile()) {
+                    try {
+                        file.delete();
+                    } catch (SecurityException se) {
+                        se.printStackTrace();
+                    }
+                }
+            }
+        }
+        downInfos.remove(url);
+    }
+
+    private void remove(String url) {
         Call call = downCalls.get(url);
         Call call = downCalls.get(url);
         if (call != null) {
         if (call != null) {
             call.cancel();//取消
             call.cancel();//取消
@@ -170,7 +222,7 @@ class DownloadManager {
                 fileNameOther = fileName.substring(0, dotIndex)
                 fileNameOther = fileName.substring(0, dotIndex)
                         + "(" + i + ")" + fileName.substring(dotIndex);
                         + "(" + i + ")" + fileName.substring(dotIndex);
             }
             }
-            File newFile = new File(savePath, fileNameOther + suffix);
+            File newFile = new File(savePath, fileNameOther);
             file = newFile;
             file = newFile;
             downloadLength = newFile.length();
             downloadLength = newFile.length();
             i++;
             i++;
@@ -207,6 +259,7 @@ class DownloadManager {
             Call call = mClient.newCall(request);
             Call call = mClient.newCall(request);
             //把这个添加到call里,方便取消
             //把这个添加到call里,方便取消
             downCalls.put(url, call);
             downCalls.put(url, call);
+            downInfos.put(url, downloadInfo);
             Response response = call.execute();
             Response response = call.execute();
             String savePath = FileUtil.isExistDir(mContext.getPackageName());
             String savePath = FileUtil.isExistDir(mContext.getPackageName());
             File file = new File(savePath, downloadInfo.getFileName());
             File file = new File(savePath, downloadInfo.getFileName());
@@ -222,6 +275,7 @@ class DownloadManager {
                     fileOutputStream.write(buffer, 0, len);
                     fileOutputStream.write(buffer, 0, len);
                     downloadLength += len;
                     downloadLength += len;
                     downloadInfo.setProgress(downloadLength);
                     downloadInfo.setProgress(downloadLength);
+                    downInfos.put(url, downloadInfo);
                     e.onNext(downloadInfo);
                     e.onNext(downloadInfo);
                 }
                 }
                 downloadInfo.setFile(file);
                 downloadInfo.setFile(file);
@@ -235,6 +289,57 @@ class DownloadManager {
         }
         }
     }
     }
 
 
+    private class DownloadingSubscribe implements ObservableOnSubscribe<DownloadInfo> {
+
+        private String url;
+
+        DownloadingSubscribe(String url) {
+            this.url = url;
+        }
+
+        @Override
+        public void subscribe(ObservableEmitter<DownloadInfo> e) throws Exception {
+            DownloadInfo downloadInfo = downInfos.get(url);
+            //已经下载好的长度
+            long downloadLength = downloadInfo.getProgress();
+            //初始进度信息
+            e.onNext(downloadInfo);
+
+            //把这个添加到call里,方便取消
+            Call call = downCalls.get(url);
+            if (call != null) {
+                Response response = call.execute();
+                String savePath = FileUtil.isExistDir(mContext.getPackageName());
+                File file = new File(savePath, downloadInfo.getFileName());
+                InputStream is = null;
+                FileOutputStream fileOutputStream = null;
+                try {
+                    is = response.body().byteStream();
+                    fileOutputStream = new FileOutputStream(file, true);
+                    //缓冲数组2kB
+                    byte[] buffer = new byte[2048];
+                    int len;
+                    while ((len = is.read(buffer)) != -1) {
+                        fileOutputStream.write(buffer, 0, len);
+                        downloadLength += len;
+                        downloadInfo.setProgress(downloadLength);
+                        downInfos.put(url, downloadInfo);
+                        e.onNext(downloadInfo);
+                    }
+                    downloadInfo.setFile(file);
+                    fileOutputStream.flush();
+                    downCalls.remove(url);
+                } finally {
+                    //关闭IO流
+                    IoUtil.closeAll(is, fileOutputStream);
+                }
+            } else {
+                e.onError(new Throwable("下载失败"));
+            }
+            e.onComplete();//完成
+        }
+    }
+
     /**
     /**
      * 获取下载长度
      * 获取下载长度
      *
      *

+ 5 - 0
okhttplib/src/main/java/com/benyanyi/okhttp/type/HttpRequest.java

@@ -158,6 +158,11 @@ public class HttpRequest implements RequestType {
         return new DownloadCall.Builder().setContext(context).setUrl(url).builder();
         return new DownloadCall.Builder().setContext(context).setUrl(url).builder();
     }
     }
 
 
+    @Override
+    public DownloadConfig download(String suffix) {
+        return new DownloadCall.Builder().setContext(context).setUrl(url).setSuffix(suffix).builder();
+    }
+
     private RequestConfig send() {
     private RequestConfig send() {
         return new HttpCall.Builder()
         return new HttpCall.Builder()
                 .setCache(isCache)
                 .setCache(isCache)

+ 2 - 0
okhttplib/src/main/java/com/benyanyi/okhttp/type/RequestType.java

@@ -27,4 +27,6 @@ public interface RequestType {
 
 
     DownloadConfig download();
     DownloadConfig download();
 
 
+    DownloadConfig download(String suffix);
+
 }
 }