Cordova Exec即使使用了CordovaInterface.getThreadPool()仍会阻塞主线程

7
我收到以下警告:
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
@Fabii 我不确定,但可能是函数调用。对我来说,48毫秒甚至对于生成Threadpool来说都很多。 - snaggs
啊,我明白了。我也遇到了同样的问题,不过那只是一个警告。如果我找到任何可行的解决方案,我会告诉你的。 - Fabii
在这里遇到同样的问题,即使使用cordova.getThreadPool()也会收到警告。 - jcesarmobile
3个回答

7
根据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 你修改了什么?我没看到。 - Christian
我找到了解决方案:https://github.com/katzer/cordova-plugin-background-mode/issues/578 - Santiago Vasquez

0

参考来源

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


0

你必须使用:

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

的替代方案:

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

4
在执行此操作时要小心,这将阻塞UI线程..."如果您不需要在UI线程上运行,但也不希望阻塞WebCore线程,则应使用通过cordova.getThreadPool()获取的Cordova ExecutorService来执行代码。" - sMyles
经过紧张的调试,我成功提取了以下错误日志:线程警告:对UniversalAnalytics.startTrackerWithId的exec()调用阻塞了主线程34毫秒。插件应该使用CordovaInterface.getThreadPool()。和线程警告:对OneSignalPush.init的exec()调用阻塞了主线程64毫秒。插件应该使用CordovaInterface.getThreadPool()。我想知道是什么导致了应用程序的冻结和无响应,以及这是否与您的查询有关。您是否想到了可能的解决方法?谢谢 - MBC870
2023年1月了,安卓端仍然存在这个问题。有解决方案吗? https://github.com/katzer/cordova-plugin-background-mode/issues/578 - Santiago Vasquez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接