Mercurial > dwindows
changeset 2501:41984ffb5ca2
Android: Initial implement of HTML control with WebView.
Getting an error about view calls not on the UI thread, even though
the call stack is on the main thread... confusing.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 06 May 2021 00:05:32 +0000 |
parents | ac0b7e579229 |
children | b6319aed3298 |
files | android/DWindows.kt android/dw.cpp |
diffstat | 2 files changed, 141 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/android/DWindows.kt Wed May 05 21:59:23 2021 +0000 +++ b/android/DWindows.kt Thu May 06 00:05:32 2021 +0000 @@ -14,17 +14,18 @@ import android.text.InputFilter import android.text.InputFilter.LengthFilter import android.text.method.PasswordTransformationMethod +import android.util.Base64 import android.util.Log import android.view.Gravity import android.view.View import android.view.ViewGroup +import android.webkit.WebView import android.widget.* import android.widget.SeekBar.OnSeekBarChangeListener import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.collection.SimpleArrayMap import androidx.recyclerview.widget.RecyclerView -import androidx.viewpager.widget.ViewPager import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout.OnTabSelectedListener @@ -678,6 +679,53 @@ percent.max = range } + fun htmlNew(cid: Int): WebView? + { + val looper = Looper.myLooper() + + // WebView requires an active Looper + if(looper == null) { + Looper.prepare() + } + + var dataArrayMap = SimpleArrayMap<String, Long>() + val html = WebView(this) + + html.tag = dataArrayMap + html.id = cid + return html + } + + fun htmlLoadURL(html: WebView, url: String) + { + html.loadUrl(url) + } + + fun htmlRaw(html: WebView, data: String) + { + val encodedHtml: String = Base64.encodeToString(data.toByteArray(), Base64.NO_PADDING) + html.loadData(encodedHtml, "text/html", "base64") + } + + fun htmlJavascriptRun(html: WebView, javascript: String, data: Long) + { + html.evaluateJavascript(javascript) { value -> + // Execute onReceiveValue's code + eventHandlerHTMLResult(html, 18, value, data) + } + } + + fun htmlAction(html: WebView, action: Int) + { + when (action) { + 0 -> html.goBack() + 1 -> html.goForward() + 2 -> html.loadUrl("http://dwindows.netlabs.org") + 4 -> html.reload() + 5 -> html.stopLoading() + } + } + fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer { // creating timer task, timer @@ -801,6 +849,7 @@ external fun eventHandlerSimple(obj1: View, message: Int) external fun eventHandlerNotebook(obj1: View, message: Int, pageID: Long) external fun eventHandlerTimer(sigfunc: Long, data: Long): Int + external fun eventHandlerHTMLResult(obj1: View, message: Int, result: String, data: Long) companion object {
--- a/android/dw.cpp Wed May 05 21:59:23 2021 +0000 +++ b/android/dw.cpp Thu May 06 00:05:32 2021 +0000 @@ -371,7 +371,7 @@ _dw_event_handler(obj1, params, message); } -/* A more simple method for quicker calls */ +/* Handler for notebook page changes */ JNIEXPORT void JNICALL Java_org_dbsoft_dwindows_DWindows_eventHandlerNotebook(JNIEnv* env, jobject obj, jobject obj1, jint message, jlong pageID) { void *params[8] = { NULL }; @@ -380,6 +380,16 @@ _dw_event_handler(obj1, params, message); } +/* Handler for HTML events */ +JNIEXPORT void JNICALL +Java_org_dbsoft_dwindows_DWindows_eventHandlerHTMLResult(JNIEnv* env, jobject obj, jobject obj1, + jint message, jstring htmlResult, jlong data) { + const char *result = env->GetStringUTFChars(htmlResult, NULL); + void *params[8] = { NULL, DW_POINTER(result), NULL, 0, 0, 0, 0, DW_INT_TO_POINTER(data) }; + + _dw_event_handler(obj1, params, message); +} + JNIEXPORT void JNICALL Java_org_dbsoft_dwindows_DWindows_eventHandlerInt(JNIEnv* env, jobject obj, jobject obj1, jint message, jint inta, jint intb, jint intc, jint intd) { @@ -887,7 +897,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(box && item && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -909,7 +919,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -935,7 +945,7 @@ JNIEnv *env; HWND retval = 0; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { + if(box && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); // Get the method that you want to call @@ -1082,7 +1092,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -1250,7 +1260,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -1321,7 +1331,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -1368,7 +1378,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -1419,7 +1429,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call //jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -1443,7 +1453,7 @@ { JNIEnv *env; - if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { // First get the class that contains the method you need to call //jclass clazz = _dw_find_class(env, DW_CLASS_NAME); @@ -2790,19 +2800,46 @@ */ void API dw_html_action(HWND handle, int action) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlAction = env->GetMethodID(clazz, "htmlAction", + "(Landroid/webkit/WebView;I)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, htmlAction, handle, action); + } } /* * Render raw HTML code in the embedded HTML widget.. * Parameters: * handle: Handle to the window. - * string: String buffer containt HTML code to + * string: String buffer containing HTML code to * be rendered. * Returns: * DW_ERROR_NONE (0) on success. */ int API dw_html_raw(HWND handle, const char *string) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a String + jstring jstr = env->NewStringUTF(string); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlRaw = env->GetMethodID(clazz, "htmlRaw", + "(Landroid/webkit/WebView;Ljava/lang/String;)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, htmlRaw, handle, jstr); + return DW_ERROR_NONE; + } return DW_ERROR_GENERAL; } @@ -2817,6 +2854,21 @@ */ int API dw_html_url(HWND handle, const char *url) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a String + jstring jstr = env->NewStringUTF(url); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlLoadURL = env->GetMethodID(clazz, "htmlLoadURL", + "(Landroid/webkit/WebView;Ljava/lang/String;)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, htmlLoadURL, handle, jstr); + return DW_ERROR_NONE; + } return DW_ERROR_GENERAL; } @@ -2832,6 +2884,21 @@ */ int API dw_html_javascript_run(HWND handle, const char *script, void *scriptdata) { + JNIEnv *env; + + if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a String + jstring jstr = env->NewStringUTF(script); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlJavascriptRun = env->GetMethodID(clazz, "htmlJavascriptRun", + "(Landroid/webkit/WebView;Ljava/lang/String;J)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, htmlJavascriptRun, handle, jstr, (jlong)scriptdata); + return DW_ERROR_NONE; + } return DW_ERROR_UNKNOWN; } @@ -2844,6 +2911,19 @@ */ HWND API dw_html_new(unsigned long cid) { + JNIEnv *env; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID htmlNew = env->GetMethodID(clazz, "htmlNew", + "(I)Landroid/webkit/WebView;"); + // Call the method on the object + jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, htmlNew, (int)cid)); + return result; + } return 0; }