Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread/Handler error - The specified message queue synchronization barrier token has not been posted

I am getting this error -

java.lang.IllegalStateException: The specified message queue synchronization barrier token has not been posted or has already been removed.

As a relative newcomer to Java/Android, there is no doubt something I have missed, but what I am doing is this -

I have a project which uses Exif Data to display Photos according to the date they were taken, and the intention is to use a similar model on each stage...

Worker Thread -> UI Thread -> Custom Display Adapter. Then clicking on one of the "Cells" in GridView triggers the next Activity. The First Activity searches for all the Photo Files, creating a list of "Years", and then each subsequent activity filters it to months, days etc.

Starting the second activity however launches straight into the above error, and the Messages are dealt with via the basic Thread/Handler set-up.

Here is the class that is passing the messages to the thread -

public class MonthSort {
Handler handler;
int imageWidth;
List<PhotoData> photoList;
public MonthSort(Handler handler2, int width, List<PhotoData> pList) {
    photoList = new ArrayList<PhotoData>();
    photoList = pList;
    imageWidth = width;
    handler = handler2;
}

public void sortFiles()
{
    int month, photoCount;
    File fileName = new File("");
    Message msg = handler.obtainMessage();
    //Message msg = Message.obtain();
    //Bundle bundle = new Bundle();
    try {
        for (int i = 0; i < 12; i++) {
            month = i + 1;
            photoCount = 0;
            for (PhotoData pd : photoList) {
                if(month == pd.month)
                {
                    if(photoCount == 0)
                        fileName = pd.fileName;
                    photoCount++;
                }
            }
            if(photoCount != 0)
            {

                Bundle bundle = new Bundle();
                bundle.putString("filename", fileName.toString());
                bundle.putInt("month", month);
                bundle.putInt("count", photoCount);
                byte[] thumbNail = getThumbnail(fileName, imageWidth);
                bundle.putByteArray("thumbnail", thumbNail);


                msg.setData(bundle);
                handler.sendMessage(msg);

            }
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        Log.d("Debug", "handler error occurs in monthSort class");
    }
    /*Bundle bundle = new Bundle();
    bundle.putBoolean("end", true);
    msg.setData(bundle);
    handler.sendMessage(msg);*/
}

... and this is the code that receives it in the UI Thread.

public class MonthActivity extends Activity {
List<PhotoData> photoList;
static List<MonthData> photos;
int imageWidth;
GridView photoGrid;
static ImageAdapter2 iAdapter;
int year;
Thread monthSortThread;

Handler handler2 = new Handler() {
    @Override
    public void handleMessage(Message msg) 
    {
        Bundle bundle = msg.getData();  // Get the message sent to the Handler.
        boolean ended = bundle.getBoolean("end");
        if(ended)
        {
            //Toast.makeText(getBaseContext(), "FINISHED !!!", Toast.LENGTH_LONG).show();
        } else
        {
            try {
                MonthData md = new MonthData();
                md.monthValue = bundle.getInt("month");
                md.monthString = getMonthString(md.monthValue);
                md.count = bundle.getInt("count");
                byte[] tn = bundle.getByteArray("thumbnail");
                md.thumbnail =  BitmapFactory.decodeByteArray(tn, 0, tn.length);
                photos.add(md);
                iAdapter.notifyDataSetChanged();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Log.d("Debug", "handler error occurs in UI Handler");
            }
        }
    }
};

Please note that I haven't included all of the code, just the parts I feel are relevant.

The previous activity managed to successfully operate messages in the same way, why not the second activity ?

I understand that the Main UI thread already has a looper set-up, and therefore you don't have to create one. Is that still true of any subsequent Activities that are launched ?

like image 888
Douglas Brett Avatar asked Apr 07 '13 22:04

Douglas Brett


2 Answers

The problem was solved by using the Handler's dispatchMessage method, instead of sendMessage.

like image 53
Douglas Brett Avatar answered Nov 06 '22 20:11

Douglas Brett


I got the same problem as you did here. After two days' struggle, I found a way to solve it. It is simple. Just add this.obtainMessage() in your handlerMessage() before updating any UI. After doing this, everything will be fine now.

I guess it was because we are communicating between UI thread and background thread too quickly in which situation the Android system can not dispatch Msg properly all by itself. When we force Android to do so, problem solved. I am not sure, it's just a guess. I hope it can help you.

like image 31
Erwin.H Avatar answered Nov 06 '22 18:11

Erwin.H