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

时间:2015-02-07 01:13:22

标签: android cordova phonegap-plugins

我已经编写了一个Cordova插件,可以在Android上对图像进行图像重新调整大小,但UI会在翻阅大量图像(超过100)时锁定,直到翻阅停止。我在theadPool上执行所有调整大小,最初只有一个可运行的,但在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对象除外。有没有办法看到导致速度减慢或阻塞主线程的原因?

1 个答案:

答案 0 :(得分:2)

您可以尝试使用以下代码,它使用最小AsyncTask来运行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;
    }
}

注意:这未经过测试,代码就是为了说明这些想法。