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

Android Cordova Plugin locks UI thread even though Thread Pool is used

我写了一个 Cordova 插件,可以在 Android 上调整图像大小,但是 UI 在翻动大量图像(超过 100 张)时锁定,直到翻动停止.我正在对 theadPool 执行所有大小调整,最初只有一个可运行的,但在 Cordova Plugins and Thread Blocking 上阅读这篇博客 post 后,我切换到外部 class 来完成这项工作。但是我仍然得到:

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;
}

除了传入的 photoData 对象,GetImageRunnable 没有指向主插件的链接。有什么方法可以查看是什么导致了速度变慢或阻塞了主线程?

你可以试试下面的代码,它使用最小的 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;
    }
}

注意:这没有经过测试,代码只是为了说明思路。