diff --git a/ohos/src/main/ets/components/FlutterDownloaderPlugin.ets b/ohos/src/main/ets/components/FlutterDownloaderPlugin.ets index 19af95eaaf9e7dd77b4f18f737f1916226134e21..b7a2c0b14558ddf75259cc53ad9b563ccf43220f 100644 --- a/ohos/src/main/ets/components/FlutterDownloaderPlugin.ets +++ b/ohos/src/main/ets/components/FlutterDownloaderPlugin.ets @@ -17,6 +17,10 @@ import { AbilityAware, AbilityPluginBinding, Any, + DartExecutor, + FlutterCallbackInformation, + FlutterEngine, + FlutterInjector, FlutterPlugin, FlutterPluginBinding, MethodCall, @@ -35,6 +39,7 @@ import { common, Want, wantConstant } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { request } from '@kit.BasicServicesKit'; import Logger from './Logger'; +import { DartCallback } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor'; const invalidTaskId = "invalid_task_id"; const invalidStatus = "invalid_status"; @@ -46,10 +51,12 @@ export class FlutterDownloaderPlugin implements FlutterPlugin, MethodCallHandler public static readonly SHARED_PREFERENCES_KEY = 'vn.hunghd.downloader.pref'; public static readonly CALLBACK_DISPATCHER_HANDLE_KEY = "callback_dispatcher_handle_key"; private flutterChannel: MethodChannel | null = null; + private backgroundChannel: MethodChannel | null = null; private flutterPluginBinding: FlutterPluginBinding | null = null; private taskDao: TaskDao | null = null; private context: common.UIAbilityContext | null = null; private callbackHandle: number = 0; + private backgroundFlutterEngine: FlutterEngine | null = null; private debugMode: number = 0; private tasks: Set = new Set(); @@ -79,6 +86,10 @@ export class FlutterDownloaderPlugin implements FlutterPlugin, MethodCallHandler this.flutterChannel.setMethodCallHandler(null); this.flutterChannel = null; } + if (this.backgroundChannel != null) { + this.backgroundChannel.setMethodCallHandler(null); + this.backgroundChannel = null; + } } getUniqueClassName(): string { @@ -356,6 +367,8 @@ export class FlutterDownloaderPlugin implements FlutterPlugin, MethodCallHandler preferences.getPreferencesSync(this.context, { name: FlutterDownloaderPlugin.SHARED_PREFERENCES_KEY }) .putSync(FlutterDownloaderPlugin.CALLBACK_DISPATCHER_HANDLE_KEY, this.callbackHandle); result.success(null) + + this.startBackgroundIsolate(this.callbackHandle); } private sendUpdateProgress(id: string, status: DownloadStatus, progress: number): void { @@ -420,6 +433,12 @@ export class FlutterDownloaderPlugin implements FlutterPlugin, MethodCallHandler lastProgress = -1; } else { lastProgress = Math.trunc(progress.processed * 100 / progress.sizes[0]); + + const args: Map = new Map(); + args["task_id"] = taskId + args["status"] = status + args["progress"] = lastProgress + this.backgroundChannel?.invokeMethod('', [this.callbackHandle, taskId, status, lastProgress]) } const values: ValuesBucket = {}; values[TaskEntry.COLUMN_NAME_FILE_NAME] = filename; @@ -549,4 +568,26 @@ export class FlutterDownloaderPlugin implements FlutterPlugin, MethodCallHandler return Promise.resolve(taskId); } + + private async startBackgroundIsolate(handle: number) { + if (this.backgroundFlutterEngine == null) { + let context = this.context ?? getContext(this); + this.backgroundFlutterEngine = new FlutterEngine(context, null, null, null); + await this.backgroundFlutterEngine.init(context, null, true); + + let flutterCallback = FlutterCallbackInformation.lookupCallbackInformation(handle); + if (flutterCallback == null) { + Logger.error(TAG, `Fatal: failed to find callback".`); + return + } + let resourceManager = context.getApplicationContext().resourceManager; + let appBundlePath = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + this.backgroundFlutterEngine?.dartExecutor.executeDartCallback( + new DartCallback(resourceManager, appBundlePath, flutterCallback) + ) + } + this.backgroundChannel = + new MethodChannel(this.backgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), "vn.hunghd/downloader_background"); + this.backgroundChannel.setMethodCallHandler(this); + } } \ No newline at end of file