6
6
7
7
import 'dart:ffi' ;
8
8
import 'dart:io' ;
9
+ import 'dart:ui' ;
9
10
10
11
import 'package:ffi/ffi.dart' ;
11
12
import 'package:flutter/material.dart' ;
@@ -73,12 +74,13 @@ String backAndForth() {
73
74
return dartString;
74
75
}
75
76
76
- void quit () {
77
- JObject .fromReference (Jni .getCurrentActivity ()).use ((ac) =>
78
- ac.jClass.instanceMethodId ("finish" , "()V" ).call (ac, jvoid.type, []));
77
+ void quit (JObject activity) {
78
+ activity.jClass
79
+ .instanceMethodId ("finish" , "()V" )
80
+ .call (activity, jvoid.type, []);
79
81
}
80
82
81
- void showToast (String text) {
83
+ void showToast (String text, JObject activity ) {
82
84
// This is example for calling your app's custom java code.
83
85
// Place the Toaster class in the app's android/ source Folder, with a Keep
84
86
// annotation or appropriate proguard rules to retain classes in release mode.
@@ -93,9 +95,9 @@ void showToast(String text) {
93
95
'(Landroid/app/Activity;Landroid/content/Context;'
94
96
'Ljava/lang/CharSequence;I)'
95
97
'Lcom/github/dart_lang/jni_example/Toaster;' );
96
- final toaster = makeText. call (toasterClass, JObject .type, [
97
- Jni . getCurrentActivity () ,
98
- Jni .getCachedApplicationContext ( ),
98
+ final toaster = makeText (toasterClass, JObject .type, [
99
+ activity ,
100
+ Jni .androidApplicationContext ( PlatformDispatcher .instance.engineId ! ),
99
101
'😀' .toJString (),
100
102
0 ,
101
103
]);
@@ -104,19 +106,20 @@ void showToast(String text) {
104
106
}
105
107
106
108
void main () {
109
+ WidgetsFlutterBinding .ensureInitialized ();
107
110
if (! Platform .isAndroid) {
108
111
Jni .spawn ();
109
112
}
110
113
final examples = [
111
- Example ("String.valueOf(1332)" , () => toJavaStringUsingEnv (1332 )),
112
- Example ("Generate random number" , () => randomUsingEnv (180 ),
114
+ Example ("String.valueOf(1332)" , (_ ) => toJavaStringUsingEnv (1332 )),
115
+ Example ("Generate random number" , (_ ) => randomUsingEnv (180 ),
113
116
runInitially: false ),
114
- Example ("Math.random()" , () => randomDouble (), runInitially: false ),
117
+ Example ("Math.random()" , (_ ) => randomDouble (), runInitially: false ),
115
118
if (Platform .isAndroid) ...[
116
119
Example ("Minutes of usage since reboot" ,
117
- () => (uptime () / (60 * 1000 )).floor ()),
118
- Example ("Back and forth string conversion" , () => backAndForth ()),
119
- Example ("Device name" , () {
120
+ (_ ) => (uptime () / (60 * 1000 )).floor ()),
121
+ Example ("Back and forth string conversion" , (_ ) => backAndForth ()),
122
+ Example ("Device name" , (_ ) {
120
123
final buildClass = JClass .forName ("android/os/Build" );
121
124
return buildClass
122
125
.staticFieldId ("DEVICE" , JString .type.signature)
@@ -125,13 +128,15 @@ void main() {
125
128
}),
126
129
Example (
127
130
"Package name" ,
128
- () => JObject .fromReference (Jni .getCurrentActivity ()).use ((activity) =>
129
- activity.jClass
130
- .instanceMethodId ("getPackageName" , "()Ljava/lang/String;" )
131
- .call (activity, JString .type, [])),
131
+ (activity) => activity.jClass
132
+ .instanceMethodId ("getPackageName" , "()Ljava/lang/String;" )
133
+ .call (activity, JString .type, []),
134
+ ),
135
+ Example (
136
+ "Show toast" ,
137
+ (activity) => showToast ("Hello from JNI!" , activity),
138
+ runInitially: false ,
132
139
),
133
- Example ("Show toast" , () => showToast ("Hello from JNI!" ),
134
- runInitially: false ),
135
140
Example (
136
141
"Quit" ,
137
142
quit,
@@ -144,7 +149,7 @@ void main() {
144
149
145
150
class Example {
146
151
String title;
147
- dynamic Function () callback;
152
+ dynamic Function (JObject activity ) callback;
148
153
bool runInitially;
149
154
Example (this .title, this .callback, {this .runInitially = true });
150
155
}
@@ -158,8 +163,12 @@ class MyApp extends StatefulWidget {
158
163
}
159
164
160
165
class _MyAppState extends State <MyApp > {
166
+ late Stream <JObject ?> activityStream;
167
+
161
168
@override
162
169
void initState () {
170
+ activityStream =
171
+ Jni .androidActivities (PlatformDispatcher .instance.engineId! );
163
172
super .initState ();
164
173
}
165
174
@@ -170,20 +179,29 @@ class _MyAppState extends State<MyApp> {
170
179
appBar: AppBar (
171
180
title: const Text ('JNI Examples' ),
172
181
),
173
- body: ListView .builder (
174
- itemCount: widget.examples.length,
175
- itemBuilder: (context, i) {
176
- final eg = widget.examples[i];
177
- return ExampleCard (eg);
182
+ body: StreamBuilder (
183
+ stream: activityStream,
184
+ builder: (_, snapshot) {
185
+ if (! snapshot.hasData || snapshot.data == null ) {
186
+ return Container ();
187
+ }
188
+ return ListView .builder (
189
+ itemCount: widget.examples.length,
190
+ itemBuilder: (context, i) {
191
+ final eg = widget.examples[i];
192
+ return ExampleCard (eg, snapshot.data! );
193
+ },
194
+ );
178
195
}),
179
196
),
180
197
);
181
198
}
182
199
}
183
200
184
201
class ExampleCard extends StatefulWidget {
185
- const ExampleCard (this .example, {super .key});
202
+ const ExampleCard (this .example, this .activity, {super .key});
186
203
final Example example;
204
+ final JObject activity;
187
205
188
206
@override
189
207
_ExampleCardState createState () => _ExampleCardState ();
@@ -210,7 +228,7 @@ class _ExampleCardState extends State<ExampleCard> {
210
228
var hasError = false ;
211
229
if (_run) {
212
230
try {
213
- result = eg.callback ().toString ();
231
+ result = eg.callback (widget.activity ).toString ();
214
232
} on Exception catch (e) {
215
233
hasError = true ;
216
234
result = e.toString ();
0 commit comments