Using looper inside AsyncTask - android

I want to display a progress dialog while my video is being loaded and I used AsyncTask but got the following error:
cant create handler inside thread that has not called looper.prepare
then I tried to use looper inside it and still no luck (as it seems AsyncTask and Looper are two fundamentally different threading models, which are not compatible)
I have read using HandlerThread, but I was not able to find any simple example for it(I usually learn by examples).Please tell me if I need to use HandlerThread and if I should, please provide with a sample of using HandlerThread like we do in AsyncTask for handling a task in background.
That's what I'm doing:
I Just wanted to add that I'm using Vitamio API for playing a flash.
class WaitTask extends AsyncTask<Integer, Void, Void> {
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog (TvProg.this);
progressDialog.show();
}
#Override
protected Void doInBackground(Integer... params) {
videoView.setMediaController(new MediaController(TvProg.this));
return null;
}
#Override
protected void onPostExecute(Void unused) {
progressDialog.dismiss();
}
}

I haven't tried it but I found this example of a progress dialog and a media controller:
Streaming video with videoview

Do it like this..
public MyTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(context, "", msg, true);
}
/*
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected String doInBackground(String... arg0) {
//
}
#Override
protected void onPostExecute(final String result) {
progressDialog.dismiss();
}
}

create ProgressDialog inside asynctask's preexecute() & dismiss that in post execute.

The problem is that the MediaPlayer only can operate on threads with a Looper. Hence, you should not use an AsyncTask for this use case. A HandlerThread is much better suited. The progress bar can be controlled by sending messages back to the UI thread before and after you've setup the videoView as shown in some sample code below:
mMyBgThread = new HandlerThread("HandlerThread");
mMyBgThread.start();
mBgHandler = new Handler(mMyBgThread.getLooper()) {
public void handleMessage(Message msg) {
Message uiMsg = mUiHandler.obtainMessage(SHOW_PROGRESS_BAR);
mUiHandler.sendMessage(uiMsg);
// Setup videoView
uiMsg = mUiHandler.obtainMessage(HIDE_PROGRESS_BAR);
mUiHandler.sendMessage(uiMsg);
}
};
Now you only have to handle SHOW_PROGRESS_BAR and HIDE_PROGRESS_BAR on your UI thread.

Related

Showing progressbar in listview while downloading

There's a "download" button in each listview item. While the button is clicked, it will start a worker thread to down files. And at the same time, the button changed to progressbar and showing the progress rate.
So please show me some proper ways.
Use an AsyncTask since it has special methods for communicating with the main (UI) thread despite being asynchronous.
Here is an example:
http://android-er.blogspot.com/2010/11/progressbar-running-in-asynctask.html
Something like this:
public class DownloadTask extends AsyncTask<Void, Void, Boolean> {
protected void onPreExecute() {
ProgressDialog() progress = new ProgressDialog(context);
progress.setMessage("Loading ...");
progress.show();
}
protected Boolean doInBackground(Void... arg0) {
// Do work
return true;
}
protected void onPostExecute(Boolean result) {
progress.dismiss();
}
}
This should be nested in your activity class and executed like this:
new DownloadTask().execute();
You will likely need to adjust the asynctask to fit your needs but this will get you started.

Show ProgressDialog when loading heavy UI

I use asynctask quite often however this time it doesn't work!
I have a UI contains a viewpager and fragments. To populate the view, it takes about 3 secs. Now I want to show the ProgressDialog until it finishes by using AsyncTask. But the ProgressDialog is not showing!!!!
Anybody can tell me the solution? Thanks
onCreate(...){
setContentView(...)
new LoadUI(MyActivity.this).execute();
}
public class LoadUI extends AsyncTask<Void, Void, Void>{
ProgressDialog pd;
Context context;
public LoadUI(Context mContext) {
this.context = mContext;
pd = new ProgressDialog(mContext);
aViewPager = (ViewPager) findViewById(R.id.aPagerDay);
}
#Override
protected void onPreExecute() {
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
//Create ViewPager
//Create pagerAdapter
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pd.isShowing()) {
pd.dismiss();
}
super.onPostExecute(result);
}
}
You can try out two options:
Either use the AsyncTask's method get(long timeout, TimeUnit unit) like that:
task.get(1000, TimeUnit.MILLISECONDS);
This will make your main thread wait for the result of the AsyncTask at most 1000 milliseconds.
Alternatively you can show a progress dialog in the async task until it finishes. See this thread. Basically a progress dialog is shown while the async task runs and is hidden when it finishes.
You have even third option:" if Thread is sufficient for your needs you can just use its join method. However, if the task is taking a long while you will still need to show a progress dialog, otherwise you will get an exception because of the main thread being inactive for too long.
The problem is the GUI is not ready in onCreate(). And nothing will be shown if I try to show Dialog in this state. A solution is move the dialog to activity onStart():
#override
onStart(){
new LoadUI(MyActivity.this).execute();
}

Loading a layout using ASyncTask in Android

I have an application that loads a dialog with some images specified in the dialog's XML layout. I've read a lot about using images in Android and being careful with the VM budget so I believe that any handling of images with the potential to take up a decent amount of memory should be handled off of the main thread. With that said I was wondering if it is wise to load an entire layout off of the UI thread using an ASyncTask. I have a working code but I couldn't find out if this was good practice through some Google searches. Here is the code below.
This is the case statement that triggers when the user presses a button to load the dialog.
case R.id.showDialog:
vibrator.vibrate(vibrateMilis);
mDialog = new Dialog(getActivity(), R.style.CustomDialog);
new LoadLayout().execute("");
break;
And here is the ASyncTask
private class LoadLayout extends AsyncTask<String, Void, String>
{
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params)
{
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.setContentView(R.layout.dialog_layout);
mDialog.setCancelable(true);
return null;
}
#Override
protected void onPostExecute(String result)
{
progressDialog.cancel();
mDialog.show();
}
#Override
protected void onPreExecute()
{
progressDialog = new ProgressDialog(
getActivity());
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values)
{
// Do nothing
}
}
So this code works but the question I have is this. Is this considered good practice? It seems a bit hacky for my taste. I didn't come across this with multiple Google searches so that's why I'm a bit concerned. I mean if it was good practice it would've been documented somewhere right?
Thanks for any input.
Have you refer the android developer site. your approach is wrong. For more guidance please refer Vogella Documentation. Its a nice explaination of AsyncTask.
Also refer below example code for the AsyncTask.
// The definition of our task class
private class PostTask extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
displayProgressBar("Downloading...");
}
#Override
protected String doInBackground(String... params) {
String url=params[0];
// Dummy code
for (int i = 0; i <= 100; i += 5) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return "All Done!";
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
updateProgressBar(values[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dismissProgressBar();
}
}
Hope it will help you a lot.
Enjoy Coding... :)
I think you are doing it in a wrong way , because :
First,when call method doInBackground() , It will in other thread , you can only change UI elements in main thread .
Second,show a dialog is not waste time,you can call it in onPreExecute() or onPostExecute(String result),and just do actions in doInBackground() that make user wait ,like get data from network or database.
You can not load whole Layout in background thread(pls note AsyncTask.postExecute() is executed on main thread). Because all the UI components should be modified from only Main Thread(also called UI thread). You can use the background thread just to gather the information that is needed for displaying UI.

How to properly implement a progressBar in Android?

Now I am doing an Android application.In my application I have to get the data from json page.This operation is taking time delay.So I have to show a progressbar until the fetching process is completed.I used the following code to show progressbar.
public void onCreate(Bundle savedInstanceState) {
//somecode
ProgressDialog progressBar = new ProgressDialog(this);
progressBar.setCancelable(true);
progressBar.setMessage("Loading");
progressBar.show();
Thread thread = new Thread(this);
thread.start();
}
public void run() {
flag=GetFixtureDetailsJsonFunction();
handler.sendEmptyMessage(0);
}
protected boolean GetFixtureDetailsJsonFunction() {
//json parsing code
return true
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (flag==true) {
progressBar.dismiss();
}
}
};
Using this code I am getting exception.android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
AsyncTask is best way for getting response from xml or database. try like this,
private class DownloadQuestion extends AsyncTask<String, Void, String>
{
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(Activity_SplashScreen.this, "","Please wait...", true,false);
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls)
{
//Write background code here Code
return "";
}
#Override
protected void onPostExecute(String response1)
{
//Some Code.....
if (pd != null && pd.isShowing())
pd.dismiss();
}
}
Instead i would suggest you to implement AsyncTask, which is known as Painless Threading in android.
Using this AsyncTask, you don't need to bother about managing Threads. And its easy!!
FYI, do as follows:
Display ProgressBar in onPreExecute() method.
Do long running tasks inside the doInBackground() method.
Dismiss the ProgressBar inside the onPostExecute() method. You can also do display kinds of operation in this method.
This is a bit strange way to implement this functionality. Instead of fixing that code I suggest you using AsyncTask, which was implemented right for that purpose. See here.
You are trying to access the UI View from another thread which is not eligible.In this case this is your handler.
Instead of trying to access UI thread like this you should use an AsyncTask and do your progressDialog logic in it.
Start showing the progress bar onPreExecute
doInBackground() jobs while progressBar showing
And finallly dismiss your progressBar after your doInBackground() is complete onPostExecute()

Android: display image during async background streaming task

I am trying to retrieve JPGs from an MJPG Stream using an async task. I first thought, i could let the task continuously be running and just letting the buffered JPGs pop up in the onProgressUpdate() method. But this doesn't seem to work, because the method only displays integers, no drawables...what I tried:
private class StreamTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
image = readMJPGStream();
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
imView.setImageDrawable(image); // << doesn't work
}
}
Do you have any ideas? What approach should I try?
Thank you very much in advance!
Huck
When you start a AsyncTask, the doInBackground is called, but it is only run once. I'm not sure what readMJPGStream does, but assuming it blocks until an image is retrieved, its certainly possible that onProgressUpdate gets called several times while your image is still null, then once image get set to something valid and doInbackground quickly exits, there are no further calls to OnProgressUpdate.
You should probably put the call to imView.setImageDrawable in onPostExecute to make sure it gets called when the image has been downloaded. You may also need to call invalidate() on your image view to ensure it gets redrawn. Additionally, if you intend to loop and continue downloading images, you'll need to devise a mechanism of triggering updates. In reality, the issue you're having is because you want 'on demand' get on the UI Thread, but you're dependent on calls to onProgressUpdate. You'd have much better luck using a Handler and your own Runnable/Thread because then when an image download completes, you can post to the UI thread (using the Handler) without having to wait for the onProgressUpdate.
I now got it running this way:
public class StreamActivity extends Activity implements Runnable{
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imView = (ImageView) findViewById(R.id.imView);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (connected){
image = readMJPGStream();
handler.sendEmptyMessage(0);
}
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
imView.setImageDrawable(image);
}
};
public Drawable readMJPGStream() {
//...
return image;
}
}
The only problem is that my while loop is not fast enough. Any ideas are very much appreciated!
Huck

Categories

Resources