I'm trying to build an ane who take an empty bitmap
bitmapData = new BitmapData(size.width,size.height,false, 0x00000000);
acquire it, edit the bytebuffer in a different thread then release it.
Here's the call function code in the java part
public FREObject call(FREContext freContext, FREObject[] args) {
try {
FREBitmapData bitmapData = (FREBitmapData)args[0];
bitmapData.acquire();
ByteBuffer bytebuffer =
myTaskProcessingQueue.put(new Task(freContext,bitmapData,bytebuffer)); //edit the bitmap data in a specific thread
} catch (InterruptedException e) {
Log.e(TAG, "exception", e);
} catch (FREInvalidObjectException e) {
Log.e(TAG, "exception", e);
} catch (FREWrongThreadException e) {
Log.e(TAG, "exception", e);
}
return null;
}
And when I'm done with the bytebuffer :
new Handler(Looper.getMainLooper()).post(new Runnable () {
@Override
public void run () {
try {
Toast.makeText(task.context.getActivity(),"Toast",Toast.LENGTH_SHORT).show();
task.bitmapData.release();
} catch (FREInvalidObjectException e) {
Log.e("InitExtractorFunction", "FREInvalidObjectException", e);
} catch (FREWrongThreadException e) {
Log.e(TAG, "exception", e);
}
}
});
The toast instruction works fine, but the bitmapData.release() one throws a FREWrongThreadException even though I am on the main thread, and I can't find any documentation about this exception on the adobe website.
Any idea?
Edit :
Here's more code for the thread class where i'm editing the data :
private class MyTaskWorker extends Thread {
@Override
public void run() {
while (true) {
try {
processMyTask(myTaskProcessingQueue.take());
} catch (InterruptedException e) {
Log.e(TAG,"InterruptedException", e);
}
}
}
private void processMyTask(Task task) {
// do work with bytebuffer
new Handler(Looper.getMainLooper()).post(new Runnable () {
@Override
public void run () {
try {
Log.d(TAG, "Thread: " + Thread.currentThread().getName());
Toast.makeText(task.context.getActivity(),"Toast",Toast.LENGTH_SHORT).show();
task.bitmapData.release();
Log.i(TAG,"bitmap released");
} catch (FREInvalidObjectException e) {
Log.e(TAG, "FREInvalidObjectException", e);
} catch (FREWrongThreadException e) {
Log.e(TAG,"FREWrongThreadException", e);
}
}
});
}
}
Edit 2 :
I also tried to do both the acquire and the relase in the same background thread and still no dice. The only way I managed to make it work is when I do both the acquire and the release inside the call function, but I don't want to block the main thread to wait for the bitmap modification...
Just like regular multithreading, whenever you
acquirea lock, it must be released by the same thread who locked it.The documentation for this exception has the following description:
Thus when
call()is called from a background thread, the background thread is the one that locksbitmapData, which means the main thread does not own the lock to release it later.You can always test this by logging the thread name in each location:
The solution will be to ensure that the
release()method is invoked from the same place (thread) ascall()(wherever this may be)