In android Why my ProgressBar Freezes?

2019-01-20 02:03发布

问题:

i am showing Progress Bar at time of retrieving data from server and after retrieving data from server showing that data on chart but at time of plotting that data on chart my progress bar get freezes does any one have idea why this is so......

THANKS in advance...

private ProgressDialog pd;
private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {        
        Toast.makeText(context, "Please Wait...", Toast.LENGTH_LONG).show();
        Thread t = new Thread(new Runnable() {              
            @Override
            public void run() {
                functionDrawMyData();/*in this function i am accessing activity view and drawing data on that view at time of drawing my Progress bar Freezes */
            }
        });
        runOnUiThread(t);
        pd.dismiss();           
    }
};  

this handler i am using which is called after retrieving data finished and on button click i am getting data and showing progress bar

ImageButton myButton = (ImageButton) findViewById(R.id.myBtn);
pair1ChartButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {               
                pd = ProgressDialog.show(v.getContext(),"Please wait...","Retrieving data ...",true,
                        true,
                        new DialogInterface.OnCancelListener(){
                            @Override
                            public void onCancel(DialogInterface dialog) {

                            }
                        });
                Thread t = new Thread(new Runnable() {                      
                    @Override
                    public void run() {
                            getDataFromServer();//calling function to get data from server
                        handler.sendEmptyMessage(0);                    
                    }
                });
                t.start();
        }
    });

回答1:

You should do this with the help of AsyncTask (an intelligent backround thread) and ProgressDialog

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called begin, doInBackground, processProgress and end.

The 4 steps

When an asynchronous task is executed, the task goes through 4 steps:

onPreExecute(), invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.

doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.

onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.

onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter. Threading rules

There are a few threading rules that must be followed for this class to work properly:

The task instance must be created on the UI thread. execute(Params...) must be invoked on the UI thread. Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually. The task can be executed only once (an exception will be thrown if a second execution is attempted.)

Example code
What the adapter does in this example is not important, more important to understand that you need to use AsyncTask to display a dialog for the progress.

private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
    ProgressDialog dialog;
    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(viewContacts.this);
        dialog.setMessage(getString(R.string.please_wait_while_loading));
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }
    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected ContactsListCursorAdapter doInBackground(Void... params) {
        cur1 = objItem.getContacts();
        startManagingCursor(cur1);

        adapter1 = new ContactsListCursorAdapter (viewContacts.this,
                R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});

        return adapter1;
    }

    protected void onPostExecute(ContactsListCursorAdapter result) {
        list.setAdapter(result);
        dialog.dismiss();
    }
}


回答2:

Remember android keeps the reference of dilogs in the memory. so that it does not need to recreate it again and again. so progress dialog works fine for the first time but hung/stuck for next time.

NOTE: android does not clear memory references of dilogs even after dismissing them.

there is method is Activity class named as removeDialog(int id) this will also clear memory references.

Here is how you can display and remove dialog

protected Dialog onCreateDialog(int id) {
        // TODO Auto-generated method stub
        switch(id){
          case 0:{
             dialog = ProgressDialog.show(this, "", 
                    "Loading. Please wait...", true);
             return dialog;
          }
             }

        return super.onCreateDialog(id);
    }

Now just call showDialog(0) to display dialog and removeDialog(0) to hide it.



回答3:

This is because you are starting to update your UI even before you close or dismiss your dialog. This is the reason for your progressDialog freeze.

So Change your code like this,

     pd.dismiss();  
    runOnUiThread(t);


回答4:

Same problem i too faced,i solved my self,

Just see my sample code. you will understand.

public class NearByLoc extends AsyncTask<Void, Void, Void> {
    @SuppressLint("InlinedApi")
    protected void onPreExecute() {

        // pdailog.show();
        loading_spinnerMain.setVisibility(View.VISIBLE);
    }


@Override
    protected Void doInBackground(Void... params) {
     //write your entire code [logic]here

  }
@Override
    protected void onPostExecute(Void unused) {

        //finally list of data setting to the adapter
        //before setting to the adapter you should dismiss Progress spinnerr 

        loading_spinnerMain.setVisibility(View.GONE);
        NearByMeAdapter adapter = new NearByMeAdapter(NearByMe.this, list);

        listViewNearLoc.setAdapter(adapter);
}

Its worked for me..Hope it helps you