Dismissing dialog inside Asynctask triggered IllegalArgumentException - android

I've been using dialog for the Asynctask progress to show. By doing this, I initialized it inside onPreExecute and dismissed it in onPostExecute. I'm not sure what went wrong when I placed a condition to dismiss only if it's not null and it's showing but still triggered IllegalArgumentException: View not attached to window manager
Here's the code:
public class SampleTask extends AsyncTask<String, Void, String> {
public ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SampleActivity.this);
pDialog.setMessage(getString(R.string.loading));
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... path) {
.
.
.
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(null);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
.
.
.
}
}
I read here similar solution but would it differ if I place null != pDialog && pDialog.isShowing() together in the same condition?

Your problem is you only accept the android view in main UI Thread. Read this link for more detail So when you call pDialog.dismiss(); in onPostExecute(String), it run on another thread so android throw new IllegalArgumentException. I have some solution for you and hope that help:
1. I alway use this solution but it not good at all:
Handler handler = new Handler();
Runnable runable = new Runnable() {
#Override
public void run() {
// TODO something you would like to do with Android UI.
}
};
handler.post(runable);
The Handler will create a new thread to run on UI Thread so you can work with Android UI.
2. Sometime I try to use an interface. It more effective than the solution above however, of course, it make me spend more effort.

Related

Cant create handler inside thread that has not called looper.prepare, eventlisteners

I have a class which extends Thread. This class will read some bytes over bluetooth, and once its finished, or the last byte is read, it will call an event listener in order to update all the listening classes.
Like this in the bluetooth class:
fileCompleteInitiator.fileCompleted(fileName);
The implemented method creates an AsyncTask in order to process this file:
public class Home extends Activity {
//other methods like onCreate..
#Override
public void fileComplete(String fileName) {
if(fileName.endsWith(".zip")) {
CaseGenerator generator = new CaseGenerator(Home.this, fileName, lastCases, nist);
generator.execute("");
}
}
}
Inside this asynctask, I want to show a progressdialog, but I get the not-so-original exception:
Cant create handler inside thread that has not called looper.prepare
The code for it is the usual thing, create the progressdialog in onPreExecute() and dismiss it in the onPostExecute(). Some code
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(context);
pd.setTitle("Please Wait..");
pd.setMessage("Generating file");
pd.show();
}
.....................
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if(pd != null)
pd.dismiss();
}
What am I missing?
You need to be creating and executing your AsyncTask from the main application thread. That's a requirement of AsyncTask anyway, last I checked, and it will address your onPreExecute() problems.

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

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()

ProgressDialog in AsyncTask not updating or dismissing

I am using an AsyncTask to handle complex background operations (compiling a log file to send) and I use a ProgressDialog to show the user progress. I have tried using showDialog() but it never seems to show or dismiss (it is never called), and I followed tutorials on how to do it...
So I am using unmanaged ones, and it won't dismiss my message. I am also wanting to update the message as it starts to compile the log file (as it seems to lag there - or maybe the text view is just really long so it doesn't update like it is supposed to).
I have moved my code around a bit so it look like there are problems (like onProgressUpdate()), but I don't know how to make it work. I have looked around this site and nothing seems to be having the problem I am (not exactly anyways). RunOnUiThread() doesn't work, new Thread(){} doesn't work, and onProgressUpdate() I can't get to work (the documentation is confusing on this).
It also never dismisses. I have set up a listener and it never dismisses.
Does anyone know what is wrong with my code? I thought AsyncTask was supposed to be simple.
private class BuildLogTask extends AsyncTask<Void, Void, String> {
String temp;
ProgressDialog progressdialog = new ProgressDialog(context); //variable is defined at onCreate (held as private, not static)
#Override
protected String doInBackground(Void... params) {
temp = buildLog();
logdata = temp;
publishProgress();
createLogFile();
return temp;
}
protected void onProgressUpdate() {
progressdialog.setMessage("Compiling Log File...");
}
#Override
protected void onPreExecute() {
Log.w(TAG,"Showing Dialog");
send.setEnabled(false);
ProgressDialog progressdialog = new ProgressDialog(context);
progressdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressdialog.setMessage("Gathering Data...");
progressdialog.setCancelable(false);
progressdialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
Log.e(TAG,"Progress Dialog dismissal.");
}
});
progressdialog.show();
}
#Override
protected void onCancelled(){
Log.e(TAG,"Progress Dialog was Cancelled");
progressdialog.dismiss();
logdata=null;
}
#Override
protected void onPostExecute(String result) {
progressdialog.dismiss();
send.setEnabled(true);
previewAndSend();
}
}
You have two different progress dialogs there, one local to onPreExecute() and one global. The one ur dismissing in your onPostExecution() is your global one which was never actually shown. Remove the local declaration and it should work.
There are two problems.
The signature for on onProgressUpdate is not correct. Try this instead:
#Override
protected void onProgressUpdate(Void... progress) {
progressdialog.setMessage("Compiling Log File...");
}
You're masking the progressDialog member variable with a local variable in onPreExecute()
EDIT: Second problem identified:
Try it,
Replace:
progressdialog.show();
For:
progressdialog = progressdialog.show();
Good luck.

ProgressDialog working but not progressing in the icon (wheel)

I am using a simple progressDialog that running ok but the the wheel dose not progress:
//Progress Dialog
final ProgressDialog dialog = ProgressDialog.show(TravelPharm.this, "Searching","Please wait ...", true);
((ProgressDialog) dialog)
.setProgressStyle(ProgressDialog.BUTTON_NEUTRAL);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
dialog.dismiss();
}
};
Thread checkUpdate = new Thread() {
public void run() {
handler.sendEmptyMessage(0);
}
};
checkUpdate.start();
what i am missing??
Create your progress dialog like so:
final ProgressDialog progress = new ProgressDialog(context);
add some text/icon to it:
progress.setTitle("Loading");
progress.setMessage("Loading, please wait");
progress.setIcon(R.drawable.icon);
Show it:
progress.show();
I think you should pass ProgressDialog.STYLE_SPINNER to ProgressDialog.setProgressStyle() method.
final ProgressDialog dialog = ProgressDialog.show(TravelPharm.this, "Searching","Please wait ...", true);
The way you are creating the ProgressDialog is correct - if the spinner isn't spinning then something is blocking your UI thread.
Out of interest, why are you using TravelPharm.this for the context instead of this? I'm not sure it's the cause of your problem, I'm just wondering why.
I am guessing that you are launching a time intensive task from a dialog and then trapping the thread exit in your handler where you are trying to dismiss the dialog. If possible, consider simply sending an empty message when the dialog is done. Then in the handler create a new AsyncTask as:
private class MyAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
resetProgress();
progress.show();
}
#Override
protected String doInBackground(String...strings) { // <== DO NOT TOUCH THE UI VIEW HERE
// TODO Auto-generated method stub
doNonUIStuff();
return someString; // <== return value String result is sent to onPostExecute
}
protected void onPostExecute(String result){
progress.dismiss();
doSomethingWithString(result); // you could launch results dialog here
}
};
protected void onPause() {
super.onPause();
if (asynch != null) {asynch.cancel(true);}
if (progress != null){progress.cancel();}
}
private void resetProgress() { // avoid frozen progress dialog on soft kill
if (progress != null && progress.isShowing()){
progress.cancel();
}
progress= new ProgressDialog(this);
progress.setIndeterminate(true);
progress.setMessage("I am thinking.");
}
You could return any type in onPostExecute, in this example I am returning a string. Another approach would be to launch a second Activity as a "dialog" using startActivityForResult create the AsycnTask in onActivityResult.
In other words, gather the data in a dialog or second Activity, then in the first activity show a progress dialog in onPreExecute, do the time intensive task in the background, and cancel the progress dialog in onPostExecute.
I have seen the frozen spinning ball, thus the call to resetProgress().

Categories

Resources