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

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()-但这并没有给我这种抱怨.


皈依舞
浏览 937回答 4
4回答

慕标琳琳

您必须将更新UI的后台任务部分移到主线程上。这里有一个简单的代码:runOnUiThread(new Runnable() {     @Override     public void run() {         // Stuff that updates the UI     }});文件Activity.runOnUiThread.只需将其嵌套在后台运行的方法中,然后复制粘贴在块中间实现任何更新的代码。只包含尽可能少的代码,否则就会开始破坏后台线程的用途。

慕娘9325324

我解决了这个问题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();

眼眸繁星

我的解决办法是:private void setText(final TextView text,final String value){     runOnUiThread(new Runnable() {         @Override         public void run() {             text.setText(value);         }     });}在后台线程上调用此方法。

qq_遁去的一_1

通常,涉及用户界面的任何操作都必须在主线程或ui线程中执行,即onCreate()执行事件处理。确保这一点的一种方法是使用runOnUiThread(),另一个是使用处理程序。ProgressBar.setProgress()它有一个机制,它总是在主线程上执行,所以这就是它工作的原因。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java
Android