【问题标题】:Unable to update seekbar with Handler无法使用 Handler 更新搜索栏
【发布时间】:2014-12-03 05:52:29
【问题描述】:

我正在尝试根据 MediaPlayer 中歌曲的进度更新搜索栏。 我正在使用 Thread 来完成这项任务。

首先我在线程内部使用了 Thred 并尝试更新 UI,但它使应用程序崩溃并说只有原始线程可以附加到视图。

然后我尝试使用可运行线程内的处理程序对其进行更新。这工作正常,但它没有更新搜索栏。当我做日志时,我才知道循环不会进入我的处理程序。我不知道问题出在哪里。请帮我更新 SeekBar。

代码:

private Runnable mUpdateTimeTask = new Runnable() {
    public void run() {
        try {
            if ((musicPath != mIRemoteService.getPath())) {
                System.out.println("..... MUSIC CHANGE.....");
                setOrUpdateData();
                updateFragmentLayout();     

            }

            // Displaying Current Duration time/Progress

            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    try {
                        songCurrentDurationLabel.setText(""+ Utilities.milliSecondsToTimer(mIRemoteService.position()));
                        songProgressBar.setProgress((int)mIRemoteService.position());
                        System.out.println("Runnnnn.........");
                        //songProgressBar.invalidate();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                        System.out.println("Runnnnn......... EXCEPTION....");
                    }

                }
            });
            System.out.println("Runnnnn.........MAIN....");

            if (!(mIRemoteService.isPlayerRunning())) {
                btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.play_now_playing));
                mHandler.removeCallbacks(mUpdateTimeTask);
                System.out.println("Runnnnn.........MAIN....IF");

            }else{
                System.out.println("Runnnnn.........MAIN....ELSE");
                mHandler.post(mUpdateTimeTask);     
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

【问题讨论】:

  • 您是否遇到任何错误?如果不放一些日志,看看代码的流程是什么,是否卡在某个地方或者没有进入if语句
  • @GoranHoriaMihail 如果我使用 Thread 代替 Handler,那么我得到错误“只有创建视图层次结构的原始线程才能触及其视图。”
  • 是的,除了 UI 线程之外,您不能触摸来自其他线程的任何视图。处理程序将在 UI 线程上发布修改,这就是它起作用的原因,是的,您应该使用处理程序。现在使用 handler 时出现什么错误/问题?
  • @GoranHoriaMihail 问题是,我的 seekBar 没有更新进度。然后我检查了日志,我开始知道线程没有按应有的方式调用......我只得到一次日志......然后什么也没有发生......
  • @GoranHoriaMihail 我们可以在 SO 上聊天吗?

标签: android android-view ui-thread android-runonuithread


【解决方案1】:

您可以使用处理程序或线程,您应该确保在 UI 线程上发布修改:

private class UpdateSeekBar extends Thread
{
    @Override
    public void run()
    {
        super.run();

        while (null != mp && mp.isPlaying() && this.isAlive())
        {
            //final int min = (mp.getCurrentPosition() / 1000) / 60;
            //final int sec = (mp.getCurrentPosition() / 1000) % 60;

            MainActivity.this.runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    try
                    {
                        songCurrentDurationLabel.setText("" + Utilities.milliSecondsToTimer(mIRemoteService.position()));
                        songProgressBar.setProgress((int) mIRemoteService.position());
                        System.out.println("Runnnnn.........");
                        // songProgressBar.invalidate();
                    }
                    catch (RemoteException e)
                    {
                        e.printStackTrace();
                        System.out.println("Runnnnn......... EXCEPTION....");
                    }
                }
            });

            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

【讨论】:

  • 感谢您的回答。你能告诉我如何使它顺利。我的意思是现在它每 1 秒更新一次。现在我删除 Thread.Sleep(1000) 然后它会运行得非常快速和流畅,并且它也会挂起其他 UI。
  • 现在搜索栏每秒更新 1 次。你可以试试 Thread.Sleep(500) 看看效果更好。
  • 您的答案是完美的工作和更新进度条。但是有一些事情发生在 UI 线程上。因为它影响了我的其他 UI 部分。如果播放器处于播放状态,我将无法顺利工作。如果播放器处于暂停状态意味着当时没有线程在运行,那么在这种情况下所有 UI 都可以正常工作......你知道是什么导致了这个问题......?
  • 我想说不要太频繁地更新进度条。它可以挂起ui线程。 500 - 1000 毫秒之间的 Thread.sleep() 应该是安全的。您使用的是什么值?
  • 感谢您的支持。现在我通过 50 只是为了测试,但即使它阻塞了我的 UI 线程。在它运行平稳之前。我只想知道 UI 上正在运行哪个其他线程。再次感谢...
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
相关资源
最近更新 更多