11package com .tflite ;
22
3+ import android .annotation .SuppressLint ;
4+ import android .content .Context ;
5+ import android .net .Uri ;
36import android .util .Log ;
47
58import androidx .annotation .NonNull ;
69
710import com .facebook .proguard .annotations .DoNotStrip ;
811import com .facebook .react .bridge .JavaScriptContextHolder ;
9- import com .facebook .react .bridge .Promise ;
1012import com .facebook .react .bridge .ReactApplicationContext ;
1113import com .facebook .react .bridge .ReactContextBaseJavaModule ;
1214import com .facebook .react .bridge .ReactMethod ;
1315import com .facebook .react .module .annotations .ReactModule ;
1416import com .facebook .react .turbomodule .core .CallInvokerHolderImpl ;
1517
18+ import java .io .ByteArrayOutputStream ;
19+ import java .io .InputStream ;
20+ import java .lang .ref .WeakReference ;
21+
1622import okhttp3 .OkHttpClient ;
1723import okhttp3 .Request ;
1824import okhttp3 .Response ;
2127@ ReactModule (name = TfliteModule .NAME )
2228public class TfliteModule extends ReactContextBaseJavaModule {
2329 public static final String NAME = "Tflite" ;
30+ private static WeakReference <ReactApplicationContext > weakContext ;
31+ private static final OkHttpClient client = new OkHttpClient ();
2432
2533 public TfliteModule (ReactApplicationContext reactContext ) {
2634 super (reactContext );
35+ weakContext = new WeakReference <>(reactContext );
2736 }
2837
2938 @ Override
@@ -32,21 +41,64 @@ public String getName() {
3241 return NAME ;
3342 }
3443
44+ @ SuppressLint ("DiscouragedApi" )
45+ private static int getResourceId (Context context , String name ) {
46+ return context .getResources ().getIdentifier (
47+ name ,
48+ "raw" ,
49+ context .getPackageName ()
50+ );
51+ }
52+
53+ /** @noinspection unused*/
3554 @ DoNotStrip
36- public static byte [] fetchByteDataFromUrl (String url ) {
37- OkHttpClient client = new OkHttpClient ( );
55+ public static byte [] fetchByteDataFromUrl (String url ) throws Exception {
56+ Log . i ( NAME , "Loading byte data from URL: " + url + "..." );
3857
39- Request request = new Request .Builder ().url (url ).build ();
58+ Uri uri = null ;
59+ Integer resourceId = null ;
60+ if (url .contains ("://" )) {
61+ Log .i (NAME , "Parsing URL..." );
62+ uri = Uri .parse (url );
63+ Log .i (NAME , "Parsed URL: " + uri .toString ());
64+ } else {
65+ Log .i (NAME , "Parsing resourceId..." );
66+ resourceId = getResourceId (weakContext .get (), url );
67+ Log .i (NAME , "Parsed resourceId: " + resourceId );
68+ }
4069
41- try (Response response = client .newCall (request ).execute ()) {
42- if (response .isSuccessful () && response .body () != null ) {
43- return response .body ().bytes ();
44- } else {
45- throw new RuntimeException ("Response was not successful!" );
70+ if (uri != null ) {
71+ // It's a URL/http resource
72+ Request request = new Request .Builder ().url (uri .toString ()).build ();
73+ try (Response response = client .newCall (request ).execute ()) {
74+ if (response .isSuccessful () && response .body () != null ) {
75+ return response .body ().bytes ();
76+ } else {
77+ throw new RuntimeException ("Response was not successful!" );
78+ }
79+ } catch (Exception ex ) {
80+ Log .e (NAME , "Failed to fetch URL " + url + "!" , ex );
81+ throw ex ;
82+ }
83+ } else if (resourceId != null ) {
84+ // It's bundled into the Android resources/assets
85+ Context context = weakContext .get ();
86+ if (context == null ) {
87+ throw new Exception ("React Context has already been destroyed!" );
88+ }
89+ try (InputStream stream = context .getResources ().openRawResource (resourceId )) {
90+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream ();
91+ byte [] buffer = new byte [2048 ];
92+ int length ;
93+ while ((length = stream .read (buffer )) != -1 ) {
94+ byteStream .write (buffer , 0 , length );
95+ }
96+ return byteStream .toByteArray ();
4697 }
47- } catch (Exception e ) {
48- Log .e (NAME , "Failed to fetch URL " + url + "!" , e );
49- return null ;
98+ } else {
99+ // It's a bird? it's a plane? not it's an error
100+ throw new Exception ("Input is neither a valid URL, nor a resourceId - " +
101+ "cannot load TFLite model! (Input: " + url + ")" );
50102 }
51103 }
52104
0 commit comments