处理程序和runnable之间的消息传递不一致

时间:2014-11-27 14:59:06

标签: android multithreading runnable android-handler

我正在尝试通过Handler从后台线程更新UI。 Runnable定期发送(最少每两秒一次,每秒最多16次)新数据到处理程序进行更新。在我的runnable类中,我有一个用于启动/停止循环的标志 - 主要类的方法附加到此任务的按钮 - 。

我有几个问题:

  1. 收到的第一条消息始终为0
  2. 经过几次循环后,处理程序收到的消息始终为0
  3. 不时(抱歉,精确度差,我知道),按停止会产生IllegalStateException。这是代码(简化):
  4. 主要活动:

    public class MainActivity extends Activity
    {
    
        OtherClass otherObbject;
        Thread otherClassThread;
        Handler handler;
        TextView txtBeat;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            txtBeat = (TextView) findViewById(R.id.txtBeat);
    
            handler = new Handler()
            {
                int beat;
    
                @Override
                public void handleMessage(Message msg)
                {
                    msg = this.obtainMessage();
                    beat = msg.getData().getInt("beat");
                    txtBeat.setText(String.valueOf(beat));
                }
            };
        }
    
        public void onPlay(View v)
        {
            otherObbject = new OtherClass(handler);
            otherClassThread = new Thread(otherObbject);
            otherObbject.start();
            otherClassThread.start();
        }
    
        public void onStop(View v)
        {
            otherObbject.stop();
        }
    
    }
    

    Runnable类:

    public class OtherClass implements Runnable
    {
        private Boolean isPlaying;
        private Handler mHandler;
        private int beatMaximum;
        private long waitTime;
        private long maxWait;
    
        public OtherClass(Handler handler)
        {
            isPlaying = false;
            mHandler = handler;
            beatMaximum = 4;
            waitTime = 30;
            maxWait = 500;
        }
    
        @Override
        public void run()
        {
            int counter = 0;
            int beat = 1;
            Bundle bundle = new Bundle();
            Message msg = new Message();
    
            while (isPlaying)
            {
                if(counter == 0)
                {
                    //Do some stuff
    
                    System.out.println(beat);
                    bundle.putInt("beat", beat);
                    msg.setData(bundle);
                    mHandler.sendMessage(msg);
    
                    if (beat == beatMaximum)
                        beat = 1;
                    else
                        beat++;
                }
                else
                    waitThread();
    
                if ((counter += waitTime) >= maxWait)
                    counter = 0;
            }
        }
    
        private void waitThread()
        {
    
            try
            {
                Thread.currentThread().sleep(waitTime);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    
        public void start()
        {
            isPlaying = true;
        }
    
        public void stop()
        {
            isPlaying = false;
        }
    }
    

    例外:

    FATAL EXCEPTION: main
    java.lang.IllegalStateException: The specified message queue synchronization  barrier token has not been posted or has already been removed.
            at android.os.MessageQueue.removeSyncBarrier(MessageQueue.java:266)
            at android.os.Looper.removeSyncBarrier(Looper.java:242)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:990)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
            at android.view.Choreographer.doCallbacks(Choreographer.java:555)
            at android.view.Choreographer.doFrame(Choreographer.java:525)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
    

    我几天都遇到这些问题了。我没有尝试过AsyncTask,因为它可以运行几分钟,而且来自Google documentation

      

    理想情况下,AsyncTasks应该用于短操作(最多几秒钟。)

    感谢您的时间。

0 个答案:

没有答案