ProgressDialog in another AsyncTask class not showing when called from Activity - java

I have a class called RestClient that gets some information from my webService and then return and I'm trying to make a Progress dialog run while it is accessing the internet. And as I use this class in more than one place I won't make in the Activity itself. Here is my RestClient class:
public class RestClient extends AsyncTask<URL, String, String> {
private Context context;
private String string;
public RestClient(Context context, String string)
{
this.context = context;
this.string = string;
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(context, "Buscando seu Produto","Por favor, espere um momento...",true ,false);
//I've already tried:
/*ProgressDialog dialog = new ProgressDialog(context);
dialog.setTitle("Buscando seu Produto");
dialog.setMessage("Por favor, espere um momento...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);*/
dialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(URL... params) {
try {
//Some WebService gets and Json conversions using my string variable
//and some Thread.sleep that counts 2000 miliseconds to do all the queries
dialog.dismiss();
} catch (IOException | InterruptedException |JSONException e) {
e.printStackTrace();
dialog.dismiss();
return e.getMessage();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
And in my activity I call the class RestClient when I click a button like this:
--- EDIT : I forgot to mention that I have an AlertDialog in this same activity that CAN be shown sometimes before and after the ProgressDialog ---
private Button buttonConfirm;
private EditView evString;
private String theString;
private String returnFromExecute;
private RestClient restClient;
private AlertDialog.Builder dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_access_webservice);
evString = (EditText) findViewById(R.id.editViewMyString);
buttonConfirm = (Button) findViewById(R.id.buttonConfirm);
dialog = new ProgressDialog(IdentificacaoDeProdutoActivity.this);
dialog.setTitle("Error");
dialog.setMessage("Please try again");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
buttonConfirmar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
theString = evString.getText().toString();
if(!(theString!=null && theString.trim().length()>0)) //To check if theString is not null
{
dialog.show();
}
restClient = new RestClient(AccessWebserviceActivity.this, theString);
//Then I call execute and put a Thread.sleep a bit longer to compensate the ones I have in my doInBackground
restClient.execute();
try {
Thread.sleep(2050);
} catch (Exception e) {
dialog.show();
return;
}
}
}
}
The problem is that my ProgressDialog never shows. I've already tried getParent(), getApplication() and getApplicationContext() instead of AccessWebserviceActivity.this but none have worked. Someone Have any idea what is happening and what should I do?

you have not created progress dialog try this.
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog= new ProgressDialog(context);
dialog.setMessage("on Progress");
dialog.show();
super.onPreExecute();
}

returnFromExecute = restClient.get();
Remove that statement. You have already:
restClient.execute();
That should do.
The result of doInBackground() you should handle in onPostExecute(). It cannot be handled or retrieved in onCreate().

You need to call
dialog = ProgressDialog.show(context, "Buscando seu Produto","Por favor, espere um momento...",true ,false);
and remove
dialog.show();
Also put your dialog.dismiss(); method in onPostExecute(). This dialog.dismiss() method is good in catch block but what's its purpose if you are calling this method in try block. It will remove progress dialog as soon as you call this AsyncTask.

After a lot of researches about Threads and Process I found out that I had to encapsulate the all the code I have after my
RestClient.execute in a
new Thread(new Runnable() { public void run() { // My code } });
so that the execution of the code happened in background as well as the WebService query.
EDIT:
Even if creating a new Thread works, it is not recommended! The right thing to do would be to create another class that extends AsyncTask to do job.

Related

Progress Dialog: android.view.WindowLeaked: has leaked window DecorView#6995336[] that was originally added here

I tried to change the orientation of my device on recycler view but it always crashes when progress dialog shows up.
How to solve this?
Here is my code:
private class LoadOrdersListAgent extends AsyncTask {
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(OrdersActivity.this);
ordersList = new ArrayList<>();
rvor = findViewById(R.id.recycler_view_orders_agent);
emptytv = findViewById(R.id.empty_view_orders_agent);
emptytv.setVisibility(View.GONE);
rvor.setHasFixedSize(true);
rvor.setLayoutManager(new LinearLayoutManager(OrdersActivity.this));
rvor.setItemAnimator(new DefaultItemAnimator());
dialog.setMessage("Loading....");
dialog.show();
}
#Override
protected void onPostExecute(Void aVoid) {
final OrdersAdapter adapter = new OrdersAdapter(getApplicationContext(), ordersList);
rvor.setAdapter(adapter);
rvor.setLayoutManager(new LinearLayoutManager(OrdersActivity.this));
srl.setRefreshing(false);
if (dialog.isShowing()) {
dialog.dismiss();
}
if (ordersList.isEmpty()) {
Log.d("TESTING.....", "LIST OF ORDERS ----->" + ordersList);
rvor.setVisibility(View.GONE);
srl.setVisibility(View.GONE);
emptytv.setVisibility(View.VISIBLE);
} else {
rvor.setVisibility(View.VISIBLE);
srl.setVisibility(View.VISIBLE);
emptytv.setVisibility(View.GONE);
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected Void doInBackground(Void... voids) {
ordersList = OrdersApi.getOrders(url, key);
return null;
}
}
private void swipeOrderLayout() {
srl = findViewById(R.id.swipe);
srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
if (new CheckNetworkUtil(OrdersActivity.this).isNetworkAvailable()) {
new LoadOrdersListAgent().execute();
// new LoadOrdersListAdmin().execute();
} else
Toast.makeText(OrdersActivity.this, "No Internet Connection!", Toast.LENGTH_SHORT).show();
srl.setRefreshing(false);
}
});
}
I got this error when i was Finishing/Destroying the activity without Dismissing progress Dialogue.
Solution use dialog.dismiss(); to dismiss the progress dialogue before destroying or pausing the activity
in your case remove the if condition and just call dialog.dismiss(); in postExecute method
Declare your ProgressDialog in Global using :
Add this code above onCreate() :
private ProgressDialog dialog;
Add this code within a onCreate():
dialog = new ProgressDialog(OrdersActivity.this);
dialog.setMessage("Loading....");
dialog.show();
Add this code within as onPreExecute method ,
if (!dialog.isShowing()) {
dialog.show();
}

ProgressDialog new Activity Asynctask is not showing, why?

I made a AsyncTask class with the following code
public class removeDialog extends AsyncTask<Void, Void, Void> {
Context c;
ProgressDialog asyncDialog;
String page;
public removeDialog(Context c, String page) {
this.c = c;
this.page = page;
asyncDialog = new ProgressDialog(c);
}
#Override
protected void onPreExecute() {
//set message of the dialog
asyncDialog.setTitle("Please wait");
asyncDialog.setMessage("Loading...");
asyncDialog.setCancelable(false);
//show dialog
asyncDialog.show();
if (page == "algemeneVoorwaarden") {
Intent intent = new Intent(c, algemeneVoorwaarden.class);
c.startActivity(intent);
}
if (page == "contact") {
Intent intent = new Intent(c, contactTest.class);
c.startActivity(intent);
}
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
//don't touch dialog here it'll break the application
//do some lengthy stuff like calling login webservice
return null;
}
#Override
protected void onPostExecute(Void result) {
//hide the dialog
asyncDialog.dismiss();
super.onPostExecute(result);
}
}
First time I tried:
on the first time I see an ProgressDialog, but the second time I want to open the activity I get nothing.
Second time I tried:
I get no ProgressDialog even the first time I try.
I execute my code in an AsyncTask class, code:
voorwaarden.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new removeDialog(c, "algemeneVoorwaarden").execute();
}
});
Does someone know why it isn't working? Please help me.
Your dialog will be dismissed as soon as it's shown, because your doInBackground is empty. Try adding a Thread.sleep() with a few seconds, just to simulate a delay.
Also, I suspect that the new activities you're starting will leave your dialog behind. So I would suggest you to test the code without these new activities for now.
public class RemoveDialog extends AsyncTask<Void, Void, Void> {
ProgressDialog asyncDialog;
public RemoveDialog(Context c) {
asyncDialog = new ProgressDialog(c);
}
#Override
protected void onPreExecute() {
//set message of the dialog
asyncDialog.setTitle("Please wait");
asyncDialog.setMessage("Loading...");
asyncDialog.setCancelable(false);
//show dialog
asyncDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
try {
Thread.sleep(3000);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
//hide the dialog
asyncDialog.dismiss();
super.onPostExecute(result);
}
}

AsyncTask return value late

I have an authentication interface with an email field and a button.
When i click the button an AsyncTask should verify if the email exist in a google app engine datastore or not.
This is the code for my asyncTask:
public class ConnexionAsyncTask extends AsyncTask<Object, Object, Inscrit> {
private static InscritApi inscritApi = null;
private Context context;
String email;
ProgressDialog dialog;
public ConnexionAsyncTask(Context context, String email) {
this.context = context;
dialog = new ProgressDialog(context);
this.email = email;
}
#Override
protected void onPreExecute() {
dialog.setMessage("Connexion en cours");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
#Override
protected Inscrit doInBackground(Object... params) {
if (inscritApi == null) {
InscritApi.Builder builder = new InscritApi.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
.setRootUrl( // some url );
inscritApi = builder.build();
}
try {
return inscritApi.get(email).execute();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Inscrit inscrit) {
MainActivity main = (MainActivity) context;
main.setInscrit(inscrit);
dialog.dismiss();
}}
And this is the MainActivity code:
public class MainActivity extends AppCompatActivity {
Inscrit inscrit;
Button btncnx;
EditText emailcnx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btncnx = (Button) findViewById(R.id.btncnx);
emailcnx = (EditText) findViewById(R.id.emailcnx);
btncnx.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ConnexionAsyncTask task = new ConnexionAsyncTask(MainActivity.this, emailcnx.getText().toString());
task.execute();
if (inscrit == null)
Toast.makeText(MainActivity.this, "not exist", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "exist", Toast.LENGTH_SHORT).show();
}
});
}
public void setInscrit(Inscrit inscrit) {
this.inscrit = inscrit;
}}
So the code should work like this:
the MainActivity should give the "inscrit" variable to the ConnexionAsyncTask
the ConnexionAsyncTask should verify if the email exist in the datastore or not and then put the result (Inscrit instance or null) in the "inscrit" variable with a setter
the MainActivity should verify if "inscrit" is null or not and show a toast
When i run my code i have to click 2 times to get the real result for example if i put "user#gmail.com" and this email exist of course in the datastore it will show me "not exist" for the first time and exist for second that's mean that the AsyncTask return the value just after the verification.
If i return value with .execute().get() it works but it blocks the ui thread and i want to show a progress Dialog.
I've tried to use a callback interface but it doesn't work either.
You should do the checking
if (inscrit == null)
Toast.makeText(MainActivity.this, "not exist", Toast.LENGTH_SHORT).show();
else
Toast.makeText(MainActivity.this, "exist", Toast.LENGTH_SHORT).show();
after your AsyncTask has finished executing. Basically, you are safe to check on inscrit nullability onPostExecute.

Progress dialog async task taking longer time than expected

I am new to android programming. I am developing a web crawler for which i am using a Async Task and it is working well.In order to keep user informed,i am using progress dialog. My problem is,if i use a Progress Dialog my program takes more time to execute and when i won`t use the progress dialog,it executes faster.
Done Work
OnCreate Method
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
Intent intent = getIntent();
s1 = intent.getStringExtra("Number1");
s2 = intent.getStringExtra("Number2");
s3=intent.getIntExtra("selectedItem",0);
HttpAsyncTask asyncTask = new HttpAsyncTask();
asyncTask.execute();
}catch (Exception e)
{
messageBox("Exception",e.getMessage());
}
}
Async Task Class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Results.this);
dialog.setIndeterminate(true);
dialog.setMessage("Please Wait");
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
#Override
protected List<String> doInBackground(List<String>... urls) {
//android.os.Debug.waitForDebugger();
// spinner.setVisibility(View.VISIBLE);
List<String>resultList=new ArrayList<String>();
try
{
if(isCancelled())
return resultList;
resultList=WebCrawlerClass.GetPost(s1,s2,s3);
}catch (Exception e)
{
messageBoxs("Error", e.getMessage());
}
return resultList;
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<String> result)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
if(s3 == 2)
{
docListAdapter=new ListViewData(Results.this,result);
}
else {
docListAdapter = new NameNumListData(Results.this, result);
}
docList=(ListView)findViewById(R.id.listView2);
docList.setAdapter(docListAdapter);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
super.onCancelled();
this.cancel(true);
}
}
Am I missing something? Need help..
Thanks and Regards,
Abhinav
In you activity
// Start the progress dialog
..
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// dismiss the progress dialog
}
};
HttpAsyncTask asyncTask = new HttpAsyncTask(handler);
asyncTask.execute();
In your asynctask class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private Handler handler = null;
public HttpAsyncTask (Handler handler) {
this.handler = handler;
}
protected Void doInBackground(Void... params) {
//Perform your task
// When you know that task is finished , fire following code
if (null != handler) {
Message message = handler.obtainMessage();
message.obj = Any data you want to sent to the activity
message.what = 1 ; ( Optional )
handler.sendMessage(message);
}
}
Thus when sendMessage function is called from doInbackground.. your handleMessage in your activity will get triggered and then you should dismiss the progress dialog
Hope this will improve the performance issue what you are facing
Remove super.onPreExecute(); in onPreExecute() method and check .It might Help

Can't create handler inside thread that has not called Looper.prepare()

I get this error "Can't create handler inside thread that has not called Looper.prepare()"
Can you tell me how to fix it?
public class PaymentActivity extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.payment);
final Button buttonBank = (Button) findViewById(R.id.buttonBank);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
progressDialog = ProgressDialog.show(PaymentActivity.this, "",
"Redirecting to payment gateway...", true, true);
new Thread() {
public void run() {
try {
startPayment("Bank");
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
}
}.start();
}
});
StartPayment Method:
private void startPayment(String id) {
Bundle b = getIntent().getExtras();
final Sail sail = b.getParcelable(Constant.SAIL);
final Intent bankIntent = new Intent(this, BankActivity.class);
try {
Reservation reservation = RestService.createReservation(
sail.getId(),
getSharedPreferences(Constant.PREF_NAME_CONTACT, 0));
bankIntent.putExtra(Constant.RESERVATION, reservation);
// <workingWithDB> Storing Reservation info in Database
DBAdapter db = new DBAdapter(this);
db.open();
#SuppressWarnings("unused")
long rowid;
rowid = db.insertRow(sail.getId(), sail.getFrom(),
sail.getTo(), sail.getShip(), sail.getDateFrom().getTime(),
sail.getPrice().toString(), reservation.getId().floatValue());
db.close();
// </workingWithDB>
String html = PaymentService.getRedirectHTML(id, reservation);
bankIntent.putExtra(Constant.BANK, html);
} catch (Exception e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder.create();
alertDialog.setMessage(e.getMessage());
alertDialog.show();
}
startActivity(bankIntent);
}
You should know that when you try to modify your UI , the only thread who can do that is the UiThread.
So if you want to modify your UI in another thread, try to use the method: Activity.runOnUiThread(new Runnable);
Your code should be like this :
new Thread() {
public void run() {
YourActivity.this.runOnUiThread(new Runnable(){
#Override
public void run(){
try {
startPayment("Bank");//Edit,integrate this on the runOnUiThread
} catch (Exception e) {
alertDialog.setMessage(e.getMessage());
handler.sendEmptyMessage(1);
progressDialog.cancel();
}
});
}
}
}.start();
I assume you create a Handler in startPayment() method. You can't do that, as handlers can be created on th UI thread only. Just create it in your activity class.
Instead of new Thread() line, try giving
this.runOnUiThread(new Runnable() {
you cant change any UI in thread you can use runOnUIThread or AsyncTask for more detail about this click here
I've found that most thread handling can be replaced by AsyncTasks like this:
public class TestStuff extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonBank = (Button) findViewById(R.id.button);
buttonBank.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new StartPaymentAsyncTask(TestStuff.this).execute((Void []) null);
}
});
}
private class StartPaymentAsyncTask extends AsyncTask<Void, Void, String> {
private ProgressDialog dialog;
private final Context context;
public StartPaymentAsyncTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
// setup your dialog here
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(context.getString(R.string.doing_db_work));
dialog.setCancelable(false);
dialog.show();
}
#Override
protected String doInBackground(Void... ignored) {
String returnMessage = null;
try {
startPayment("Bank");
} catch (Exception e) {
returnMessage = e.getMessage();
}
return returnMessage;
}
#Override
protected void onPostExecute(String message) {
dialog.dismiss();
if (message != null) {
// process the error (show alert etc)
Log.e("StartPaymentAsyncTask", String.format("I received an error: %s", message));
} else {
Log.i("StartPaymentAsyncTask", "No problems");
}
}
}
public void startPayment(String string) throws Exception {
SystemClock.sleep(2000); // pause for 2 seconds for dialog
Log.i("PaymentStuff", "I am pretending to do some work");
throw new Exception("Oh dear, database error");
}
}
I pass in the Application Context to the Async so it can create dialogs from it.
The advantage of doing it this way is you know exactly which methods are run in your UI and which are in a separate background thread. Your main UI thread isn't delayed, and the separation into small async tasks is quite nice.
The code assumes your startPayment() method does nothing with the UI, and if it does, move it into the onPostExecute of the AsyncTask so it's done in the UI thread.
Try
final Handler handlerTimer = new Handler(Looper.getMainLooper());
handlerTimer.postDelayed(new Runnable() {
public void run() {
......
}
}, time_interval});

Categories