当前位置: 首页 > 知识库问答 >
问题:

在Android中使用WebView实现JavascriptInterface的最佳实践?

戈念
2023-03-14

我有一个相同错误的崩溃报告,就像这个问题中的一样:同一线程上的WebView方法错误

建议创建Runnable()。

我不明白为什么这能解决问题。该错误表示相同线程上的Webview方法,但答案建议在UI-Thread(主线程)上创建该方法。但是UI-Thread不是唯一的线程吗?有人能详细解释整个过程吗(考虑到我在构造函数的每个活动中创建了一个新的Webview)?

实现Javascript函数/方法的代码如下:

public class JS_Bind {
    private static final String TAG = "JS_Bind";
    private Context context;
    private AdvancedWebView mWebView;

    public JS_Bind(Context c, AdvancedWebView mWebView) {
        context = c;
        this.mWebView = mWebView;
    }
    @JavascriptInterface
    public void openActivity(String activityName) {
        try {
            Class activityClass = Class.forName(PACKAGE_NAME + "." + activityName);
            context.startActivity(new Intent(MainActivity.this, activityClass));
        } catch (ClassNotFoundException e) {
            Toast.makeText(context, "Invalid activity name: " + activityName, Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
    @JavascriptInterface
    public void makeToast(String toast) {
        Toast mToast = Toast.makeText(context, toast, Toast.LENGTH_SHORT);
        mToast.setGravity(Gravity.CENTER, 0, 0);
        mToast.show();
    }
    @JavascriptInterface
    public void external(String url) {
        mTracker.send(new HitBuilders.EventBuilder().setCategory("Action").setAction("External Link: " + url).build());
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }
    @JavascriptInterface
    public String showToken() {
        return gcmToken;
    }
    @JavascriptInterface
    public int showUid() {
        SharedPreferences pref = getSharedPreferences("Pref", Activity.MODE_PRIVATE);
        int uid = pref.getInt("uid", 0);
        return uid;
    }
    @JavascriptInterface
    public void buyPremium() {
        bp.purchase(MainActivity.this, PRODUCT_ID);
    }
}

我是否必须将EVERY函数更改为此代码(在我引用的问题中的第一个答案):

@JavascriptInterface
    mWebView.post(new Runnable() {
        @Override
        public void makeToast() {
          // ...
        }
    });

顺便说一下,这就是我在构造函数activiesonCreate方法中创建webview的方式:

mWebView = (AdvancedWebView) findViewById(R.id.webView);
mWebView.setListener(this, this);
mWebView.addJavascriptInterface(new JS_Bind(this, mWebView), "Android");
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

if (!DetectConnection.checkInternetConnection(this)) {
    mWebView.loadUrl("file:///android_asset/offline.html");
}
else {
        mWebView.loadUrl("http://example.com/tw3/index.php?s=home");
}

共有1个答案

索瀚海
2023-03-14

但是UI线程不是唯一的线程吗?

没有。WebView有自己的线程池。Android应用程序中可以有许多其他线程。

我是否必须将每个函数都更改为该代码

不一定。

首先,我看不出您是如何从上面显示的@JavascriptInterface方法中得到该错误的(在线程“JavaBridge”上调用了WebView方法。所有WebView方法必须在同一线程上调用。)。当您在WebView本身上调用一个方法时,就会出现此错误,而您没有这样做。

在以下情况下,您需要使用runOnUiThread()(或等效技术):

>

  • 您的@JavascriptInterface方法引用了WebView本身,或者

    您的@JavascriptInterface尝试在主应用程序线程上执行其他操作(这将产生不同的错误消息,因为它不会专门绑定到WebView

    您的startActivity()调用可能需要在主应用程序线程上调用-我忘了这是否可以在后台线程上调用。与你的Toast工作类似——虽然我认为这可以在后台线程上完成,但我不确定。我已经很久没有尝试过在后台线程中做这些事情了。

    此外,如果您控制网络视图中显示内容的每个字节,请仅使用您的代码。向任意Web内容公开startActivity()。

  •  类似资料:
    • 问题内容: 我打算通过此库在android中实现Socket.io,用于基于聊天的应用程序。据我了解,该图书馆似乎还不错。我想知道如何始终保持整个应用程序中的 单个 套接字连接吗?在这里,我列出了实现的方法,其中我需要最好和稳定的方法。 三种方式 MainApplication 类扩展 应用程序 这样,我们就可以在 主线程 (或应用程序的生命周期)中维护套接字连接,并且只要活动需要套接字实例,我们

    • 问题内容: 假设我们有一个活动,该活动有很多视图要注册。 最常见的实现方法是让Activity-Subclass实现OnClickListener,如下所示: 我喜欢实现它的方式是在Activity-Subclass内部创建一个私有类,并让该内部类实现OnClickListener: 这样,代码看起来更加井井有条,易于维护。 此外,在谈论“ Is-a”,“ Has-a”关系时,后者似乎是一个好习惯

    • 我目前正在改进一些旧的uni分配,将它们从可序列化文件转移到任何其他形式的存储,主要是SQL数据库。我理解关系数据库设计的概念以及与OOP类的相似之处,但是,我不完全确定如何从OOP设计的角度来处理这个问题。 现在我有一个酒店类,房间列表为属性,每个房间都有一个客人列表为属性(此处为完整代码) 回到使用文件时,我可以用Serializable接口标记这些类,并将父对象存储在单个文件中。但是当使用关

    • 问题内容: 我开发Joomla网站/组件/模块和插件,并且每隔一段时间我都需要使用JavaScript来加载页面时触发事件的功能。在大多数情况下,这是使用函数完成的。 我的问题是: 这是在页面加载时触发JavaScript事件的最佳方法,还是有更好/更新的方法? 如果这是触发页面加载事件的唯一方法,那么确保多个事件可以由不同的脚本运行的最佳方法是什么? 问题答案: 可以,但是您可能已经注意到, 它

    • 本文向大家介绍Android实现webview实例代码,包括了Android实现webview实例代码的使用技巧和注意事项,需要的朋友参考一下 webview是一个很简单的功能,代码没有什么逻辑上的难度,只是需要注意权限上的问题。其实在安卓编程的过程当中,权限问题可以算是出现的比较多的BUG。 1.MainAct 2.最重要的是在manifest中添加权限,否则是无法显示的。 以上就是本文的全部内

    • 问题内容: 我(使用Java)正在研究一种递归图像处理算法,该算法以递归方式从中心点向外遍历图像的像素。 不幸的是,这会导致堆栈溢出。因此,我决定切换到基于队列的算法。 现在,这一切都很好而且很花哨- 但考虑到以下事实:它的队列将在非常短的时间内分析成千上万个像素,同时不断弹出并推动,而不会保持可预测的状态(长度可能在100到100之间,和20000),则队列实现需要具有显着的快速弹出和推送功能。