Pārlūkot izejas kodu

优化语音文件偏大时超时导致重复下载的问题

zk 1 gadu atpakaļ
vecāks
revīzija
fc063ac98d

+ 1 - 1
app/src/main/java/com/atmob/voiceai/data/repositories/VoiceAIRepository.java

@@ -196,7 +196,7 @@ public class VoiceAIRepository {
                         throw new Exception("cloneVoice is null");
                     }
                     return VoiceFileUtil.getVoiceFile(okHttpClient, userVoice.getVoiceUrl())
-                            .timeout(20, TimeUnit.SECONDS)
+                            .timeout(2, TimeUnit.SECONDS)
                             .map(file -> userVoice)
                             .onErrorReturn(throwable -> userVoice);
                 })

+ 4 - 2
app/src/main/java/com/atmob/voiceai/module/result/VoiceResultActivity.java

@@ -36,6 +36,7 @@ import dagger.hilt.android.AndroidEntryPoint;
 @AndroidEntryPoint
 public class VoiceResultActivity extends BaseActivity<ActivityVoiceResultBinding> {
 
+    private final String TAG = VoiceResultActivity.class.getSimpleName();
 
     private static final String USER_VOICE_BEAN = "user_voice_bean";
     private VoiceResultViewModel voiceResultViewModel;
@@ -166,7 +167,7 @@ public class VoiceResultActivity extends BaseActivity<ActivityVoiceResultBinding
 
             @Override
             public void onPlayerError(PlaybackException error) {
-                AtmobLog.d("zk", "onPlayerError: " + error.getMessage());
+                AtmobLog.d(TAG, "onPlayerError: " + error.getMessage());
                 ToastUtil.show(R.string.voice_play_error, ToastUtil.LENGTH_SHORT);
                 setVoicePlayEnd();
             }
@@ -185,7 +186,7 @@ public class VoiceResultActivity extends BaseActivity<ActivityVoiceResultBinding
 
             @Override
             public void onPlaybackStateChanged(int state) {
-                AtmobLog.d("zk", "onPlaybackStateChanged: " + state);
+                AtmobLog.d(TAG, "onPlaybackStateChanged: " + state);
                 if (Player.STATE_ENDED == state) {
                     setVoicePlayEnd();
                 }
@@ -222,6 +223,7 @@ public class VoiceResultActivity extends BaseActivity<ActivityVoiceResultBinding
             if (uri == null) {
                 return;
             }
+            AtmobLog.d(TAG, "voiceUri: " + uri);
             MediaItem mediaItem = MediaItem.fromUri(uri);
             player.setMediaItem(mediaItem);
             player.prepare();

+ 4 - 0
app/src/main/java/com/atmob/voiceai/module/result/VoiceResultViewModel.java

@@ -49,6 +49,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
 @HiltViewModel
 public class VoiceResultViewModel extends BaseViewModel {
 
+    private final String TAG = VoiceResultViewModel.class.getSimpleName();
 
     private final VoiceAIRepository voiceAIRepository;
     private final MutableLiveData<Boolean> isPlay = new MutableLiveData<>();
@@ -273,15 +274,18 @@ public class VoiceResultViewModel extends BaseViewModel {
                     @Override
                     public void onSubscribe(@NonNull Disposable d) {
                         addDisposable(d);
+                        AtmobLog.d(TAG, "startDownloadVoice onSubscribe: voiceUrl:" + voiceUrl);
                     }
 
                     @Override
                     public void onSuccess(@NonNull File file) {
+                        AtmobLog.d(TAG, "startDownloadVoice onSuccess: " + file.getPath());
                         voiceUri.setValue(Uri.fromFile(file));
                     }
 
                     @Override
                     public void onError(@NonNull Throwable e) {
+                        AtmobLog.d(TAG, "startDownloadVoice onError: " + e.getMessage());
                         voiceUri.setValue(Uri.parse(voiceUrl));
                     }
                 });

+ 40 - 4
app/src/main/java/com/atmob/voiceai/utils/DownloadUtils.java

@@ -1,5 +1,7 @@
 package com.atmob.voiceai.utils;
 
+import android.os.CancellationSignal;
+
 import java.io.File;
 import java.io.IOException;
 
@@ -7,8 +9,11 @@ import atmob.okhttp3.OkHttpClient;
 import atmob.okhttp3.Request;
 import atmob.okhttp3.Response;
 import atmob.okhttp3.ResponseBody;
+import atmob.reactivex.rxjava3.annotations.NonNull;
 import atmob.reactivex.rxjava3.core.Observable;
 import atmob.reactivex.rxjava3.core.ObservableOnSubscribe;
+import atmob.reactivex.rxjava3.core.Observer;
+import atmob.reactivex.rxjava3.disposables.Disposable;
 import atmob.reactivex.rxjava3.schedulers.Schedulers;
 
 public class DownloadUtils {
@@ -22,8 +27,9 @@ public class DownloadUtils {
     }
 
 
-    public static void downLoad(OkHttpClient client, String url, final String filePath, final String fileName,
-                                final FileDownLoadObserver<File> fileDownLoadObserver) {
+    public static CancellationSignal downLoad(OkHttpClient client, String url, final String filePath, final String fileName,
+                                              final FileDownLoadObserver<File> fileDownLoadObserver) {
+        CancellationSignal cancellationSignal = new CancellationSignal();
         Observable.create((ObservableOnSubscribe<ResponseBody>) emitter -> {
                     Request request = new Request.Builder()
                             .url(url)
@@ -45,7 +51,7 @@ public class DownloadUtils {
                         emitter.onError(e);
                     }
                 })
-                .map(responseBody -> fileDownLoadObserver.saveFile(responseBody,
+                .map(responseBody -> fileDownLoadObserver.saveFile(cancellationSignal, responseBody,
                         filePath, fileName))
                 .subscribeOn(Schedulers.io())
                 .observeOn(Schedulers.io())
@@ -55,7 +61,37 @@ public class DownloadUtils {
                     }
                     return file;
                 })
-                .subscribe(fileDownLoadObserver);
+                .subscribe(new Observer<File>() {
+                    @Override
+                    public void onSubscribe(@NonNull Disposable d) {
+                        if (cancellationSignal.isCanceled()) {
+                            return;
+                        }
+                        fileDownLoadObserver.onDownLoadStart();
+                    }
+
+                    @Override
+                    public void onNext(@NonNull File file) {
+                        if (cancellationSignal.isCanceled()) {
+                            return;
+                        }
+                        fileDownLoadObserver.onDownLoadSuccess(file);
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable e) {
+                        if (cancellationSignal.isCanceled()) {
+                            return;
+                        }
+                        fileDownLoadObserver.onDownLoadFail(e);
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                });
+        return cancellationSignal;
     }
 
 

+ 16 - 29
app/src/main/java/com/atmob/voiceai/utils/FileDownLoadObserver.java

@@ -1,7 +1,12 @@
 package com.atmob.voiceai.utils;
 
+import android.os.CancellationSignal;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
+import com.atmob.common.logging.AtmobLog;
+
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -11,9 +16,10 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import atmob.okhttp3.ResponseBody;
-import atmob.reactivex.rxjava3.observers.DefaultObserver;
 
-public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {
+public abstract class FileDownLoadObserver<T> {
+
+    private static final String TAG = FileDownLoadObserver.class.getSimpleName();
 
     public abstract void onDownLoadStart();
 
@@ -24,38 +30,19 @@ public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {
     public abstract void onDownLoadFail(Throwable throwable);
 
 
-    @Override
-    protected void onStart() {
-        super.onStart();
-        onDownLoadStart();
-    }
-
-    @Override
-    public void onNext(T t) {
-        onDownLoadSuccess(t);
-    }
-
-    @Override
-    public void onError(Throwable e) {
-        onDownLoadFail(e);
-    }
-
-    @Override
-    public void onComplete() {
-
-    }
-
-    private void copyStream(InputStream is, OutputStream os) throws IOException {
+    private void copyStream(InputStream is, OutputStream os, @NonNull CancellationSignal cancellationSignal) throws IOException {
         byte[] buf = new byte[2048];
         int n;
-        while ((n = is.read(buf)) > 0) {
+        while ((n = is.read(buf)) > 0 && !cancellationSignal.isCanceled()) {
             os.write(buf, 0, n);
         }
         os.flush();
     }
 
 
-    public File saveFile(ResponseBody responseBody, String destFileDir, String destFileName) {
+    public File saveFile(@NonNull CancellationSignal cancellationSignal, ResponseBody responseBody, String destFileDir, String destFileName) {
+        AtmobLog.d(TAG, "start save file : fileDir = " + destFileDir + " , fileName = " + destFileName);
+
         File file = null;
         File dir = new File(destFileDir);
 
@@ -71,13 +58,13 @@ public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {
                     FileOutputStream fos = new FileOutputStream(file);
                     OutputStream os = new BufferedOutputStream(fos);
             ) {
-                copyStream(is, os);
+                copyStream(is, os, cancellationSignal);
             }
 
         } catch (IOException e) {
-            Log.d("FileDownLoadObserver", "saveFile: " + e.getMessage());
+            Log.d(TAG, "saveFile error: " + e.getMessage());
         }
-
+        AtmobLog.d(TAG, "start save file over,file:" + file.getPath());
         return file;
     }
 }

+ 19 - 3
app/src/main/java/com/atmob/voiceai/utils/VoiceFileUtil.java

@@ -2,20 +2,26 @@ package com.atmob.voiceai.utils;
 
 
 import android.net.Uri;
+import android.os.CancellationSignal;
 
 import androidx.annotation.NonNull;
 
 
+import com.atmob.common.logging.AtmobLog;
+
 import java.io.File;
 
 import atmob.okhttp3.OkHttpClient;
 import atmob.reactivex.rxjava3.core.Single;
 import atmob.reactivex.rxjava3.core.SingleOnSubscribe;
+import atmob.reactivex.rxjava3.functions.Cancellable;
 import atmob.rxjava.utils.RxJavaUtil;
 
 public class VoiceFileUtil {
 
 
+    private static final String TAG = VoiceFileUtil.class.getSimpleName();
+
     /**
      * 先判断本地是否有,没有再下载,然后返回
      *
@@ -29,7 +35,9 @@ public class VoiceFileUtil {
                         emitter.onSuccess(localFile);
                     } else {
                         String fileName = getFileName(url);
-                        DownloadUtils.downLoad(okHttpClient, url, DownloadUtils.voiceFile.getPath(), fileName, new FileDownLoadObserver<File>() {
+                        CancellationSignal cancellationSignal = DownloadUtils.downLoad(okHttpClient, url, DownloadUtils.voiceFile.getPath(), fileName, new FileDownLoadObserver<File>() {
+
+
                             @Override
                             public void onDownLoadStart() {
 
@@ -37,16 +45,24 @@ public class VoiceFileUtil {
 
                             @Override
                             public void onDownLoadSuccess(File file) {
-                                emitter.onSuccess(FileUtils.rename(file, DownloadUtils.FILE_PREFIX + fileName));
+                                File renameFile = FileUtils.rename(file, DownloadUtils.FILE_PREFIX + fileName);
+                                AtmobLog.d(TAG, "onDownLoadSuccess old: path:" + file.getAbsolutePath());
+                                AtmobLog.d(TAG, "onDownLoadSuccess new: path:" + renameFile.getAbsolutePath());
+                                emitter.onSuccess(renameFile);
                             }
 
                             @Override
                             public void onDownLoadFail(Throwable throwable) {
+                                AtmobLog.d(TAG, "onDownLoadFail: " + throwable.getMessage());
                                 emitter.onError(throwable);
                             }
-
+                        });
+                        emitter.setCancellable(() -> {
+                            cancellationSignal.cancel();
+                            AtmobLog.d(TAG, "download cancel");
                         });
                     }
+
                 })
                 .compose(RxJavaUtil.SingleSchedule.io2Main());
     }