66
77import 'dart:ffi' ;
88import 'dart:io' ;
9+ import 'dart:ui' ;
910
1011import 'package:ffi/ffi.dart' ;
1112import 'package:flutter/material.dart' ;
@@ -73,12 +74,13 @@ String backAndForth() {
7374 return dartString;
7475}
7576
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, []);
7981}
8082
81- void showToast (String text) {
83+ void showToast (String text, JObject activity ) {
8284 // This is example for calling your app's custom java code.
8385 // Place the Toaster class in the app's android/ source Folder, with a Keep
8486 // annotation or appropriate proguard rules to retain classes in release mode.
@@ -93,9 +95,9 @@ void showToast(String text) {
9395 '(Landroid/app/Activity;Landroid/content/Context;'
9496 'Ljava/lang/CharSequence;I)'
9597 '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 ! ),
99101 '😀' .toJString (),
100102 0 ,
101103 ]);
@@ -104,19 +106,20 @@ void showToast(String text) {
104106}
105107
106108void main () {
109+ WidgetsFlutterBinding .ensureInitialized ();
107110 if (! Platform .isAndroid) {
108111 Jni .spawn ();
109112 }
110113 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 ),
113116 runInitially: false ),
114- Example ("Math.random()" , () => randomDouble (), runInitially: false ),
117+ Example ("Math.random()" , (_ ) => randomDouble (), runInitially: false ),
115118 if (Platform .isAndroid) ...[
116119 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" , (_ ) {
120123 final buildClass = JClass .forName ("android/os/Build" );
121124 return buildClass
122125 .staticFieldId ("DEVICE" , JString .type.signature)
@@ -125,13 +128,15 @@ void main() {
125128 }),
126129 Example (
127130 "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 ,
132139 ),
133- Example ("Show toast" , () => showToast ("Hello from JNI!" ),
134- runInitially: false ),
135140 Example (
136141 "Quit" ,
137142 quit,
@@ -144,7 +149,7 @@ void main() {
144149
145150class Example {
146151 String title;
147- dynamic Function () callback;
152+ dynamic Function (JObject activity ) callback;
148153 bool runInitially;
149154 Example (this .title, this .callback, {this .runInitially = true });
150155}
@@ -158,8 +163,12 @@ class MyApp extends StatefulWidget {
158163}
159164
160165class _MyAppState extends State <MyApp > {
166+ late Stream <JObject ?> activityStream;
167+
161168 @override
162169 void initState () {
170+ activityStream =
171+ Jni .androidActivities (PlatformDispatcher .instance.engineId! );
163172 super .initState ();
164173 }
165174
@@ -170,20 +179,29 @@ class _MyAppState extends State<MyApp> {
170179 appBar: AppBar (
171180 title: const Text ('JNI Examples' ),
172181 ),
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+ );
178195 }),
179196 ),
180197 );
181198 }
182199}
183200
184201class ExampleCard extends StatefulWidget {
185- const ExampleCard (this .example, {super .key});
202+ const ExampleCard (this .example, this .activity, {super .key});
186203 final Example example;
204+ final JObject activity;
187205
188206 @override
189207 _ExampleCardState createState () => _ExampleCardState ();
@@ -210,7 +228,7 @@ class _ExampleCardState extends State<ExampleCard> {
210228 var hasError = false ;
211229 if (_run) {
212230 try {
213- result = eg.callback ().toString ();
231+ result = eg.callback (widget.activity ).toString ();
214232 } on Exception catch (e) {
215233 hasError = true ;
216234 result = e.toString ();
0 commit comments