Reputation: 25
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...
Upvotes: 0
Views: 60
Reputation: 21733
Just like regular multithreading, whenever you acquire
a lock, it must be released by the same thread who locked it.
The documentation for this exception has the following description:
FRE_WRONG_THREAD The method was called from a thread other than the one on which the runtime has an outstanding call to a native extension function.
Thus when call()
is called from a background thread, the background thread is the one that locks bitmapData
, 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:
Log.d(..., "Thread: " + Thread.currentThread().getName());
The solution will be to ensure that the release()
method is invoked from the same place (thread) as call()
(wherever this may be)
Upvotes: 0