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

Android“只有创建视图层次结构的原始线程才能触及其视图.”,第1张

概述我在Android中构建了一个简单的音乐播放器.每首歌曲的视图都包含一个SeekBar,实现方式如下:publicclassSongextendsActivityimplementsOnClickListener,Runnable{privateSeekBarprogress;privateMediaPlayermp;//...privateServiceConnection

我在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;          }    };    public voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.song);        // ...        progress = (Seekbar) findVIEwByID(R.ID.progress);        // ...    }    public voID run() {    int pos = 0;    int total = mp.getDuration();    while (mp != null && pos<total) {        try {            Thread.sleep(1000);            pos = appService.getSongposition();        } catch (InterruptedException e) {            return;        } catch (Exception e) {            return;        }        progress.setProgress(pos);    }}

这很好用.现在我想要一个计时器来计算歌曲进度的秒/分钟.所以我在布局中放置一个TextVIEw,在onCreate()中使用findVIEwByID()获取它,并在progress.setProgress(pos)之后将它放在run()中:

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: Only the original thread that created a vIEw hIErarchy can touch its vIEws.

然而,我在这里做的基本上和我在Seekbar上做的一样 – 在onCreate中创建视图,然后在run()中触摸它 – 它并没有给我这个抱怨.

解决方法:

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

runOnUiThread(new Runnable() {    @OverrIDe    public voID run() {        // Stuff that updates the UI    }});

Activity.runOnUiThread的文档.

只需将其嵌套在后台运行的方法中,然后复制粘贴在块中间实现任何更新的代码.只包括可能的最小代码量,否则你开始打败后台线程的目的.

总结

以上是内存溢出为你收集整理的Android“只有创建视图层次结构的原始线程才能触及其视图.”全部内容,希望文章能够帮你解决Android“只有创建视图层次结构的原始线程才能触及其视图.”所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1104586.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存