From 5c797fa5acf6fc2f73c347f7e1c74630548df525 Mon Sep 17 00:00:00 2001 From: Seonghyun Kim Date: Fri, 27 Oct 2023 17:27:18 +0900 Subject: [PATCH] Add example of MultiThreadExecutor Signed-off-by: Seonghyun Kim --- .../android/app/src/main/AndroidManifest.xml | 1 + .../lwe/escargot/shell/MainActivity.java | 128 +++++++++++++++++- .../app/src/main/res/layout/activity_main.xml | 6 + .../samsung/lwe/escargot/EscargotTest.java | 88 ++++++++++++ 4 files changed, 218 insertions(+), 5 deletions(-) diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml index fdf77a270..d55271d5b 100644 --- a/build/android/app/src/main/AndroidManifest.xml +++ b/build/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,7 @@ + callback(Context context, JavaScriptValue javaS }).start(); } + public void runExample() + { + new Thread(() -> { + Looper.prepare(); + Handler handler = new Handler(Looper.myLooper()); + + Globals.initializeGlobals(); + + VMInstance vmInstance = VMInstance.create(Optional.empty(), Optional.empty()); + Context context = Context.create(vmInstance); + + context.getGlobalObject().set(context, JavaScriptString.create("print"), JavaScriptJavaCallbackFunctionObject.create(context, "", 1, false, new JavaScriptJavaCallbackFunctionObject.Callback() { + @Override + public Optional callback(Context context, JavaScriptValue receiverValue, JavaScriptValue[] arguments) { + System.out.println(arguments[0].toString(context).get().toJavaString()); + return Optional.empty(); + } + })); + + context.getGlobalObject().set(context, JavaScriptString.create("end"), JavaScriptJavaCallbackFunctionObject.create(context, "", 1, false, new JavaScriptJavaCallbackFunctionObject.Callback() { + @Override + public Optional callback(Context context, JavaScriptValue receiverValue, JavaScriptValue[] arguments) { + Looper.myLooper().quitSafely(); + return Optional.empty(); + } + })); + + MultiThreadExecutor executor = new MultiThreadExecutor(vmInstance, new MultiThreadExecutor.WorkerThreadEndNotifier() { + @Override + public void notify(MultiThreadExecutor executor, MultiThreadExecutor.ExecutorInstance instance) { + handler.post(new Runnable() { + @Override + public void run() { + executor.pumpEventsFromThreadIfNeeds(); + } + }); + } + }); + Bridge.register(context, "HTTP", "get", new Bridge.Adapter() { + @Override + public Optional callback(Context context, Optional data) { + String url = ""; + if (data.isPresent()) { + Optional mayBeString = data.get().toString(context); + if (mayBeString.isPresent()) { + url = mayBeString.get().toJavaString(); + } + } + final String finalURL = url; + MultiThreadExecutor.ExecutorInstance instance = executor.startWorker(context, new MultiThreadExecutor.Executor() { + @Override + public MultiThreadExecutor.ResultBuilderContext run() { + try { + HttpURLConnection connection = (HttpURLConnection)new URL(finalURL).openConnection(); + connection.setRequestMethod("GET"); + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { // success + BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); + String inputLine; + StringBuffer response = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + return new MultiThreadExecutor.ResultBuilderContext(true, response.toString()); + } else { + return new MultiThreadExecutor.ResultBuilderContext(false, "error HTTP return code:" + responseCode); + } + } catch (IOException e) { + return new MultiThreadExecutor.ResultBuilderContext(false, e.toString()); + } + } + }, new MultiThreadExecutor.ResultBuilder() { + @Override + public JavaScriptValue build(Context scriptContext, MultiThreadExecutor.ResultBuilderContext builderContext) { + return JavaScriptString.create((String)builderContext.data()); + } + }); + return Optional.of(instance.promise()); + } + }); + + Evaluator.evalScript(context, "" + + "let promise1 = HTTP.get('https://httpbin.org/get');" + + "let promise2 = HTTP.get('http://google.com');" + + "Promise.allSettled([promise1, promise2]).then(function(v) {" + + "print(JSON.stringify(v));" + + "print('http all end!');" + + "end();" + + "});", "", false); + + + Looper.loop(); + Looper.myLooper().quit(); + + context = null; + vmInstance = null; + + Memory.gc(); + Memory.gc(); + Memory.gc(); + Memory.gc(); + Memory.gc(); + + Globals.finalizeGlobals(); + }).start(); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -205,11 +323,11 @@ public void onClick(View v) { } }); - (new Handler()).postDelayed(new Runnable() { + findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { @Override - public void run() { - findViewById(R.id.button).callOnClick(); + public void onClick(View v) { + runExample(); } - }, 3000); + }); } } \ No newline at end of file diff --git a/build/android/app/src/main/res/layout/activity_main.xml b/build/android/app/src/main/res/layout/activity_main.xml index e12ed3d7b..b1f09ba2e 100644 --- a/build/android/app/src/main/res/layout/activity_main.xml +++ b/build/android/app/src/main/res/layout/activity_main.xml @@ -11,6 +11,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="run"/> +