另一个线程上的Android网络操作比UI

时间:2013-01-21 12:38:06

标签: android multithreading android-asynctask android-videoview ui-thread

我正在播放来自互联网的流,因为不应该在UI线程上处理网络操作等长时间进程,我正在使用AsyncTask。 在主线程中,我设置了一些videoView规范:

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.videoview);
    progressDialog = ProgressDialog.show(this, "Loading", "Please Wait", true, true);

    videoView = (VideoView) findViewById(R.id.surface_view);
    videoView.setVideoPath(ChannelPath);
    videoView.setMediaController(new MediaController(this));

    new LoadStream().execute("");
}

在AsyncTask中我开始播放视频:

private class LoadStream extends AsyncTask<String, Void, Void> {
    protected Void doInBackground(String... urls) {
            videoView.setOnPreparedListener(new OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    videoView.start();
                    progressDialog.dismiss();
                }
            });
        return null;
    }
}

我试图在AsyncTask上拥有与videoView相关的所有部分,但无法在AsyncTask上设置setVideoPath和setMediaController。 我想知道哪个部分正是耗时的部分?我的代码好吗?或者我仍然在UI Thread上进行漫长的过程?

3 个答案:

答案 0 :(得分:2)

当非UI线程希望对UI执行某些操作时,该线程可以将Runnable传递给UI线程来执行。有几种方法可以做到这一点;其中一个是非UI线程做类似下面的事情(这需要稍微调整;我输入它而不参考运行代码):

runOnUiThread(new Runnable() {
    void run() {
        // place UI code here
    }
});

答案 1 :(得分:2)

您不需要为此使用异步任务。仅使用ProgressDialog progressBar = ProgressDialog.show(context, "", "Loading Records, Please Wait..", true);并在onPrepared方法中取消此progressBar。

答案 2 :(得分:0)

另见http://developer.android.com/reference/android/media/MediaPlayer.html 最初的prepare()步骤是花费时间的,所以你应该在另一个线程上执行该操作或使用prepareAsnyc调用。 setVideoPath()方法仅显示将在prepare()中使用的路径。

如果您浏览代码(例如http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/VideoView.java#VideoView.openVideo()),您会发现如果表面尚未初始化则没有任何操作,即使它已经完成,也会在该方法中调用prepareAsync()举重。