为了账号安全,请及时绑定邮箱和手机立即绑定

Android“只有创建视图层次结构的原始线程才能触及其视图。

Android“只有创建视图层次结构的原始线程才能触及其视图。

皈依舞 2019-05-30 13:10:31
Android“只有创建视图层次结构的原始线程才能触及其视图。我用Android制作了一个简单的音乐播放器。每首歌的视图包含一个SeekBar,实现方式如下:public class Song extends Activity implements OnClickListener,Runnable {     private SeekBar progress;     private MediaPlayer mp;     // ...     private ServiceConnection onService = new ServiceConnection() {           public void onServiceConnected(ComponentName className,             IBinder rawBinder) {               appService = ((MPService.LocalBinder)rawBinder).getService(); // service that handles the MediaPlayer               progress.setVisibility(SeekBar.VISIBLE);               progress.setProgress(0);               mp = appService.getMP();               appService.playSong(title);               progress.setMax(mp.getDuration());               new Thread(Song.this).start();           }           public void onServiceDisconnected(ComponentName classname) {               appService = null;           }     };这个很好用。现在我要一个计时器来计算这首歌的进度的秒/分钟。所以我把TextView在布局中,用findViewById()在……里面onCreate(),把这个放进去run()后progress.setProgress(pos):String time = String.format("%d:%d",             TimeUnit.MILLISECONDS.toMinutes(pos),             TimeUnit.MILLISECONDS.toSeconds(pos),             TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(                     pos))             );currentTime.setText(time);  // currentTime = (TextView) findViewById(R.id.current_time);但最后一行给了我一个例外:android.view.ViewRoot$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。然而,我在这里所做的与我在这里所做的事情基本上是一样的。SeekBar-在onCreate,然后触摸它run()-但这并没有给我这种抱怨.
查看完整描述

4 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

您必须将更新UI的后台任务部分移到主线程上。这里有一个简单的代码:

runOnUiThread(new Runnable() {

    @Override
    public void run() {

        // Stuff that updates the UI

    }});

文件Activity.runOnUiThread.

只需将其嵌套在后台运行的方法中,然后复制粘贴在块中间实现任何更新的代码。只包含尽可能少的代码,否则就会开始破坏后台线程的用途。


查看完整回答
反对 回复 2019-05-30
?
慕娘9325324

TA贡献1783条经验 获得超4个赞

我解决了这个问题runOnUiThread( new Runnable(){ ..run():

thread = new Thread(){
        @Override
        public void run() {
            try {
                synchronized (this) {
                    wait(5000);

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            dbloadingInfo.setVisibility(View.VISIBLE);
                            bar.setVisibility(View.INVISIBLE);
                            loadingText.setVisibility(View.INVISIBLE);
                        }
                    });

                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Intent mainActivity = new Intent(getApplicationContext(),MainActivity.class);
            startActivity(mainActivity);
        };
    };  
    thread.start();


查看完整回答
反对 回复 2019-05-30
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

我的解决办法是:

private void setText(final TextView text,final String value){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            text.setText(value);
        }
    });}

在后台线程上调用此方法。


查看完整回答
反对 回复 2019-05-30
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

通常,涉及用户界面的任何操作都必须在主线程或ui线程中执行,即onCreate()执行事件处理。确保这一点的一种方法是使用runOnUiThread(),另一个是使用处理程序。

ProgressBar.setProgress()它有一个机制,它总是在主线程上执行,所以这就是它工作的原因。

查看完整回答
反对 回复 2019-05-30
  • 4 回答
  • 0 关注
  • 936 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信