Browse Source

优化文件导出流程

zk 1 year ago
parent
commit
009264d201

+ 117 - 77
app/src/main/java/com/datarecovery/master/module/filerecover/FileRecoverViewModel.java

@@ -18,21 +18,27 @@ import com.datarecovery.master.sdk.bugly.BuglyHelper;
 import com.datarecovery.master.utils.BoxingUtil;
 import com.datarecovery.master.utils.FileUtil;
 import com.datarecovery.master.utils.FilesSearch;
+import com.datarecovery.master.utils.ImageDeepDetector;
 import com.datarecovery.master.utils.Maps;
 import com.datarecovery.master.utils.MediaStoreHelper;
 import com.datarecovery.master.utils.ReportUtil;
+import com.datarecovery.master.utils.ReverseArrayList;
 import com.datarecovery.master.utils.ToastUtil;
 
 import org.reactivestreams.Subscriber;
 import org.reactivestreams.Subscription;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 
 import atmob.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import atmob.reactivex.rxjava3.annotations.NonNull;
+import atmob.reactivex.rxjava3.core.Single;
+import atmob.reactivex.rxjava3.core.SingleObserver;
 import atmob.reactivex.rxjava3.disposables.Disposable;
 import atmob.rxjava.utils.RxJavaUtil;
 import dagger.hilt.android.lifecycle.HiltViewModel;
@@ -48,11 +54,18 @@ public class FileRecoverViewModel extends BaseViewModel {
     private final int[] tabTitle = {R.string.word, R.string.excel, R.string.ppt, R.string.pdf};
 
     private final List<MutableLiveData<Boolean>> checkList = new ArrayList<>();
-    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedWordList = new MutableLiveData<>(new ArrayList<>());
-    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedExcelList = new MutableLiveData<>(new ArrayList<>());
-    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPPTList = new MutableLiveData<>(new ArrayList<>());
-    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPDFList = new MutableLiveData<>(new ArrayList<>());
-    private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>(new ArrayList<>());
+    private final List<FilesSearch.DocumentFile> wordList = new ReverseArrayList<>();
+    private final List<FilesSearch.DocumentFile> excelList = new ReverseArrayList<>();
+    private final List<FilesSearch.DocumentFile> pptList = new ReverseArrayList<>();
+    private final List<FilesSearch.DocumentFile> pdfList = new ReverseArrayList<>();
+    private final List<FilesSearch.DocumentFile> selectList = new ArrayList<>();
+
+
+    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedWordList = new MutableLiveData<>();
+    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedExcelList = new MutableLiveData<>();
+    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPPTList = new MutableLiveData<>();
+    private final MutableLiveData<List<FilesSearch.DocumentFile>> detectedPDFList = new MutableLiveData<>();
+    private final MutableLiveData<List<FilesSearch.DocumentFile>> selectedList = new MutableLiveData<>();
 
     private final SingleLiveEvent<?> scrollTop = new SingleLiveEvent<>();
     private final MutableLiveData<Boolean> showTrialView = new MutableLiveData<>();
@@ -167,6 +180,11 @@ public class FileRecoverViewModel extends BaseViewModel {
                         scanDisposable = Disposable.fromSubscription(s);
                         addDisposable(scanDisposable);
                         showScanDialogEvent.setValue(true);
+                        wordList.clear();
+                        excelList.clear();
+                        pptList.clear();
+                        pdfList.clear();
+                        selectList.clear();
                     }
 
                     @Override
@@ -174,24 +192,37 @@ public class FileRecoverViewModel extends BaseViewModel {
                         if (documentFiles == null || documentFiles.isEmpty()) {
                             return;
                         }
-                        MutableLiveData<List<FilesSearch.DocumentFile>> liveData = null;
+                        int wordCount = 0;
+                        int excelCount = 0;
+                        int pptCount = 0;
+                        int pdfCount = 0;
                         for (FilesSearch.DocumentFile item : documentFiles) {
+                            detectedLastFileName.setValue(item.getName());
                             if (item.getCategory() == FilesSearch.DocumentFile.WORD) {
-                                liveData = detectedWordList;
+                                wordCount++;
+                                wordList.add(item);
                             } else if (item.getCategory() == FilesSearch.DocumentFile.EXCEL) {
-                                liveData = detectedExcelList;
+                                excelCount++;
+                                excelList.add(item);
                             } else if (item.getCategory() == FilesSearch.DocumentFile.PPT) {
-                                liveData = detectedPPTList;
+                                pptCount++;
+                                pptList.add(item);
                             } else if (item.getCategory() == FilesSearch.DocumentFile.PDF) {
-                                liveData = detectedPDFList;
-                            }
-                            if (liveData == null) {
-                                continue;
+                                pdfCount++;
+                                pdfList.add(item);
                             }
-                            detectedLastFileName.setValue(item.getName());
-                            List<FilesSearch.DocumentFile> list = getList(liveData);
-                            list.add(0, item);
-                            liveData.setValue(list);
+                        }
+                        if (wordCount > 0) {
+                            detectedWordList.setValue(wordList);
+                        }
+                        if (excelCount > 0) {
+                            detectedExcelList.setValue(excelList);
+                        }
+                        if (pptCount > 0) {
+                            detectedPPTList.setValue(pptList);
+                        }
+                        if (pdfCount > 0) {
+                            detectedPDFList.setValue(pdfList);
                         }
                         scrollTop.call();
                     }
@@ -219,67 +250,49 @@ public class FileRecoverViewModel extends BaseViewModel {
     private void setFreeExport() {
         if (isTrial) {
             showTrialView.setValue(true);
-            List<FilesSearch.DocumentFile> list = getList(detectedWordList);
-            if (!list.isEmpty()) {
-                list.get(0).setTrial(true);
+            if (!wordList.isEmpty()) {
+                wordList.get(0).setTrial(true);
             }
-            list = getList(detectedExcelList);
-            if (!list.isEmpty()) {
-                list.get(0).setTrial(true);
+            if (!excelList.isEmpty()) {
+                excelList.get(0).setTrial(true);
             }
-            list = getList(detectedPPTList);
-            if (!list.isEmpty()) {
-                list.get(0).setTrial(true);
+            if (!pptList.isEmpty()) {
+                pptList.get(0).setTrial(true);
             }
-            list = getList(detectedPDFList);
-            if (!list.isEmpty()) {
-                list.get(0).setTrial(true);
+            if (!pdfList.isEmpty()) {
+                pdfList.get(0).setTrial(true);
             }
         }
     }
 
-
-    private List<FilesSearch.DocumentFile> getList(LiveData<List<FilesSearch.DocumentFile>> liveData) {
-        List<FilesSearch.DocumentFile> selectList = liveData.getValue();
-        if (selectList == null) {
-            selectList = new ArrayList<>();
-        }
-        return selectList;
-    }
-
     public void onCheckAllClick(boolean isCheck) {
         int index = BoxingUtil.boxing(checkPosition.getValue());
         getCheckAll(index).setValue(isCheck);
         int id = tabTitle[index];
-        MutableLiveData<List<FilesSearch.DocumentFile>> liveData = null;
+        List<FilesSearch.DocumentFile> list = null;
         if (id == R.string.word) {
-            liveData = detectedWordList;
+            list = wordList;
         } else if (id == R.string.excel) {
-            liveData = detectedExcelList;
+            list = excelList;
         } else if (id == R.string.ppt) {
-            liveData = detectedPPTList;
+            list = pptList;
         } else if (id == R.string.pdf) {
-            liveData = detectedPDFList;
-        }
-        if (liveData == null) {
-            return;
+            list = pdfList;
         }
-        List<FilesSearch.DocumentFile> list = getList(liveData);
-        if (list.isEmpty()) {
+        if (list == null || list.isEmpty()) {
             return;
         }
-        List<FilesSearch.DocumentFile> selectedList = getList(this.selectedList);
         for (FilesSearch.DocumentFile item : list) {
             if (item.isCheck() != isCheck) {
                 if (isCheck) {
-                    selectedList.add(item);
+                    selectList.add(item);
                 } else {
-                    selectedList.remove(item);
+                    selectList.remove(item);
                 }
             }
             item.setCheck(isCheck);
         }
-        this.selectedList.setValue(selectedList);
+        this.selectedList.setValue(selectList);
     }
 
     public MutableLiveData<Boolean> getCheckAll(int position) {
@@ -288,12 +301,11 @@ public class FileRecoverViewModel extends BaseViewModel {
 
 
     public void onExportClick() {
-        List<FilesSearch.DocumentFile> list = selectedList.getValue();
-        if (list == null || list.isEmpty()) {
+        if (selectList == null || selectList.isEmpty()) {
             return;
         }
         if (isTrial) {
-            for (FilesSearch.DocumentFile file : list) {
+            for (FilesSearch.DocumentFile file : selectList) {
                 if (!file.isTrial()) {
                     showTrialExportFailDialog.call();
                     return;
@@ -304,24 +316,53 @@ public class FileRecoverViewModel extends BaseViewModel {
                 return;
             }
         }
-        showLoadingEvent.setValue(true);
-        RxJavaUtil.doInBackground(() -> {
-            for (FilesSearch.DocumentFile item : list) {
-                MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_FILES, item.getName()));
-                item.setCheck(false);
-            }
-            return true;
-        }, o -> {
-            getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).setValue(false);
-            showLoadingEvent.setValue(false);
-            ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
-            list.clear();
-            selectedList.setValue(list);
-        }, throwable -> {
-            showLoadingEvent.setValue(false);
-            ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
-            BuglyHelper.postCatchedException(new Exception("文件导出:", throwable));
-        });
+        Single.just(selectList.size())
+                .map(oldSize -> {
+                    Iterator<FilesSearch.DocumentFile> iterator = selectList.iterator();
+                    int errorCount = 0;
+                    Exception exception = null;
+                    while (iterator.hasNext()) {
+                        FilesSearch.DocumentFile item = iterator.next();
+                        try {
+                            MediaStoreHelper.saveToSharedStorage(MediaStoreHelper.TYPE_FILES, item.newInputStream(), FileUtil.getCreateFileName(MediaStoreHelper.TYPE_FILES, item.getName()));
+                            item.setCheck(false);
+                            iterator.remove();
+                        } catch (Exception throwable) {
+                            errorCount++;
+                            exception = throwable;
+                            BuglyHelper.postCatchedException(new Exception("文件导出:", throwable));
+                        }
+                    }
+                    if (errorCount == oldSize) {
+                        throw new Exception("导出失败" + (exception == null ? "" : ":" + exception.getMessage()));
+                    } else if (errorCount > 0) {
+                        throw new Exception("部分导出失败" + ":" + exception.getMessage());
+                    }
+                    return errorCount;
+                })
+                .compose(RxJavaUtil.SingleSchedule.io2Main())
+                .subscribe(new SingleObserver<Integer>() {
+                    @Override
+                    public void onSubscribe(@NonNull Disposable d) {
+                        showLoadingEvent.setValue(true);
+                        addDisposable(d);
+                    }
+
+                    @Override
+                    public void onSuccess(@NonNull Integer integer) {
+                        showLoadingEvent.setValue(false);
+                        selectedList.setValue(selectList);
+                        ToastUtil.show(R.string.export_success, ToastUtil.LENGTH_SHORT);
+                        getCheckAll(BoxingUtil.boxing(checkPosition.getValue())).setValue(false);
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable throwable) {
+                        showLoadingEvent.setValue(false);
+                        selectedList.setValue(selectList);
+                        ToastUtil.show(throwable.getMessage(), ToastUtil.LENGTH_SHORT);
+                    }
+                });
     }
 
     public void itemClick(FilesSearch.DocumentFile documentFile) {
@@ -329,13 +370,12 @@ public class FileRecoverViewModel extends BaseViewModel {
             return;
         }
         documentFile.setCheck(!documentFile.isCheck());
-        List<FilesSearch.DocumentFile> list = getList(selectedList);
         if (documentFile.isCheck()) {
-            list.add(documentFile);
+            selectList.add(documentFile);
         } else {
-            list.remove(documentFile);
+            selectList.remove(documentFile);
         }
-        this.selectedList.setValue(list);
+        this.selectedList.setValue(selectList);
     }
 
     @Override

+ 5 - 0
app/src/main/java/com/datarecovery/master/module/filerecover/fragment/FileRecoverAdapter.java

@@ -9,6 +9,7 @@ import androidx.lifecycle.LifecycleOwner;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.datarecovery.master.databinding.ItemDataFileBinding;
+import com.datarecovery.master.sdk.bugly.BuglyHelper;
 import com.datarecovery.master.utils.FileUtil;
 import com.datarecovery.master.utils.FilesSearch;
 
@@ -63,6 +64,10 @@ public class FileRecoverAdapter extends RecyclerView.Adapter<FileRecoverAdapter.
 
     @Override
     public void onBindViewHolder(@NonNull FileRecoverAdapter.ViewHolder holder, int position) {
+        if (position < 0 || position >= list.size()) {
+            BuglyHelper.postCatchedException(new IndexOutOfBoundsException("文件列表onBindViewHolder出现数组越界:" + position + ",size:" + list.size()));
+            return;
+        }
         holder.bind(list.get(position));
     }
 

+ 0 - 1
app/src/main/java/com/datarecovery/master/module/imgrecover/ImageItemAdapter.java

@@ -49,7 +49,6 @@ public class ImageItemAdapter extends RecyclerView.Adapter<ImageItemAdapter.View
             BuglyHelper.postCatchedException(new IndexOutOfBoundsException("图片列表onBindViewHolder出现数组越界:type:" + type + "," + position + ",size:" + list.size()));
             return;
         }
-//        AtmobLog.d("zk", "position: " + position + ",index:" + list.indexOf(list.get(position)) + ",size:" + list.size());
         holder.bind(list.get(position));
     }
 

+ 1 - 2
app/src/main/java/com/datarecovery/master/module/imgrecover/ImageRecoverViewModel.java

@@ -299,6 +299,7 @@ public class ImageRecoverViewModel extends BaseViewModel {
                         int qqCount = 0;
                         int otherCount = 0;
                         for (ImageDeepDetector.ImageFile imageFile : imageFiles) {
+                            detectedLastFileName.setValue(imageFile.getName());
                             if (imageFile.getCategory() == ImageDeepDetector.ImageFile.CATEGORY_GALLERY) {
                                 detectedPhotoList.add(imageFile);
                                 photoCount++;
@@ -312,7 +313,6 @@ public class ImageRecoverViewModel extends BaseViewModel {
                                 detectedOtherList.add(imageFile);
                                 otherCount++;
                             }
-                            detectedLastFileName.setValue(imageFile.getName());
                         }
                         if (photoCount > 0) {
                             detectedPhotoImg.setValue(detectedPhotoList);
@@ -619,7 +619,6 @@ public class ImageRecoverViewModel extends BaseViewModel {
                 .map(oldSize -> {
                     Iterator<ImageDeepDetector.ImageFile> iterator = selectList.iterator();
                     int errorCount = 0;
-                    int test = 0;
                     Exception exception = null;
                     while (iterator.hasNext()) {
                         ImageDeepDetector.ImageFile item = iterator.next();