0

I am playing an stream from Internet and because long processes such as network operation should not be handled on UI Thread, I'm using AsyncTask. In Main Thread I set some specification of 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("");
}

And in AsyncTask I start the video:

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;
    }
}

I tried to have all the parts related to videoView on AsyncTask but was unable to setVideoPath and setMediaController on AsyncTask. I am wondering which part is exactly the time consuming part? Is my code alright? or I'm still having the long process on UI Thread?

Nima K
  • 995
  • 1
  • 8
  • 15

3 Answers3

2

When a non-UI thread wishes to do something with the UI, that thread can pass a Runnable to the UI thread to execute. There are a few ways to do this; one of them is for the non-UI thread to do something like the following (which will need minor tweaking; I'm typing it in without reference to running code):

runOnUiThread(new Runnable() {
    void run() {
        // place UI code here
    }
});
mah
  • 39,056
  • 9
  • 76
  • 93
  • 1
    Network operation should not be handled on UiThread. because they are lengthy. If I wanted to have them on UiThread, I could have simply put them in onCreate – Nima K Jan 21 '13 at 13:03
  • Nima, I did not imply you should put the network operation on the UI thread. Your question indicates you are having problems affecting `videoView` from your AsyncThread -- which is valid since non-UI threads can't properly access UI elements. However, within your AsyncThread, you can (and should) call `runOnUiThread()` to get things such as `videoView.setOnPreparedListener(new OnPreparedListener() {...` completed on the proper thread. – mah Jan 21 '13 at 15:20
  • Let's assume the non-UI thread get network operation done by calling runOnUiThread, But the network operation takes more than 5 seconds. Won't the application freeze because of handling a lengthy operation by runOnUiThread? If not, is there a way I can check this after I do what you said? – Nima K Jan 21 '13 at 17:38
  • I guess I'm having a problem being clear, so let me be low level here: 1) do the network operation in an async thread, where it can take as long as it needs without upsetting Android. 2) when you want to do something on the UI (update progress, etc.), do _that_ within runOnUiThread. – mah Jan 21 '13 at 18:43
  • Your reputation shows that I'm having hard times understanding you. So I apologize. I have 2 questions: 1- I think The following two lines are my network operations(at least one of them is my lengthy operation): videoView.setVideoPath(ChannelPath); videoView.setMediaController(new MediaController(this)); I cannot put them in doInBackground without calling runOnUiThread. And I think I will make Android upset if I put them in runOnUiThread. 2- If that won't make Android upset, why not put these codes on onPreExecute() instead of calling runOnUiThread. – Nima K Jan 23 '13 at 10:00
  • Looking at both the (sparse) documentation on VideoView, and various VideoView tutorials on the web, noone is placing these calls in an async thread. However, some have said that this control does not work well in an emulator, that it should be tested on a real device instead. What is clear though is that you are dealing with a UI control, so accessing it from an async thread is inappropriate and also possible to break your application, so if it is a network operation, it's the OS's problem to deal with, not yours. – mah Jan 23 '13 at 11:03
2

You donot need to use Async Task for this. Use only ProgressDialog progressBar = ProgressDialog.show(context, "", "Loading Records, Please Wait..", true); and dissmiss this progressBar in onPrepared method.

Adnan Amjad
  • 2,553
  • 1
  • 20
  • 29
  • @ AdnanAmjad Network operation should not be handled on UiThread because they are lengthy. That is why I used AsyncTask, so it would be run on non-UI Thread – Nima K Jan 21 '13 at 13:05
  • 1
    @NimaK : VideoView opertions handled by os not by Activity main UI thread so i think no need to use AsyncTask . a u agree with me? – ρяσѕρєя K Jan 21 '13 at 13:22
  • @Adnan No, videoView in this case has to load a stream from network. So if the network ping takes more than 5 seconds, the application will freeze. – Nima K Jan 21 '13 at 17:42
  • @NimaK : but 5 seconds is very less time and u cann't minimize it using AsyncTask – ρяσѕρєя K Jan 21 '13 at 18:30
  • @NimaK I have also created this kind of project which streams through a live server. I have not use Async task for it and it is working fine. – Adnan Amjad Jan 22 '13 at 07:08
  • @AdnanAmjad I suggest you to read http://android-developers.blogspot.com/2009/05/painless-threading.html – Nima K Jan 22 '13 at 09:00
  • @AdnanAmjad You were probably right that OS handles videoview operations. – Nima K Jan 26 '13 at 09:27
0

See also http://developer.android.com/reference/android/media/MediaPlayer.html The initial prepare() step is what is taking time, so you should do that on another thread or use the prepareAsnyc call. The setVideoPath() method only serts the path that will be used in prepare().

If you browse through the code (e.g. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/VideoView.java#VideoView.openVideo() ) you see that nothing is done there if the surface is not yet initialized, and even if it is, prepareAsync() is called in that method for the heavy lifting.

koljaTM
  • 10,064
  • 2
  • 40
  • 42
  • @ koljaTM Are you saying that setVideoPath and setMediaController are not time consuming? Please mention what method exactly have to be on another thread. – Nima K Jan 21 '13 at 13:13
  • Do you think videoView.setMediaController(new MediaController(this)); is the time consuming part? – Nima K Jan 23 '13 at 11:44