我有一个AsyncTask
which 需要一个ArrayList
音乐文件来播放。在该doInBackground
方法中,我循环遍历 ArrayList 并一一播放歌曲。我想TextView
在 UI 或其他内容上放置一条状态消息以指示正在播放哪首歌曲,但收到错误只有创建视图层次结构的原始线程才能触及其视图。 如果我只更新 UI 小部件onPreExecute()
并且onPostExecute()
列表已经播放。有没有办法使用onProgressUpdate
或其他AsyncTask
方法来做到这一点?
3 回答
这当然是可能的。这是一个基本示例,如果您想要为歌曲名称、专辑名称和艺术家姓名显示字符串(我还没有完全实现 AsyncTask,只是与 onProgressUpdate 相关的部分):
private class myAsyncTask extends AsyncTask<Void, String, Void>
{
protected Void doInBackground(Void... voids)
{
//Get some list of songs, named songs
for(Song song in songs)//This is the loop where you're playing your songs
{
publishProgress(song.name, song.album, song.artist);
//Play the song and wait for it to finish
}
return null;
}
protected void onProgressUpdate(String... songData)
{
//Assuming three text views exist to display your data
nameTextView.setText(songData[0]);
albumTextView.setText(songData[1]);
artistTextView.setText(songData[2]);
}
}
需要注意的重要事项是尖括号中的第二个类是参数的类型onProgressUpdate
,它publishProgress
在 doInBackground 中被调用以触发onProgressUpdate
。大多数关于 onProgressUpdate 的示例都涉及增加 ProgressBar 的填充,但该方法在 UI 线程上运行,并且可以与 AsyncTask 可以访问的任何视图进行交互。如果您仍然遇到一些问题,请发布您当前的 AsyncTask,以便更轻松地将这个示例类集成到您已有的内容中。这是 AsyncTask 的文档以获取更多信息。希望这可以帮助!
您应该能够使用 onProgressUpdate() 从 UI 线程执行更新。或者,您可以这样做(这在不使用 AsyncTask 时很典型)。
在 UI 线程上发布一个事件来更新您的 UI,如下所示:
view.post( new Runnable() {
@Override
public void run() {
// Update your UI
}
});
它将在 UI 线程上运行,因此它可以访问和更新视图。
就在这里。
当你 decalre AsyncTask 时,你 decalre 进入任务每个部分的类型:
public class MyTask extends AsyncTask<URL,Integer,Long> {
.
.
.
}
按顺序排列的类型,对于此示例:
URL
被传递给doInBackground
viaexecute
Integer
到达onProgressUpdate
(通过publishProgress
)Long
得到onPostExecute
,也是返回值doInBackground
在您的doInBackground()
中,您可以调用publishProgress()
,这将依次调用onProgessUpdate()
主线程(假设您在主线程上创建了 AsyncTask)。
参考文档中有一个完整的示例,位于Usage ( link ) 下。