Android Cordova插件即使使用线程池仍会锁定UI线程

3
我编写了一个 Cordova 插件,用于在 Android 上调整图像大小,但是当浏览大量图像(超过 100 张)时,界面会锁定,直到浏览结束。我正在使用线程池执行所有的缩放操作,最初只是使用 Runnable,但是在阅读了这篇博客文章 Cordova Plugins and Thread Blocking 后,我切换到一个外部类来进行操作。然而,我仍然遇到以下问题:
W/PluginManager﹕ THREAD WARNING: exec() call to ImageStore.getImage blocked the main thread for 91ms. Plugin should use CordovaInterface.getThreadPool().

每次调整大小图像时,调用看起来像这样:

private boolean getImage(final JSONArray args, final CallbackContext callbackContext) throws JSONException {

    JSONObject argObject = args.getJSONObject(0);

    int photoId = argObject.getInt("photoId");
    final PhotoData photoData = mPhotos.get(photoId);

    cordova.getThreadPool().execute(new GetImageRunnable(photoData, callbackContext));

    return true;
}

GetImageRunnable没有与主插件有任何链接,除了传入的photoData对象。有没有办法查看是什么导致了减速或阻塞了主线程?


我建议尝试使用AsyncTask并忽略CordovaInterface似乎存在问题的功能(其他人似乎也遇到了这个问题)。 - vbence
@vbence 把这个作为答案,如果可能的话提供一些例子,我会标记它为已接受... - Kris Erickson
1个回答

2
您可以尝试使用下面的代码,它使用了一个简单的异步任务来运行GetImageRunnable:
private boolean getImage(final JSONArray args, final CallbackContext callbackContext) throws JSONException {

    JSONObject argObject = args.getJSONObject(0);

    int photoId = argObject.getInt("photoId");
    final PhotoData photoData = mPhotos.get(photoId);

    (new MyTask(photoData, callbackContext)).execute();

    return true;
}

private class MyTask extends AsyncTask<Void, Void, Void> {

    private PhotoData mPhotoData;
    private CallbackContext mCallbackContext;

    public MyTask(PhotoData photoData, CallbackContext callbackContext) {
        mPhotoData = photoData
        mCallbackContext = callbackContext;
    }

    protected Void doInBackground(Void... v) {
        (new GetImageRunnable(photoData, callbackContext)).run();
        return null;
    }

    protected void onProgressUpdate(Void... v) {
    }

    protected void onPostExecute(Void v) {
    }
}

然而,它还有待完善;回调将在后台线程中运行。如果您需要在主线程中运行它,可以掩盖初始的CallbackContext(它不是最终版本),并将结果传递给onPostExecute中的原始回调:

private boolean getImage(final JSONArray args, final CallbackContext callbackContext) throws JSONException {

    JSONObject argObject = args.getJSONObject(0);

    int photoId = argObject.getInt("photoId");
    final PhotoData photoData = mPhotos.get(photoId);

    (new MyTask(photoData, callbackContext)).execute();

    return true;
}

private class MyTask extends AsyncTask<Void, Void, Void> {

    private PhotoData mPhotoData;
    private CallbackContext mCallbackContext;
    private CallbackContext mMaskedContext;

    public MyTask(PhotoData photoData, CallbackContext callbackContext) {
        mPhotoData = photoData
        mCallbackContext = callbackContext;
        mMaskedContext = new MyCallbackContext(callbackContext);
    }

    protected Void doInBackground(Void... v) {
        (new GetImageRunnable(photoData, mMaskedContext)).run();
        return null;
    }

    protected void onProgressUpdate(Void... v) {
    }

    protected void onPostExecute(Void v) {
        mCallbackContext.sendPluginResult(mMaskedContext.getPluginResult());
    }
}

class MyCallbackContext extends CallbackContext {
    private CallbackContext mOriginalContext;
    private PluginResult mPluginResult;

    public MyCallbackContext(CallbackContext originalContext) {
        super(originalContext.getCallbackId(), null);
        mOriginalContext = originalContext;
    }

    public void sendPluginResult(PluginResult pluginResult) {
        mPluginResult = pluginResult;
    }

    public pluginResult getPluginResult() {
        return mPluginResult;
    }
}

注意:这并未经过测试,代码仅用于说明思路。


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