【问题标题】:Cordova Exec blocked the main thread even after usage of CordovaInterface.getThreadPool()即使在使用 CordovaInterface.getThreadPool() 之后,Cordova Exec 也会阻塞主线程
【发布时间】:2014-08-26 14:35:33
【问题描述】:

我收到以下警告:

THREAD WARNING: exec()
 call to MyPlugin.setAndroidPreferences blocked the main thread for 49ms.   
Plugin should use CordovaInterface.getThreadPool().

但是从我的代码中我使用cordova.getThreadPool()

private boolean setAndroidPreferences(
        final JSONArray args,
        final CallbackContext callbackContext)
{
    cordova.getThreadPool().execute(new Runnable() {
        @Override
        public void run() {
            try {
                /* ... */

                if ( /* ... */) 
                {
                    final SharedPreferences settings = cordova.getActivity().getSharedPreferences(preferenceLib, Context.MODE_PRIVATE);
                    final SharedPreferences.Editor editor = settings.edit();

                    editor.putString(preferenceName, preferenceValue);
                    editor.commit();
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));                     
                } else {                                                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR));
                }
            } catch (JSONException e) {
                e.printStackTrace();
                Log.e(TAG, "getSetSharePreferences" + ": Error: " + PluginResult.Status.JSON_EXCEPTION);
                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
            }
        }
    });
    return true;
}

我做错了什么?

谢谢,

【问题讨论】:

  • 你能解决这个问题吗?
  • @Fabii 我不知道,但它可能是函数调用。对我来说 48 毫秒甚至对于生成线程池来说也是很多
  • 啊,我明白了,我遇到了同样的问题,这更像是一个警告;如果我遇到任何可行的解决方案,我会告诉你。
  • 同样的问题,即使使用 cordova.getThreadPool() 也会收到警告

标签: android cordova


【解决方案1】:

根据THREAD WARNING: exec() call blocked the main thread. Plugin should use CordovaInterface.getThreadPool(). – Cordova Plugin Warning,尝试以下操作:

    public boolean execute(String action, final JSONArray inputs, final CallbackContext callbackContext) throws JSONException {
        if (action.equals("setAndroidPreferences")) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    callbackContext.sendPluginResult(setAndroidPreferences(inputs));
                }
            });
        }
    }

    private PluginResult setAndroidPreferences(JSONArray args) {
        try {
            if ( /* ... */) {
                SharedPreferences settings = cordova.getActivity().getSharedPreferences(preferenceLib, Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = settings.edit();

                editor.putString(preferenceName, preferenceValue);
                editor.commit();
                return new PluginResult(PluginResult.Status.OK);                     
            } else {
                return new PluginResult(PluginResult.Status.ERROR);
            }
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e(TAG, "getSetSharePreferences" + ": Error: " + PluginResult.Status.JSON_EXCEPTION);
            return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
        }
    }
}

【讨论】:

  • @PaulFacklam 你做了什么改变?我只是没看到。
【解决方案2】:

reference source

这是一个已知的不重要的 cordova 警告,它告诉插件用户, 应该在后台线程中调用所有慢于 50 毫秒的东西。 OCI SDK 没有使用cordova 线程池, 相反,它使用了一个后台工作线程,该线程已更改为 ExecutorTask 以供将来发布。 您的异步 connect() 调用已在后台线程中执行,因此它不应阻塞您的浏览器线程。 但是 OCI 插件(Java VM)的初始化和加载机制可能是短时间阻塞的原因。 我们添加此问题是为了详细调查阻止原因 所以我们可以防止科尔多瓦在未来认识到这种短暂的挂起情况。 您无法在代码中阻止此警告,而必须忽略该警告。

【讨论】:

    【解决方案3】:

    你必须使用:

    this.cordova.getActivity().runOnUiThread(new Runnable() {...}
    

    代替:

    cordova.getThreadPool().execute(new Runnable() {...}
    

    【讨论】:

    • 这样做要小心,这会阻塞 UI 线程... "如果你不需要在 UI 线程上运行,但也不希望阻塞 WebCore 线程,你应该执行您的代码使用通过 cordova.getThreadPool() "cordova.apache.org/docs/en/latest/guide/platforms/android/… 获得的 Cordova ExecutorService
    • 经过密集调试后,我设法提取了以下错误日志:线程警告:对 UniversalAnalytics.startTrackerWithId 的 exec() 调用阻塞了主线程 34 毫秒。插件应该使用 CordovaInterface.getThreadPool()。和线程警告:对 OneSignalPush.init 的 exec() 调用阻塞了主线程 64 毫秒。插件应该使用 CordovaInterface.getThreadPool()。我想知道是什么导致了应用程序的冻结和无响应,以及这是否与您的查询有关。您是否想出了解决此问题的可能方法?谢谢
    猜你喜欢
    • 2013-08-10
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2016-11-29
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多