I have a progress dialog, I want it to show and dismiss when my method has finished executing. now, I have this:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try{
DownloadMethod(s);
progressDialog.dismiss();
}catch (Exception e){
Toast.makeText(prefs.this, "We can't reach the data...Try again", Toast.LENGTH_SHORT).show();
}
}
}).start();
My method DownloadMethod is executed but never shows the dialog.
Actually, It must be throwing an exception with progressDialog.dismiss(); call because you cannot update UI from a worker thread, instead use AsyncTask
e.g pass parameter to constructor
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
TypeOf_S s;
public DownloadFilesTask(TypeOf_S s){
this.s = s;
}
#Override
protected Void doInBackground(Void... obj) {
DownloadMethod(s);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask(s).execute();
or with generic parameter
private class DownloadFilesTask extends AsyncTask<TypeOf_S, Void, Void> {
#Override
protected Void doInBackground(TypeOf_S... obj) {
DownloadMethod(obj[0]);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask().execute(s);
progressDialog.dismiss();is throwing an exception so move your code inside runOnUiThread() method like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
as suggested by Pavneet you can use async task as follows where AsyncTask<String, void, String> corresponds to the input type progress value and last is result value you are interested so give data types accordingly.
private class DownloadFilesTask extends AsyncTask<String, void, String> {
protected String doInBackground(String... urls) {
//here do the actual downloading instead of calling the DownloadMethod(s)
}
protected void onPreExecute() {
//here show the dialog
progressDialog.show();
}
protected void onPostExecute(String result) {
//here hide the dialog
progressDialog.dismiss();
}
}
and where you are calling the download function you just call this
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
new DownloadFilesTask().execute(s);
//here s is assumed to be string type you can give anything
Related
I want to run two connections using Android Native :
public class MyPublicClass extends AppCompatActivity {
here is the first class
private class GetNextQuestionIndex extends AsyncTask<String, Void, Void> {
//some code
protected Void doInBackground(String... params) {
URL url = new URL("url1");
//some code to initialize connection and get the output
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytxtview.setText(output1)
System.out.println("1");
progress.dismiss();
}
});
Here is the second class
private class GetLibelleOfQuestion extends AsyncTask<String, Void, Void> {
//some code
protected Void doInBackground(String... params) {
URL url = new URL("url2");
//some code to initialize another connection and get another output
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
});
}//the end of the public class
but when i run my code its give me
2 1
how can I get
1 2
?
which means execute the run of GetNextQuestionIndex before the run of GetLibelleOfQuestion
onCreateActivity(...){
...
ShowDialog();
AsyncTask1(...).execute();
}
public void callAsyncTask2(){
AsyncTask2(...).execute();
}
class AsyncTask1(...){
....
onPostExecute(...){
activity.callAsyncTask2();
}
}
class AsyncTask2(...){
....
onPostExecute(...){
activity.dismissDialog();
}
}
Hope it helps.
This is the proper ways to call 2 asyn task .
private class GetNextQuestionIndex extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
URL url = new URL("url2");
//run your background task
return results;
}
#Override
protected void onPostExecute(String result) {
mytxtview.setText(output1)
System.out.println("1");
new GetLibelleOfQuestion ().execute("");
}
#Override
protected void onPreExecute() {
progress.dismiss();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
//Second asyn task
private class GetLibelleOfQuestion extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
URL url = new URL("url2");
//run your background task
return results;
}
#Override
protected void onPostExecute(String result) {
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
oncreate method call or button click , where you want
new GetNextQuestionIndex ().execute("");
You can use set the second thread to sleep for a moment (waiting for the first thread to be executed):
private class GetLibelleOfQuestion extends AsyncTask<String, Void, Void> {
...
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Thread.sleep(WAIT_TIME_IN_MILLISECONDS);
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
});
}//the end of the public class
I'm inserting some data in my app's local database inside AysncTask, but when executing the class the progress dialog is not showing on the screen while i can see the running log. I see many related answer but the issue is not resolved. I read the .get() method blocks the ui but I'm already not using this method. I don't why it is not showing on the screen
calling async class from main Activity
AsyncGetDataFromServer task = new AsyncGetDataFromServer(this);
task.execute();
code of AsyncTask class
public class AsyncGetDataFromServer extends AsyncTask<Void, Void, Boolean> {
ProgressDialog pd;
Context cxt;
DatabaseHandler dbHelper;
private static ArrayList<DataModel> categoryArrayList;
public AsyncGetDataFromServer(Context context) {
// TODO Auto-generated constructor stub
cxt= context;
pd = new ProgressDialog(cxt);
pd.setTitle("Please wait");
pd.setMessage("Loading...");
pd.setCancelable(false);
dbHelper = new DatabaseHandler(cxt);
}
#Override
protected Boolean doInBackground(Void... params)
{
try {
Log.d("do in background","true");
for (int i = 0; i < response.body().getVideoEntity().size(); i++) {
//inserting in categories
VideoEntity videoEntity;
videoEntity = response.body().getVideoEntity().get(i);
dbHelper.insertChannels(videoEntity);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("exception error", e.getMessage());
}
return true;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("on pre execute","true");
pd.show();
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.d("on post execute","true");
pd.dismiss();
}
}
pass Activity instead of context to the constructor.For example-
AsyncGetDataFromServer task = new AsyncGetDataFromServer(MyActivity.this);
task.execute();
You should implement the method onProgressUpdate and use the method publishProgress :
see https://developer.android.com/reference/android/os/AsyncTask.html
Show dialog in onPreExecute() method & dismiss in onPostExecute() method:
private class AsyncGetDataFromServer extends AsyncTask<Void, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(YourClass.this);
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.show();
}
protected void doInBackground(final Void unused) {
//don't interact with the ui!
}
protected void onPostExecute(final Boolean result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
I am displaying a ProgressDialog in an AsyncTask, as follows.
public class DataComm extends AsyncTask<String, Void, JSONObject> {
...
ProgressDialog pd = null;
...
protected void onPreExecute() {
pd = ProgressDialog.show(activity, activity.getResources().getText(R.string.wait_please) + "\u2026", "", true);
...
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
...
pd.dismiss();
}
The PD is declared in the class which implements AsyncTask. I initialize it in onPreExecute, using the context of the activity which creates the and attempt to call pd.dismiss() at the end of doInbackground. This is called from multiple activities, in some it works, but in others I get a RuntimeException "sending message to a Handler on a dead thread".
In the failure case, I know that the activity which I used to create the PD is still alive, so I don't understand what thread has died.
The problematic call is from a class which is derived from a base class used to update a list for a class derived from ArrayAdapter. The AsyncTask is called when the ArrayAdapter needs to fill the list of options. Does this happen on some thread other than the UI main thread. I still don't see why it should die before the onPostExecute is called.
Async Task doInbackground method runs on background in separate thread other than main thread. Please check it may be because of some reason this is dying.
I think you should first create Constructor for AsyncTask DataComm ,then initialize your ProgressDialog in constructor like this:
public class DataComm extends AsyncTask<String, Void, JSONObject> {
...
ProgressDialog pd;
...
public void DataComm(Context mContext)
{
pd = new ProgressDialog(mContext);
}
protected void onPreExecute() {
this.pd.setMessage(mContext.getResources().getText(R.string.wait_please) + "\u2026");
this.pd.show();
...
}
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
...
if (pd.isShowing()) {
pd.dismiss();
}
}
Try this:
public class DataComm extends AsyncTask<String, Void, Void> {
ProgressDialog pd = null;
protected void onPreExecute() {
pd = ProgressDialog.show(activity, activity.getResources().getText(R.string.wait_please) + "\u2026", "", true);
}
protected void onProgressUpdate(Integer... progress) {
pd.setProgress(progress[0]);
}
protected void onPostExecute() {
super.onPostExecute(result);
...
activity.runOnUiThread(new Runnable() {
#Override
public void run(){
if (pd.isShowing()) {
pd.dismiss();
}
}
});
}
}
The ArrayAdapter support seems to have been the problem. Updating the list from the UpdateMap override seems to take place on a separate thread. When I put the call inside a runOnUiThread there was no more dead thread:
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
DataComm dc = new DataComm(itemFetcher, activity, pd);
dc.execute("main", "product_search","search_prefix", newFilter);
}
});
I am trying to use progress bar while updating my database. Good thing, i can successfully update my database but my progress bar is not showing. I am using a progress bar the will show also the percentage on my update. I don't know what wrong with my code below, help me figure it out please:
public class SyncBrand extends AsyncTask<String, Void, Boolean>
{
public static final int BRAND_DIALOG_DOWNLOAD_PROGRESS = 0;
public SyncBrand(Context context, String _username, String _password, String _code,String _remarks,String _date,String _province,String _infotype,
String _competitor,ArrayList<String> _brands, ArrayList<String> _segments)
{
....
}
protected Dialog onCreateDialog(int id) {
switch (id) {
case BRAND_DIALOG_DOWNLOAD_PROGRESS:
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage("Updating Sub Brands..");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
return progressDialog;
default:
return null;
}
}
#SuppressWarnings("deprecation")
protected void onPreExecute()
{
super.onPreExecute();
((Activity) mContext).showDialog(BRAND_DIALOG_DOWNLOAD_PROGRESS);
}
protected Boolean doInBackground(String... arg0)
{
try{
....
}catch (Exception e){
Log.e("Update SubBrand", "Error:", e);
exception = e;
return false;
}
....
return true;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
progressDialog.setProgress(Integer.parseInt(progress[0]));
}
#SuppressWarnings("deprecation")
protected void onPostExecute(Boolean valid)
{
((Activity) mContext).removeDialog(BRAND_DIALOG_DOWNLOAD_PROGRESS);
if(valid){
.....
}else{
Toast.makeText(mContext, "Failed to update.Please try again.", Toast.LENGTH_SHORT).show();
mContext.startActivity(new Intent(mContext, S_2nd_Main.class));
}
}
}
A couple problems I see here. You have Void for the second argument in your AsyncTask
public class SyncBrand extends AsyncTask<String, Void, Boolean>
which means that onProgressUpdate() should expect that type of data passed to it but you have protected void onProgressUpdate(String... progress) { which tells that method to take a String parameter. Also, you don't call publishProgress() from doInBackground() which is what is used to call onProgressUpdate().
Change your AsyncTask to
public class SyncBrand extends AsyncTask<String, String, Boolean>
and add publishProgress() to doInBackground() and pass the String value you want it to update the ProgressDialog to.
I have a huge database (40MB) on an SDCard. I need fetch data, with LIKE in query, which is very slow.
DB request takes about 5 seconds. Therefore, I need to do it asynchronously and with ProgressDialog.
I tried it with AsyncTask, but problem is with ProgressDialog. It was implemented this way:
private class GetDataFromLangDB extends AsyncTask<String, String, String> {
private final ProgressDialog dialog = new ProgressDialog(TranslAndActivity.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
urDBCursor.close();
curDBCursor = null;
scaAdapter = null;
this.dialog.setMessage("Loading data...");
this.dialog.show();
}
#Override
protected String doInBackground(String... whatSearch) {
String result = "";
if (myDatabaseAdapter != null) {
curDBCursor = myDatabaseAdapter.fetchAll(whatSearch[0]);
}
return result;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
prepareListView();
}
}
The problem is that ProgressDialog is not shown during the DB request.
After finished database query, it flash on screen for a short time. When user tries
to tap on screen during database request, UI is freezed, and after DB request
message about 'not responding' is shown.
I tried it with a thread this way:
public void startProgress(View view, final String aWhatSearch) {
final ProgressDialog dialog = new ProgressDialog(MyActivity.this);
if (curDBCursor != null){
curDBCursor.close();
curDBCursor = null;
}
dialog.setMessage("Loading data...");
dialog.show();
Runnable runnable = new Runnable() {
public void run() {
curDBCursor = myDatabaseAdapter.fetchAll(aWhatSearch);
// dirty trick
try {
Thread.sleep(250); // it must be here to show progress
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
public void run() {
if (dialog.isShowing()) {
dialog.dismiss();
}
prepareListView();
}
});
}
};
new Thread(runnable).start();
}
The result was the same, but when I used the trick with Thread.sleep(250);
ProgressDialog was shown during the database request. But it is not spinning,
it looks freezed during the DB request.
DB stuff is called this way (after tap on search button):
btnSearchAll.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// AsyncTask
new GetDataFromLangDB().execute(edtTextToSearch.getText().toString());
// or Thread
//startProgress(null, edtTextToSearch.getText().toString());
}
});
I found a lot of problems like this in SO, but nothing was useful for me.
Could it be that DB is on SD Card?
I put the definition of the dialog into the AsyncTask Class and it works fine for me.
Take a look at this exampel (You have to change NAMEOFCLASS in the name of your CLASS:
private class doInBackground extends AsyncTask<Integer, Integer, Void> {
final ProgressDialog dialog = new ProgressDialog(NAMEOFCLASS.this) {
#Override
protected void onPreExecute() {
dialog.setCancelable(false);
dialog.setTitle(getString(R.string.daten_wait_titel));
dialog.setIcon(R.drawable.icon);
dialog.setMessage(getString(R.string.dse_dialog_speichern));
dialog.show();
}
#Override
protected void onCancelled() {
dialog.cancel();
}
....
#Override
protected void onProgressUpdate(Integer... values) {
// DO YOUR UPDATE HERE
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
}
}
Maybe this SO answer could help you. It looks like similar problem. Try to use AsyncQueryHandler for querying your database
declare you Dialog box on Class (Activity) level like this
private ProgressDialog dialog = null;
show the progress dialog and call the AsyncTask class when you want to start you Busy work..like onButton click or any
dialog = ProgressDialog.show(this,"Sending Email to your account please! wait...", true);
SendingEmailTask task = new SendingEmailTask();
String s = "";
task.execute(s);
create your inner class like
private class SendingEmailTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
//do your work here..
// like fetching the Data from DB or any
return null;
}
#Override
protected void onPostExecute(String str) {
//hide progress dialog here
dialog.dismiss();
}
}
let me know if this help!!