In my application , I have a listview and each item has a button. If user clicks the button ,i want to execute some http connection. So i use AsyncTask in the Adapter class. Now the problem is progress dialog is not showing.
private class MyClass extends AsyncTask<Void, Long, Boolean> {
private Context context;
private ServerCall call = new ServerCall();
private ProgressDialog progressDialog1;
public MyClass(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
progressDialog1 = ProgressDialog.show(context, "",
"Please wait...", true);
progressDialog1.setIndeterminate(true);
} catch (final Throwable th) {
}
}
#Override
protected void onProgressUpdate(Long... values) {
super.onProgressUpdate(values);
}
#Override
protected Boolean doInBackground(Void... params) {
//some tasks
return true;
}
#Override
protected void onPostExecute(Boolean result) {
if (mode.equalsIgnoreCase("History")) {
Intent order = new Intent(context, ActicityA.class);
order.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(order);
} else {
Intent order = new Intent(context, ActivityB.class);
order.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(order);
}
}
}
Try this instead'
protected void onPreExecute() {
dialog = new ProgressDialog(Activity.this);
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
//dialog.setCancelable(false);
dialog.show();
}
Follow this steps
[0] start showing progressbar
[1] Execute AsyncTask class
[2] in this class one interface for post the response in main class
[3] Declare one interface class
[4] get Reponse in Main Clss using interface
[5] dismiss Progressbar and Bind your Data
ex.
[0]
progr.setVisibility(View.VISIBLE);
[1]
MyTask task = new MyTask();
task.setdata(new SendData() {
[4] #Override
public void GetStringResponse(String str) {
Log.i(General.TAG, TAG + " Overide GetString-"+str);
final String GetResponse=str;
// here you get response and parse it
[5] // here you can dismiss your progress bar
}
});
task.execute(new String[] {Newsurl[Id]});
[2] Add interface here with Method
SendData objsend;
#Override
protected void onPostExecute(String Result)
{
Log.i("**********", Result);
objsend.GetStringResponse(Result);
}
public void setdata(SendData sendd)
{
Log.i(General.TAG,TAG+"Initialise Interface object");
objsend = sendd;
}
[3] interface class
public interface SendData {
public abstract void GetStringResponse(String str);
}
<pre><code>
public MyClass(Context context) {
this.context = context;
progressDialog1=new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
progressdialog1.setMessage("please wait while loading");
progressdialog1.setIndeterminate(true);
}
Its true that ProgressDialog.show() method returns a ProgressDialog obect, but its better to first create an object of ProgressDialog like:
ProgressDialog progressDialog1 = new ProgressDialog();
and then
progressDialog1 = ProgressDialog.show(context, "",
"Please wait...", true);
And also, try to finish the progressDialog1 in onPostExecute() by calling its dismiss() method.
Related
I have problems with showing up a ProgressDialog:
The following snippet shows my code in an example:
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
progressDialog = new ProgressDialog(Context);
progressDialog.SetCancelable(false);
progressDialog.SetMessage("Saving ...");
}
private void Method()
{
progressDialog.Show();
var testDialog = progressDialog.IsShowing;
SaveImage();
}
private void SaveImage()
{
// does lot
...
// especially this method takes some time
mutableBitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
}
I create a ProgressDialog, which I want to show before calling the SaveImage Method (and Cancel it when SaveImage is done).
My problem is that the ProgressDialog will not be displayed until the SaveImage Method is done.
In Debug-Mode, progressDialog.IsShowing is true, before the SaveImage-Method is called, but it is not displayed.
You will have to shift your IO related code to a background thread, you can use an asynctask for this
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private String resp;
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params) {
saveImage();
}
#Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
progressDialog.dismiss();
}
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(getContext(),
"ProgressDialog",
"Loading");
}
}
I found a solution that works fine for me:
private async void Method()
{
progressDialog.Show();
var thread = new System.Threading.Thread(new ThreadStart(delegate
{
SaveImage();
}));
thread.Start();
while(thread.ThreadState == ThreadState.Running)
{
await Task.Delay(100);
}
progressDialog.Dismiss();
}
Meanwhile, I outsourced this code into a public static class ThreadHelper, that just takes an Action (in this case SaveImage()) and a ProgressDialog as parameters.
I am executing an AsyncTask from inside a DialogFragment but the progress bar is not shown during doInBackground. Here is the code:
public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>
{
ProgressDialog prg;
ActionBarActivity activity;
GetResponseFromGetCustomer listener;
public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer listener)
{
this.activity = activity;
this.listener = listener;
prg = new ProgressDialog(activity);
prg.setMessage("Lütfen Bekleyin");
Log.i("ED","Progress will be shown");
prg.show();
}
#Override protected String doInBackground(Void... params)
{
//some stuff
}
#Override protected void onPostExecute(String s)
{
listener.getResponseFromGetCustomer(s);
if (prg.isShowing())
{
prg.dismiss();
}
}
and where I call it:
public class B1_PhoneNumberFragment extends android.support.v4.app.Fragment
{
...
buttonLogin.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
...
PhoneNumberVerified dialog = new PhoneNumberVerified();
dialog.show(getFragmentManager(), "NumberVerifiedByUser");
}
...
}
....
public class PhoneNumberVerified extends DialogFragment
{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Format of this dialog will be changed
builder.setMessage("Numaranız doğru mu?\n" + "0" + number)
.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,
int id)
{
GlobalApplication.getUser().setPhone(
(excludeParanthesis
(number)));
//AsyncTask is not working properly,
// progress dialog is not shown and code flows before
// response is set to s
GetCustomerSoapAsync getCustomerSoapAsync =
new GetCustomerSoapAsync(
(ActionBarActivity) getActivity(),
new GetResponseFromGetCustomer()
{
#Override
public void getResponseFromGetCustomer
(String s)
{
response = s;
}
});
getCustomerSoapAsync.execute();
Log.i("ED", "Response after GetCustomerSoapAsync callback: " +
response);
}
And finally, maybe because of the flawed flow of the tasks or maybe something else, the callback can't do its job, and response is not set to return value of the AsyncTask.
Thanks for any help!
You should use onPreExecute :
class Task1 extends AsyncTask<Object, Void, String []> {
/** The Progress dialog. */
private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);
/**
* Set the Progress dialog.
*/
protected void onPreExecute()
{
super.onPreExecute();
this.dialog.setMessage("Loading...");
this.dialog.show();
dialog.setCanceledOnTouchOutside(false);
}
protected String[] doInBackground(Object... params) {
///
}
protected void onPostExecute(String [] result)
{
super.onPostExecute(result);
this.dialog.dismiss();
}
}
To call it you should:
Task1 myTask = new Task1();
myTask.execute(stopArrey, start, end);
Hope it helped! :)
You need to operate on the ProgressDialog only on the UI Thread.
The constructor on the asynctask gives great flexibility enough to put the task in it's own class. Note: It's important that any field that is initialized in the Constructor on your custom AsyncTask takes advantage of the java final keyword so the field variables get automatic null for garbage collection.
Solution ProgressDialog code needs to be invoked in onPreExecute() where the task is still on the UI thread.
public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>
{
ProgressDialog prg;
// use final for fields initialized in a constructor.
final ActionBarActivity activity;
final GetResponseFromGetCustomer listener;
//The example below passes in the ProgressDialog from the caller where it's already shown. Pass it in to have access in the async tasks publish Progress method. Dismiss the ProgressDialog in the listener method; You didn't show your listener so this is just a technique
public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer listener, ProgressDialog prg)
{
this.activity = activity;
this.listener = listener;
this.prg = prg;
// or move this code to onPreExecute() where it runs on the UI thread.
// move this code to onPreExecute()
//prg = new ProgressDialog(activity);
//prg.setMessage("Lütfen Bekleyin");
//Log.i("ED","Progress will be shown");
//prg.show();
}
Ok the issue I believe is you have to declare the PD in the layout visible to the user before the Aysnch task is executing.
For example:
//Declare the pd here. Pd private to class.
private ProgressDialog pd;
builder.setMessage("Numaranız doğru mu?\n" + "0" + number)
.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener()
{
....
pd = ProgressDialog.show(getActivity(), "",
"Your Message Here!!!", false);
// Now using a modified constructor call your execute function
//Previous parametes + pd
GetCustomerSoapAsync gCSA = new GetCustomerSoapAsync(...,...,pd);
getCustomerSoapAsync.execute();
}
Then in your Asynch class:
public class GetCustomerSoapAsync extends AsyncTask<Void, Void, String>
{
ProgressDialog prg;
ActionBarActivity activity;
GetResponseFromGetCustomer listener;
public GetCustomerSoapAsync(ActionBarActivity activity, GetResponseFromGetCustomer listener,ProgressDialog pd)
ProgressDialog prg;
{
this.activity = activity;
this.listener = listener;
this.prg = pd;
}
#Override protected String doInBackground(Void... params)
{
//some stuff
}
#Override protected void onPostExecute(String s)
{
listener.getResponseFromGetCustomer(s);
if (prg.isShowing())
{
prg.dismiss();
}
}
Ps: I don't know if you are using fragments as a implementation but if you are you must refer to the same pd you called in the onclick function in the fragment via rootview else you might be calling functions on a progresss dialog that never showed in the first place.
So I am completely new to Andorid programming and can't seem to get a ProgressDialog to show on a ListActivity (ScheduleActiviy in my example) when running an AsyncTask from a separate class (GetGames in my example). I am attempting to use separate class for code re-usability. When I previously had the AsyncTask as an embedded class it seemed to work. I have posted what I believe to be all the relevant code. Any help would be great. Thanks!
ScheduleActivity.java
public class ScheduleActivity extends ListActivity
{
private final String PDIALOG_MSG = "Loading schedule...";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.schedule);
ArrayList<HashMap<String, String>> gamesList = null;
try
{
// Loading information in Background Threads
gamesList = new GetGames(ScheduleActivity.this, PDIALOG_MSG).execute().get();
GetGames.java
public class GetGames extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>
{
private Context context;
private ProgressDialog pDialog;
private String pDialogMsg;
public GetGames(Context ctx, String dialogMsg)
{
context = ctx;
pDialogMsg = dialogMsg;
}
#Override
public void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(context);
pDialog.setMessage(pDialogMsg);
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
public void onPostExecute(ArrayList<HashMap<String, String>> rtnList)
{
pDialog.dismiss();
}
Your ProgressDialog should probably be controlled on the Activity level instead of the AsyncTask level. Theoretically I don't see why how you're doing it wouldn't work, but I can show you a method which definitely works (it's what I do) and it organizes things a bit differently:
//In AsyncTask
#Override
protected void onPreExecute() {
showProgressDialog(R.string.importing_pages);
}
#Override
public void onPostExecute(Boolean b) {
hideProgressDialog();
}
//In Activity
public void showProgressDialog(int msgResId) {
showProgressDialog(getString(msgResId));
}
public void showProgressDialog(String msg) {
mProgressDialog = ProgressDialogHelper.buildDialog(this, msg);
mProgressDialog.show();
}
public void hideProgressDialog() {
if(mProgressDialog != null)
mProgressDialog.dismiss();
}
//My progress dialog helper class:
public class ProgressDialogHelper {
/**
* Creates a generic progress dialog with the specified message
*
* #param activity the activity which hosts the dialog. This must be an activity, not a context.
* #param msgResId the resId for the message to display
* #return a progress dialog
*/
public static ProgressDialog buildDialog(Activity activity, int msgResId) {
return buildDialog(activity, activity.getApplicationContext().getString(msgResId));
}
/**
* Creates a generic progress dialog with the specified message
*
* #param activity the activity which hosts the dialog. This must be an activity, not a context.
* #param msg the message to display
* #return a progress dialog
*/
public static ProgressDialog buildDialog(Activity activity, String msg) {
ProgressDialog dialog;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
dialog = new ProgressDialog(new ContextThemeWrapper(activity, android.R.style.Theme_Holo_Dialog));
else
dialog = new ProgressDialog(activity);
dialog.setMessage(msg);
dialog.setCancelable(false);
return dialog;
}
}
You don't have to make a helper class if you don't want to, it's just how I organized it. The main idea here is that the progress dialog should be owned by the Activity instead of the AsyncTask.
Also, the context used must be the activity's, not getApplicationContext(). It looks like you have that part right though.
You can display Progress Dialogs using AsyncTasks. That's not a problem. I do it all the time. What may be the problem is the doInBackground() method. What do you have there?
I also generally nest the AsyncTasks within the Activity class, so that it can call other Activity class methods in the onPostExecute() method. Otherwise, in order for it to communicate back with your Activity you'll have to use something like a handler or static references.
public class TestActivity extends Activity {
private AsyncTask<Void, Void, ArrayList<String>> bgLoader;
private ArrayList<String> listOfStuff;
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
listOfStuff = new ArrayList<String>();
textView = (TextView) findViewById(R.id.textView);
textView.setText("Your list has " + listOfStuff.size() + " items in it!");
bgLoader = new MyAsyncTask(this, "Waiting...").execute();
}
private void resumeDoingStuff() {
try {
listOfStuff = bgLoader.get();
textView.setText("Your list has " + listOfStuff.size() + " items in it!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public class MyAsyncTask extends AsyncTask<Void, Void, ArrayList<String>> {
private ProgressDialog progressDialog;
private String message;
private Context ctx;
public MyAsyncTask(Context context, String message) {
this.ctx = context;
this.message = message;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(ctx);
progressDialog.setMessage(message);
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected ArrayList<String> doInBackground(Void... params) {
ArrayList<String> retList = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
try {
retList.add("TEST STRING " + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return retList;
}
#Override
protected void onPostExecute(ArrayList<String> result) {
progressDialog.dismiss();
resumeDoingStuff();
}
}
}
The progress dialog in AsyncTask does not dismiss, even though progressDialog.dismiss is run in onPostExecute().
I have tried implementing many answers to related questions on SO, with no success so far.
I am sure that I must be overlooking something very basic, but I am stuck.
Any pointers to an explanation and code snippet would be great, Thanks.
Main
public class Main extends Activity {
String result;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
asyncTask task = new asyncTask("Loading ...", this);
try {
result = task.execute("Question").get();
}
catch (Exception e) {
Log.e("Error: ", e.toString());
}
}
}
asyncTask
public class asyncTask extends AsyncTask<String, Void, String> {
private ProgressDialog progressDialog;
private String message;
private Context context;
public asyncTask(String msg, Context ctx) {
this.context = ctx;
message = msg;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);
progressDialog.show(context, "", message, true, false);
}
#Override
protected String doInBackground(String... params) {
int count = 100000;
for (int i = 0; i < count; i++) {
// waste time
}
return "Answer";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.dismiss();
}
}
Actually your are doing :
progressDialog.show(context, "", message, true, false);
instead it should be like :
progressDialog = ProgressDialog.show(context, "", message, true, false);
You have to statically call show method and assign it to your progressDialog
Make this changes in your onPostExecute
#Override
protected void onPostExecute(String result) {
try{
if(progrssDialog.isShowing()){
progressDialog.dismiss();
}
}
catch(Exception e){
e.printStackTrace();
}
finally
{
progressDialog.dismiss();
}
}
A common issue i have found is the Variable Scope.
Most times , the ProgressDialog will be defined inside a Method , which wont be accessable outside that method.
You need to Declare it like so ,
Public Class MainActivity extends Activity {
ProgressDialog progressDialog;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private class asyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.dismiss();
}
}
replace
task.execute("Question").get();
with
task.execute("Question");
by calling .get() you forcing main thread to wait. It will/can hang your UI.
progressDialog.dismiss();
put this in doInBackground() method before Return Statement.
I currently have a class UserFunctions that does all my user actions e.g. register, login etc. In the UserFunctions class there's a JSONParser object that does all the actual HTTP calls and returns the JSONObject.
public class UserFunctions {
private JSONParser jsonParser;
private static String registerURL = Constants.registerUrl;
// constructor
public UserFunctions(){
jsonParser = new JSONParser();
}
public JSONObject register(){
// getting JSON Object
JSONObject json = jsonParser.getJSONFromUrl(registerURL);
// return json
return json;
}
...
}
and then in my event handler of my activity classes I just do UserFunctions.register().
My question is, I now want to do all these calls in a background thread and at the same time show a ProgressDialog. I know running in the background thread is achieved with the AsyncTask.
But how should I achieve this design such that I can still do UserFunctions.register() in my Activity class, everything to be done in a background thread and a progressDialog shown.
Ok for this there are two parts the progress dialog and the async task, you need to move your JSONparser into the actual async task. If you want to use multiple progress dialogs just call them before calling the asynctask and close them when it returns
private class JsonRetriever extends AsyncTask<Url, Void, JSONObject>{
private JSONParser jsonParser;
private ProgressDialog dialog;
public JsonRetriever(Context c){
dialog= new ProgressDialog(c);
jsonParser= new JSONParser();
}
protected void onPreExecute() {
dialog.setMessage("Starting retrieval");
dialog.show();
}
protected JSONObject doInBackground(Url... params) {
try{
return jsonParser.getJSONFromUrl(params[0]);
}catch(Exception e){
return false;
}
return true;
}
protected void onPostExecute(final JSONObject success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
Then to call this just do
public JSONObject register(){
return new JSONRetriever(this).execute(registerURL).get();
}
Do as the following:
1)Declare you dialog in activity class like this:
ProgressDialog dialog;
2)then declare you AsyncTask as below:
private class RegisterUser extends AsyncTask<String,Integer,String>{
String nessage="";
#Override
protected void onPreExecute(){
dialog = ProgressDialog.show(context, "Registering user",
"Please wait.....");
}
#Override
protected String doInBackground(String... params) {
// provide yourcode to register the user then return message
return message="you are registered";
}
protected void onPostExecute(String result) {
dialog.dismiss();
if (result.equlas("you are resgisted"))
// optinal if you want to do as below
// do something here showing toast or any thing of your prefreance
}
}
Would this help you?
#Override
public void onCreate(Bundle savedInstanceState) {
new MyAsyncTask(this).execute();
}
privateclass MyAsyncTask extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog;
private Context context;
public ProgressTask(Context context) {
this.context= context;
dialog = new ProgressDialog(context);
}
protected void onPreExecute() {
this.dialog.setMessage("Progress start");
this.dialog.show();
}
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
protected Boolean doInBackground(final String... args) {
// do you registering or whether here
// in this model you can return a boolean to the PostExecute.
}
}
Have a look at publishProgress() from the AsyncTask-Class i think its what you are looking for.
This method is used for updating the UI, when the Background-Thread done some Work. You can call it when ever you want it in the doInBackground()-Method.