Pragnani
Pragnani

Reputation: 20155

progress dialog is not displaying in async task when asynctask is called from separate class

I have posted a question Progress Dialog is not displaying while getting data from separate thread class but I haven't got the appropriate answers. I have already used async task to display progress dialog but it is not displaying. here is the sample code

public class JsonData extends AsyncTask<String, String, String> {
private ProgressDialog mProgressDialog;
Context context;


public JsonData(Context context) 
{
        this.context=context;
     mProgressDialog = new ProgressDialog(context);
     mProgressDialog.setMessage("Loading Please Wait.");
     mProgressDialog.setIndeterminate(false);
     mProgressDialog.setMax(100);
     mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
     mProgressDialog.setCancelable(true);
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    mProgressDialog.show();
}

@Override
protected String doInBackground(String... aurl) {
    String results="";
    try {
         int k=0;
         URL url1;
             url1 = new URL(aurl[0]);
             InputStream input=url1.openStream();
             BufferedInputStream bis=new BufferedInputStream(input);
             ByteArrayBuffer baf=new ByteArrayBuffer(1000);
             while((k=bis.read())!=-1)
             {
             baf.append((byte)k);
             }
             results=new String(baf.toByteArray());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return results;
}


@Override
protected void onPostExecute(String jsondata) {
   mProgressDialog.dismiss();
}
}

Here is the method in which I have called the async task

 private void getRecordsByCount(final String data) {
        try {
            int color=Color.BLACK;
            tableLayoutGrid.removeAllViews();
            final String[] details = data.split("_");
            SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
            String formattedDate = df.format(new Date());
            String url = ipaddress + "/GrantLeavesList?Companyid=" + user_info.get("CompanyId") + "&divisionid=" + details[3] + "&userid=" + user_info.get("userid") + "&roleid="
                    + user_info.get("RoleId") + "&Employeeid=" + user_info.get("EmployeeId") + "&leavetypeid=" + staticDetails.get(details[0]) + "&strStatus=" + staticDetails.get(details[1])
                    + "&type=" + staticDetails.get(details[2]) + "&Date=" + formattedDate;

            String url2=ipaddress + "/GrantLeavesChildList?Companyid=" + user_info.get("CompanyId") + "&divisionid=" + details[3] + "&userid=" + user_info.get("userid") + "&roleid="
                    + user_info.get("RoleId") + "&Employeeid=" + user_info.get("EmployeeId") + "&leavetypeid=" + staticDetails.get(details[0]) + "&strStatus=" + staticDetails.get(details[1])
                    + "&type=" + staticDetails.get(details[2]) + "&Date=" + formattedDate;




            JsonData jdata=new JsonData(context);
            jdata.execute(url,null,null);
            String jsonString=jdata.get();
            JSONObject obj=new JSONObject(jsonString);

            JsonData jdataChild=new JsonData(context);
            jdataChild.execute(url2,null,null);
            String jsonChildString=jdataChild.get();
            JSONObject objchild=new JSONObject(jsonChildString);



            btnGrantSubmit.setVisibility(View.GONE);
            if (obj != null) {

                leaveforwardcounts = obj.getJSONArray("Table1");
                leaveforwardchildcounts=objchild.getJSONArray("Table11");
                ScrollView scrollGrid = new ScrollView(this);
                TableRow datarow = new TableRow(this);
                datarow.setWeightSum(100);
                TableLayout table = new TableLayout(this);
                for (int i = 0; i < leaveforwardcounts.length(); i++) {
                    btnGrantSubmit.setVisibility(View.VISIBLE);
                    JSONObject record = leaveforwardcounts.getJSONObject(i);
                    String applicantname = record.getString("Applicant");
                    String toDate = record.getString("ToDate");
                    String noofdays = record.getString("NumberOfDays");
                    String LOP = record.getString("LOP");
                    if(LOP!=null && LOP.trim().length()!=0)
                    {
                        color=Color.RED;
                    }
                    final int id = i;
                    final Button gridbutton = new Button(this);
                    gridbutton.setText(status);
                    gridbutton.setTextColor(Color.BLACK);
                    gridbutton.setBackgroundResource(R.drawable.grdbutton_30x30);
                    gridbutton.setGravity(Gravity.CENTER);
                    gridbutton.setPadding(2, 0, 2, 0);
                    gridbutton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            changeRadioButtonState(gridbutton, id, data);
                        }
                    });
                    gridbutton.setOnLongClickListener(new OnLongClickListener() {

                        @Override
                        public boolean onLongClick(View v) {
                            setSelection(gridbutton);
                            return true;
                        }
                    });

                    TextView tvApplicantName = new TextView(this);

                    TextView tvToDate = new TextView(this);
                    TextView tvNoOfDays = new TextView(this);
                    TextView empty = new TextView(this);
                    TextView empty2 = new TextView(this);
                    if (applicantname.trim().length() >= 18) {
                        applicantname = applicantname.substring(0, 18);
                    }

                    tvApplicantName.setText(applicantname);
                    tvApplicantName.setTypeface(font2);
                    tvApplicantName.setWidth(70);
                    tvApplicantName.setTextColor(color);
                    tvApplicantName.setPadding(5, 0, 0, 0);

                    tvToDate.setText(toDate);
                    tvToDate.setTypeface(font2);
                    tvNoOfDays.setText(noofdays);
                    tvNoOfDays.setTypeface(font2);
                    tvNoOfDays.setGravity(Gravity.RIGHT);

                    Button ivDetails = new Button(this);
                    ivDetails.setText(" ");
                    ivDetails.setPadding(2, 0, 2, 0);
                    ivDetails.setBackgroundResource(R.drawable.detailsbutton_30x30);
                    ivDetails.setGravity(Gravity.CENTER);

                    ivDetails.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            leaveDetails = new PopupWindow(showLeaveDetails(id, leaveforwardcounts,data,leaveforwardchildcounts), (int) (width * 0.8), height / 2, true);
                            leaveDetails.showAtLocation(mainlayout, Gravity.CENTER, 0, 0);
                        }
                    });

                    TableRow row = new TableRow(this);

                    row.setPadding(0, 3, 0, 3);
                    row.setWeightSum(100);
                    row.addView(tvApplicantName, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 55));
                    row.addView(tvNoOfDays, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 5));
                    row.addView(empty2, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 20));
                    row.addView(ivDetails, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
                    row.addView(empty, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
                    row.addView(gridbutton, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
                    table.addView(row);
                }
                scrollGrid.addView(table);
                datarow.addView(scrollGrid, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 100));
                tableLayoutGrid.addView(datarow);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

I need to build page based on the data from Service. in my app there are about 20-30 services.. if i use async task as inner class it works well and good ...but How can reuse my code...

Upvotes: 1

Views: 1115

Answers (5)

laplasz
laplasz

Reputation: 3497

you dont need to start a background method for postExecute. as @baske wrote, you have problem with .get() - that is blocking your thread even if your are using AsyncTask. try someting related to the linked question, so only add your YourActivityClass as a param to the construdtor of JsonData

public JsonData(YourActivityClass activity) 
{
    this.activity=activity;
    mProgressDialog = new ProgressDialog(activity);

}
protected void onPostExecute(String jsondata) {
    if (mProgressDialog != null || mProgressDialog.isShowing()){
        mProgressDialog.dismiss();
    }
    if(jsondata!=null) {
        activity.yourcallback(jsondata)
    }

}

And define the yourcallback() in YourActivityClass

private void yourcallback(String data) {
    jsonRecordsData=data;
    showRecordsFromJson();

}

Upvotes: 2

baske
baske

Reputation: 1352

user, I think you need to understand better what the reasons are for using an AsyncTask and what the uses are of the callback/hook methods it provides.

Starting with the reason: if you have a long-running task, you cannot run this on the main thread (also called UI thread) because your app will eventually show ANR errors. Now if your long-running task would not need to show output on the screen (when it is done, progress reports, etc) you can very well put it in a worker thread and let it run by itself (possibly even delegating it to a Service to guarantee run-to-completion, but that is another story). However, a lot of times this isn't the case and you want to update your UI based on the outcome/progress of your long-running task. To do this you would have to somehow branch off a thread and do the work there, but, since you can only manipulate the UI from the main thread, you would have to post back the result on the main thread when you are done.

This is where we move to the AsyncTask and its hook methods. An AsyncTask is actually just a Utility class that helps you do exactly what is explained above: put your work on a separate thread and get a callback on your main thread when it is done (and the result is available). Checking the documentation you will find:

onPreExecute(): guaranteed to run on the main thread. Allows you to do stuff (like show a progress dialog) BEFORE the work starts.

doInBackground(): guaranteed to run on a background thread. Do you long running stuff here.

onPostExecute(): guaranteed to run on the main thread AFTER your doInBackground() has finished. The result of your task is now available and you can do stuff with it (like put it on the screen).

Getting back to your suggestions about your .get() method having a problem: since you are calling .execute() on your AsyncTask and .get()-ing the result immediately thereafter, chances are that the background job has not yet finished. Instead you should be doing whatever you wanted to do, starting at the .get() in the AsyncTask's onPostExecute. So if your task downloads an image and you want to show a "downloading" message to the user while it is running, you should do the following:

//pseudo code
void exampleButtonClicked() {
  new AsyncImageDownloader.execute();
}

class AsyncImageDownloader extends AsyncTask {
  onPreExecute() {
    show "downloading";
  }

  doInBackground() {
    downloadImg();
  }

  onPostExecute() {
    hide "downloading";
    put downloaded img on ImageView;
  }
}
//end of pseudo code

Hope this helps.. Not going to code out your answer, because then you would have learned nothing ;-)

Cheers!

Upvotes: 2

Deepanker Chaudhary
Deepanker Chaudhary

Reputation: 1704

Try the following:

 @Override
   protected void onPreExecute() 
  {

 mProgressDialog =ProgressDialog.show(GmailInbox.this, "", "Please Wait",true,false);
 super.onPreExecute();
  }

Upvotes: 0

NAP-Developer
NAP-Developer

Reputation: 3796

You can do on override methods onPreExecute() and implement for this code,

@Override
    protected void onPreExecute() {
        super.onPreExecute();
        ProgressDialog mProgressDialog = ProgressDialog.show(ActivityName.this, "Wait", "Loading....");
    }

and onPostExecute() method implement and dismiss the dialog,

@Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        if (mProgressDialog != null || mProgressDialog.isShowing())
            mProgressDialog.dismiss();
    }

Upvotes: 0

Durairaj Packirisamy
Durairaj Packirisamy

Reputation: 4725

You can do UI operations only from an UI thread. Try running it on an UI thread.

runOnUiThread(new Runnable() {

        public void run() {
            mProgressDialog.show();
        }
    });

Upvotes: 0

Related Questions