rx代替AsyncTask

本文介绍了一个使用RxJava和AndroidSchedulers实现的发票信息加载工具类。该工具类通过数据库查询当前用户的发票信息,并返回一个Observable对象,方便在UI线程中订阅并更新视图。

rx1.2.1

public class InvoiceUtils {
    public static Observable<Invoice> getLocalInvoice(final Context context) {
        return Observable.create(new Observable.OnSubscribe<Invoice>() {
            @Override
            public void call(Subscriber<? super Invoice> subscriber) {
                subscriber.onNext(getInvoice(context));
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    private static Invoice getInvoice(Context context) {
        Cursor cursor = DbHelper.getInstance(context).query(TInvoice.TNAME, " where " + TInvoice.ACCOUNT + "='" + UserInfoKeeper.getCurrentUser().getAccount() + "'");
        if (cursor.getCount() == 0) {
            return null;
        }

        cursor.moveToNext();

        Invoice invoice = new Invoice();
        invoice.setInvoiceTitle(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICETITLE)));
        invoice.setInvoiceBandAccount(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICEBANDACCOUNT)));
        invoice.setInvoiceFlag(cursor.getInt(cursor.getColumnIndex(TInvoice.INVOICEFLAG)));
        invoice.setInvoiceBandName(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICEBANDNAME)));
        invoice.setInvoiceToAddress(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICETOADDRESS)));
        invoice.setInvoiceToTel(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICETOTEL)));
        invoice.setInvoiceToContact(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICETOCONTACT)));
        invoice.setInvoiceFromAddress(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICEFROMADDRESS)));
        invoice.setInvoiceFromTel(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICEFROMTEL)));
        invoice.setInvoiceType(cursor.getInt(cursor.getColumnIndex(TInvoice.INVOICETYPE)));
        invoice.setInvoiceIdentifyId(cursor.getString(cursor.getColumnIndex(TInvoice.INVOICEIDENTIFYID)));

        cursor.close();

        return invoice;
    }


}

要使用的地方:

InvoiceUtils.getLocalInvoice(this).subscribe(new Subscriber<Invoice>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Invoice invoice) {
                if (invoice != null) {
                    if (!TextUtils.isEmpty(invoice.getInvoiceTitle())) {
                        if (invoice != null) {
                            setViews(invoice);
                        } else {
                            // 本地为空,去网络获取,存于本地
                            presenter.getInvoiceInfo();
                        }
                    }
                }
            }
        });
private class RxUpdateManager { private CompositeDisposable disposables = new CompositeDisposable(); private PublishSubject<String> progressSubject = PublishSubject.create(); private PublishSubject<Integer> resultSubject = PublishSubject.create(); public void startUpdate() { Observable<Integer> updateObservable = Observable.create(emitter -> { try { // 阶段1: 备份数据 if (emitter.isDisposed()) return; currentPhase.set(PHASE_BACKUP); notifyProgress("开始备份数据..."); backupDir = new File(cacheDir, "backup"); if (backupDir.exists()) { if (!FileUtils.deleteRecursive(backupDir)) { emitter.onError(new IOException("删除备份文件失败")); return; } } if (!backupDir.mkdirs()) { emitter.onError(new IOException("创建备份目录失败")); return; } backupSize = FileUtils.getDirectorySize(storageDir); if (backupSize > 0) { if (!singlecopydirectory.copyDirectoryWithProgress(storageDir, backupDir, (copied, total) -> { currentCopiedBytes = copied; notifyProgress("备份中: " + formatSize(copied) + "/" + formatSize(total)); })) { emitter.onError(new IOException("备份失败")); return; } if (!backupDir.renameTo(backupAlreadyDir)) { emitter.onError(new IOException("重命名备份目录失败")); return; } } else { currentCopiedBytes = 1; backupSize = 1; notifyProgress("无数据需要备份"); } // 阶段2: 处理升级包 currentPhase.set(PHASE_COPYING); File[] updatePackages = getUpdatePackages(); for (int i = 0; i < updatePackages.length; i++) { if (isCancelled) { emitter.onError(new IOException("用户取消")); return; } while (isPaused) { if (emitter.isDisposed()) return; Thread.sleep(500); } File packageFile = updatePackages[i]; String packageName = packageFile.getName(); // 拷贝 currentPhase.set(PHASE_COPYING); File destFile = new File(storageDir, packageName); boolean copyResult = FileUtils.copyFileWithProgress(packageFile, destFile, (copied, total) -> { currentCopiedBytes = copied; notifyProgress("拷贝中: " + formatSize(copied) + "/" + formatSize(total)); }); if (!copyResult) { emitter.onError(new IOException("拷贝失败")); return; } // 解密验签 currentPhase.set(PHASE_CHECKING); DecryptUtil.ProgressCallback decryptCallback = (processed, total) -> { currentVerifiedBytes = processed; notifyProgress("解密中: " + formatSize(processed) + "/" + formatSize(total)); }; if (!dataVerification(destFile.getAbsolutePath(), decryptCallback)) { emitter.onError(new IOException("解密失败")); return; } // 解压 currentPhase.set(PHASE_EXTRACTING); boolean extractResult = FileUtils.extractZipWithProgress(destFile, storageDir, (extracted, total) -> { currentExtractedBytes = extracted; notifyProgress("解压中: " + formatSize(extracted) + "/" + formatSize(total)); }); if (!extractResult) { emitter.onError(new IOException("解压失败")); return; } if (!destFile.delete()) { Log.w(TAG, "删除升级包失败"); } } if (!mapDataController.checkInstallationStatus()) { notifyProgress("校验失败"); emitter.onError(new IOException("校验失败")); return; } // 清理 currentPhase.set(PHASE_CLEANUP); notifyProgress("清理缓存..."); if (backupDir.exists() && !FileUtils.deleteRecursive(backupDir)) { Log.w(TAG, "删除备份文件失败"); } notifyProgress("更新完成"); emitter.onNext(SUCCESS); emitter.onComplete(); } catch (Exception e) { emitter.onError(e); } }); Disposable disposable = updateObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( result -> { if (result == SUCCESS) { if (backupAlreadyDir != null && backupAlreadyDir.exists()) { if (!FileUtils.deleteRecursive(backupAlreadyDir)) { Log.w(TAG, "删除备份文件失败"); } } notifyListener(SUCCESS, "更新成功"); currentPhase.set(PHASE_IDLE); } }, error -> { if (error instanceof IOException && error.getMessage().contains("用户取消")) { notifyListener(ERROR_USER_CANCELED, "用户取消"); } else { handleFailure(ERROR_UNEXPECTED); } } ); disposables.add(disposable); } public void cancelUpdate() { disposables.clear(); // 取消所有任务 rollback(); // 执行回滚 } private void rollback() { // 执行回滚逻辑 Log.i(TAG, "执行回滚操作"); } } // // ================== 核心更新逻辑 ================== private class UpdateTask extends AsyncTask<Void, Void, Integer> { // private File backupFile;//zwx-s private File[] updatePackages; @Override protected void onPreExecute() { currentPhase.set(PHASE_DETECTING); isCancelled = false; isPaused = false; currentCopiedBytes = 0; currentExtractedBytes = 0; mProgress = 0; // 重置进度为0 } @Override protected Integer doInBackground(Void... voids) { try { // 阶段1: 备份数据 currentPhase.set(PHASE_BACKUP); notifyProgress("开始备份数据..."); backupDir = new File(cacheDir, "backup"); Log.i(TAG, "初始化备份目录为:" + backupDir.getAbsolutePath());//ZWX if (backupDir.exists()) { if (!FileUtils.deleteRecursive(backupDir)) { throw new IOException("删除备份文件失败: " + backupDir.getAbsolutePath()); } } if (!backupDir.mkdirs()) { throw new IOException("创建备份目录失败: " + backupDir.getAbsolutePath()); } // 计算实际备份大小 Log.i(TAG, "核对实际需要备份的数据大小"); backupSize = FileUtils.getDirectorySize(storageDir); Log.i(TAG, "需要备份的数据大小:[" + formatSize(backupSize) + "]"); Log.i(TAG, "storage目录为:" + storageDir.getAbsolutePath());//ZWX if (backupSize > 0) { Log.i(TAG, "开始进行数据备份"); try { // 执行目录复制 if (!singlecopydirectory.copyDirectoryWithProgress(storageDir, backupDir, (copied, total) -> { currentCopiedBytes = copied; notifyProgress("备份中: " + formatSize(copied) + "/" + formatSize(total)); })) { throw new IOException("备份失败: " + storageDir.getAbsolutePath() + " -> " + backupDir.getAbsolutePath()); } notifyProgress("数据备份完成");//P4 if (!backupDir.renameTo(backupAlreadyDir)) { throw new IOException("重命名备份目录失败: " + backupDir.getAbsolutePath() + " -> " + backupAlreadyDir.getAbsolutePath()); } Log.i(TAG, "重命名备份目录成功"); } catch (Exception e) { Log.e(TAG, "备份过程中发生错误", e); // 可选:尝试二次备份或记录日志,这里直接抛出错误 return ERROR_COPY_FAILED; } } else { // 无数据需要备份,直接标记完成 Log.i(TAG, "无备份数据,直接进行数据更新"); currentCopiedBytes = 1; backupSize = 1; notifyProgress("无数据需要备份"); } // 检查是否被取消(场景1) if (isCancelled) { return ERROR_USER_CANCELED; } // 阶段2: 处理升级包 //p5:更新前清理压缩包 // if (storageDir.exists() && storageDir.isDirectory()) { // if (!singlecopydirectory.clearDirectoryContentsOnly(storageDir.toPath())) { // // throw new IOException("无法清空目标目录: " + storageDir.getAbsolutePath()); // // } // } updatePackages = getUpdatePackages(); Log.i(TAG, "开始处理升级包【拷贝、解密验签、解压】"); for (currentPackageIndex = 0; currentPackageIndex < updatePackages.length; currentPackageIndex++) { if (isCancelled) return ERROR_USER_CANCELED; // 处理暂停状态 while (isPaused) { Thread.sleep(500); } File packageFile = updatePackages[currentPackageIndex]; UpdateSize = updatePackages[currentPackageIndex].length(); String packageName = packageFile.getName(); long packageSize = packageFile.length(); // 备份完成后重置拷贝计数器 currentCopiedBytes = 0; // 阶段3: 拷贝升级包 currentPhase.set(PHASE_COPYING); File destFile = new File(storageDir, packageName); // 拷贝时更新进度(修改) boolean copyResult = FileUtils.copyFileWithProgress( packageFile, destFile, (copied, total) -> { currentCopiedBytes = copied; notifyProgress(String.format("拷贝 %s: %s/%s", packageName, formatSize(copied), formatSize(total))); } ); if (!copyResult) { lastErrorMessage = "拷贝失败: " + packageName; return ERROR_COPY_FAILED; } // 阶段4:解密验签 currentPhase.set(PHASE_CHECKING); currentVerifiedBytes = 0; // 重置验签计数器 // 创建进度回调适配器 DecryptUtil.ProgressCallback decryptCallback = new DecryptUtil.ProgressCallback() { @Override public void onProgress(long processed, long total) { // 直接更新验签进度计数器 currentVerifiedBytes = processed; // 触发进度通知 notifyProgress(String.format("解密验签 %s: %s/%s", packageName, formatSize(processed), formatSize(total))); } }; // 执行解密验签(传入回调) if (!dataVerification(destFile.getAbsolutePath(), decryptCallback)) { if (!isCancelled) { return ERROR_DECRYPT_OR_SIGN_FAILED; } } // 确保进度设置为100% currentVerifiedBytes = UpdateSize; // 阶段5: 解压升级包 currentPhase.set(PHASE_EXTRACTING); // 修复:重置解压计数器 currentExtractedBytes = 0; // 重置计数器 notifyProgress("解压升级包: " + packageName); // 解压时更新进度(修改) boolean extractResult = FileUtils.extractZipWithProgress( destFile, storageDir, (extracted, total) -> { currentExtractedBytes = extracted; notifyProgress(String.format("解压 %s: %s/%s", packageName, formatSize(extracted), formatSize(total))); } ); if (!extractResult) { lastErrorMessage = "解压失败: " + packageName; return ERROR_EXTRACT_FAILED; } // 删除已解压的升级包以节省空间 if (!destFile.delete()) { Log.w(TAG, "删除升级包失败: " + destFile.getName()); } // 更新解压进度(完成当前包) currentExtractedBytes += packageSize; } if (!mapDataController.checkInstallationStatus()) { notifyProgress("校验失败"); return ERROR_FILE_VERIFY_FAILED; } else { notifyProgress("校验成功"); } // MapDownloader.fromEngineAsync(sdkNativeEngine, new MapDownloaderConstructionCallback() { // @Override // public void onMapDownloaderConstructedCompleted(@NonNull MapDownloader downloader) { // Log.i(TAG, "数据同步成功"); // } // }); // 阶段5: 清理工作 currentPhase.set(PHASE_CLEANUP); notifyProgress("清理缓存..."); if (backupDir.exists() && !FileUtils.deleteRecursive(backupDir)) { Log.w(TAG, "删除备份文件失败"); } // 最终进度设为100% notifyProgress("更新完成"); return SUCCESS; } catch (InterruptedException e) { lastErrorMessage = "更新任务被中断"; handleFailure(ERROR_USER_CANCELED); return ERROR_USER_CANCELED; } catch (Exception e) { lastErrorMessage = "未知错误: " + e.getMessage(); Log.e(TAG, "更新失败", e); return ERROR_UNEXPECTED; } } @Override protected void onCancelled() { lastErrorMessage = "更新任务被中断"; handleFailure(ERROR_USER_CANCELED); Log.d("MyTask", "任务被取消"); } @Override protected void onPostExecute(Integer resultCode) { if (resultCode == SUCCESS) { if (backupAlreadyDir != null && backupAlreadyDir.exists()) { Log.w(TAG, "开始删除备份文件: " + backupAlreadyDir.getAbsolutePath()); if (!FileUtils.deleteRecursive(backupAlreadyDir)) { Log.w(TAG, "删除备份文件失败: " + backupAlreadyDir.getAbsolutePath()); } } notifyListener(SUCCESS, "更新成功,请重启车机"); currentPhase.set(PHASE_IDLE); currentTask = null; } else { handleFailure(resultCode);//p4-1 } } } 务必保证rxjavaasynctask的流程注释文言完全一致,修复rxjava让它保持其优越性的基础上,在功能性上和asynctask一致。给出完整的rxjava实现
最新发布
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值