@@ -10,23 +10,22 @@ import androidx.work.WorkerParameters
10
10
import com.google.common.util.concurrent.ListenableFuture
11
11
import io.flutter.embedding.engine.FlutterEngine
12
12
import io.flutter.embedding.engine.dart.DartExecutor
13
+ import io.flutter.embedding.engine.loader.FlutterLoader
13
14
import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry
14
15
import io.flutter.plugin.common.MethodCall
15
16
import io.flutter.plugin.common.MethodChannel
16
17
import io.flutter.view.FlutterCallbackInformation
17
- import io.flutter.view.FlutterMain
18
18
import java.util.*
19
19
20
20
/* **
21
21
* A simple worker that will post your input back to your Flutter application.
22
22
*
23
23
* It will block the background thread until a value of either true or false is received back from Flutter code.
24
- *
25
24
*/
26
25
class BackgroundWorker (
27
- private val ctx : Context ,
26
+ applicationContext : Context ,
28
27
private val workerParams : WorkerParameters
29
- ) : ListenableWorker(ctx , workerParams), MethodChannel.MethodCallHandler {
28
+ ) : ListenableWorker(applicationContext , workerParams), MethodChannel.MethodCallHandler {
30
29
31
30
private lateinit var backgroundChannel: MethodChannel
32
31
@@ -37,8 +36,11 @@ class BackgroundWorker(
37
36
const val DART_TASK_KEY = " be.tramckrijte.workmanager.DART_TASK"
38
37
const val IS_IN_DEBUG_MODE_KEY = " be.tramckrijte.workmanager.IS_IN_DEBUG_MODE_KEY"
39
38
40
- const val BACKGROUND_CHANNEL_NAME = " be.tramckrijte.workmanager/background_channel_work_manager"
39
+ const val BACKGROUND_CHANNEL_NAME =
40
+ " be.tramckrijte.workmanager/background_channel_work_manager"
41
41
const val BACKGROUND_CHANNEL_INITIALIZED = " backgroundChannelInitialized"
42
+
43
+ private val flutterLoader = FlutterLoader ()
42
44
}
43
45
44
46
private val payload
@@ -51,40 +53,55 @@ class BackgroundWorker(
51
53
get() = workerParams.inputData.getBoolean(IS_IN_DEBUG_MODE_KEY , false )
52
54
53
55
private val randomThreadIdentifier = Random ().nextInt()
54
- private lateinit var engine: FlutterEngine
56
+ private var engine: FlutterEngine ? = null
55
57
56
- private var destroying = false
57
58
private var startTime: Long = 0
58
59
private val resolvableFuture = ResolvableFuture .create<Result >()
59
60
60
61
override fun startWork (): ListenableFuture <Result > {
61
62
startTime = System .currentTimeMillis()
62
63
63
- engine = FlutterEngine (ctx)
64
- FlutterMain .ensureInitializationComplete(ctx, null )
64
+ engine = FlutterEngine (applicationContext)
65
65
66
- val callbackHandle = SharedPreferenceHelper .getCallbackHandle(ctx)
67
- val callbackInfo = FlutterCallbackInformation .lookupCallbackInformation(callbackHandle)
68
- val dartBundlePath = FlutterMain .findAppBundlePath()
69
-
70
- if (isInDebug) {
71
- DebugHelper .postTaskStarting(
72
- ctx,
73
- randomThreadIdentifier,
74
- dartTask,
75
- payload,
76
- callbackHandle,
77
- callbackInfo,
78
- dartBundlePath
79
- )
66
+ if (! flutterLoader.initialized()) {
67
+ flutterLoader.startInitialization(applicationContext)
80
68
}
81
69
82
- // Backwards compatibility with v1. We register all the user's plugins.
83
- WorkmanagerPlugin .pluginRegistryCallback?.registerWith(ShimPluginRegistry (engine))
84
- engine.dartExecutor.executeDartCallback(DartExecutor .DartCallback (ctx.assets, dartBundlePath, callbackInfo))
70
+ flutterLoader.ensureInitializationCompleteAsync(
71
+ applicationContext,
72
+ null ,
73
+ Handler (Looper .getMainLooper())
74
+ ) {
75
+ val callbackHandle = SharedPreferenceHelper .getCallbackHandle(applicationContext)
76
+ val callbackInfo = FlutterCallbackInformation .lookupCallbackInformation(callbackHandle)
77
+ val dartBundlePath = flutterLoader.findAppBundlePath()
78
+
79
+ if (isInDebug) {
80
+ DebugHelper .postTaskStarting(
81
+ applicationContext,
82
+ randomThreadIdentifier,
83
+ dartTask,
84
+ payload,
85
+ callbackHandle,
86
+ callbackInfo,
87
+ dartBundlePath
88
+ )
89
+ }
90
+
91
+ // Backwards compatibility with v1. We register all the user's plugins.
92
+ WorkmanagerPlugin .pluginRegistryCallback?.registerWith(ShimPluginRegistry (engine!! ))
85
93
86
- backgroundChannel = MethodChannel (engine.dartExecutor, BACKGROUND_CHANNEL_NAME )
87
- backgroundChannel.setMethodCallHandler(this @BackgroundWorker)
94
+ backgroundChannel = MethodChannel (engine!! .dartExecutor, BACKGROUND_CHANNEL_NAME )
95
+ backgroundChannel.setMethodCallHandler(this @BackgroundWorker)
96
+
97
+ engine!! .dartExecutor.executeDartCallback(
98
+ DartExecutor .DartCallback (
99
+ applicationContext.assets,
100
+ dartBundlePath,
101
+ callbackInfo
102
+ )
103
+ )
104
+ }
88
105
89
106
return resolvableFuture
90
107
}
@@ -98,7 +115,7 @@ class BackgroundWorker(
98
115
99
116
if (isInDebug) {
100
117
DebugHelper .postTaskCompleteNotification(
101
- ctx ,
118
+ applicationContext ,
102
119
randomThreadIdentifier,
103
120
dartTask,
104
121
payload,
@@ -115,11 +132,8 @@ class BackgroundWorker(
115
132
116
133
// If stopEngine is called from `onStopped`, it may not be from the main thread.
117
134
Handler (Looper .getMainLooper()).post {
118
- if (! destroying) {
119
- if (this ::engine.isInitialized)
120
- engine.destroy()
121
- destroying = true
122
- }
135
+ engine?.destroy()
136
+ engine = null
123
137
}
124
138
}
125
139
@@ -134,7 +148,11 @@ class BackgroundWorker(
134
148
stopEngine(Result .failure())
135
149
}
136
150
137
- override fun error (errorCode : String? , errorMessage : String? , errorDetails : Any? ) {
151
+ override fun error (
152
+ errorCode : String? ,
153
+ errorMessage : String? ,
154
+ errorDetails : Any?
155
+ ) {
138
156
Log .e(TAG , " errorCode: $errorCode , errorMessage: $errorMessage " )
139
157
stopEngine(Result .failure())
140
158
}
0 commit comments