简体   繁体   English

线程/处理程序错误 - 尚未发布指定的消息队列同步屏障标记

[英]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. java.lang.IllegalStateException:指定的消息队列同步障碍标记尚未发布或已被删除。

As a relative newcomer to Java/Android, there is no doubt something I have missed, but what I am doing is this - 作为Java / Android的相对新手,毫无疑问我错过了一些东西,但我正在做的是这个 -

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... 我有一个项目使用Exif数据根据拍摄日期显示照片,目的是在每个舞台上使用类似的模型......

Worker Thread -> UI Thread -> Custom Display Adapter. 工作线程 - > UI线程 - >自定义显示适配器。 Then clicking on one of the "Cells" in GridView triggers the next Activity. 然后单击GridView中的一个“单元格”将触发下一个活动。 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. ...这是在UI线程中接收它的代码。

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. 我知道主UI线程已经有一个looper设置,因此你不必创建一个。 Is that still true of any subsequent Activities that are launched ? 是否仍然适用于任何后续活动?

通过使用Handler的dispatchMessage方法而不是sendMessage解决了该问题。

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. 只需在更新任何UI之前在handlerMessage()中添加this.obtainMessage()。 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. 我想这是因为我们在UI线程和后台线程之间进行了太快的沟通,在这种情况下Android系统无法自行调度Msg。 When we force Android to do so, problem solved. 当我们强制Android这样做时,问题就解决了。 I am not sure, it's just a guess. 我不确定,这只是猜测。 I hope it can help you. 我希望它可以帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM