2015-02-07 2 views
3

Я написал плагин Cordova, который выполняет повторное масштабирование изображений на Android, но пользовательский интерфейс блокируется при просмотре большого количества изображений (более 100), пока останавливается. Я выполняю все изменения размера на theadPool, изначально с просто исполняемым, но после прочтения этого сообщения в блоге по Cordova Plugins and Thread Blocking я переключился на внешний класс, чтобы выполнить эту работу. Однако я все еще получаю:Android Cordova Plugin блокирует нить пользовательского интерфейса, хотя используется пул потоков

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, который передается в Is есть ли способ увидеть, что вызывает замедление или блокирование основного потока?

+0

Я бы попытался использовать AsyncTask и игнорировать, казалось бы, неподходящую функциональность CordovaInterface. (У других, похоже, тоже есть эта проблема). – vbence

+0

@vbence добавьте это как ответ, и, если возможно, представите какой-то пример, и я помечаю его как принятый ... –

ответ

1

Вы можете дать следующий код попробовать, он использует минимальное 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; 
    } 
} 

Примечание: Это не проверенный, код есть только для иллюстрации идей.

Смежные вопросы