В андроиде Почему мой ProgressBar зависает? - PullRequest
4 голосов
/ 30 ноября 2011

Я показываю индикатор выполнения во время получения данных с сервера и после получения данных с сервера, показывающих эти данные на графике, но во время отображения этих данных на графике мой индикатор выполнения зависает, у кого-то есть идея, почему это так. .....

СПАСИБО заранее ...

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();           
    }
};  

этот обработчик я использую который вызывается после завершения получения данных и по нажатию кнопки я получаю данные и показываю индикатор выполнения

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();
        }
    });

Ответы [ 4 ]

2 голосов
/ 30 ноября 2011

Помните, что андроид хранит в памяти ссылку дилогов. так что не нужно его воссоздавать снова и снова. поэтому в первый раз диалоговое окно работает нормально, но в следующий раз зависает / застревает.

ПРИМЕЧАНИЕ: Android не очищает ссылки памяти из Dilogs даже после их закрытия.

существует метод Activity класса с именем removeDialog(int id), это также очистит ссылки на память.

Вот как вы можете отображать и удалять диалоги

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);
    }

Теперь просто позвоните showDialog(0), чтобы отобразить диалоговое окно, и removeDialog(0), чтобы скрыть его.

1 голос
/ 30 ноября 2011

Вы должны сделать это с помощью AsyncTask (интеллектуальный фоновый поток) и ProgressDialog

AsyncTask позволяет правильно и легко использовать поток пользовательского интерфейса.Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

Асинхронная задача определяется вычислением, которое выполняется в фоновом потоке и результат которого публикуется впоток пользовательского интерфейса.Асинхронная задача определяется 3 общими типами, называемыми Params, Progress и Result, и 4 шагами, называемыми begin, doInBackground, processProgress и end.

4 шага

При выполнении асинхронной задачи задача проходит 4 этапа:

onPreExecute(), вызываемых в потоке пользовательского интерфейса сразу после ее выполнения.Этот шаг обычно используется для настройки задачи, например, показывая индикатор выполнения в пользовательском интерфейсе.

doInBackground(Params...), вызывается в фоновом потоке сразу после завершения выполнения onPreExecute ().Этот шаг используется для выполнения фоновых вычислений, которые могут занять много времени.Параметры асинхронной задачи передаются на этот шаг.Результат вычисления должен быть возвращен этим шагом и будет возвращен к последнему шагу.Этот шаг также может использовать publishProgress (Progress ...) для публикации одной или нескольких единиц прогресса.Эти значения публикуются в потоке пользовательского интерфейса на шаге onProgressUpdate (Progress ...).

onProgressUpdate(Progress...), который вызывается в потоке пользовательского интерфейса после вызова publishProgress (Progress ...).Время выполнения не определено.Этот метод используется для отображения любой формы прогресса в пользовательском интерфейсе, пока выполняется фоновое вычисление.Например, его можно использовать для анимации индикатора выполнения или отображения журналов в текстовом поле.

onPostExecute(Result), вызывается в потоке пользовательского интерфейса после завершения фоновых вычислений.Результат фонового вычисления передается на этот шаг в качестве параметра.Правила потоков

Для правильной работы этого класса необходимо соблюдать несколько правил потоков:

Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.execute (Params ...) должен быть вызван в потоке пользовательского интерфейса.Не вызывайте onPreExecute (), onPostExecute (Result), doInBackground (Params ...), onProgressUpdate (Progress ...) вручную.Задача может быть выполнена только один раз (исключение будет выдано, если будет предпринята вторая попытка.)

Пример кода
То, что адаптер делает в этом примере, не важно, болееВажно понимать, что вам нужно использовать AsyncTask для отображения диалогового окна прогресса.

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();
    }
}
0 голосов
/ 24 февраля 2015

Та же проблема, с которой я столкнулся

Просто посмотрите мой пример кода. ты поймешь.

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);
}

Это сработало для меня .. Надеюсь, это вам поможет

0 голосов
/ 30 ноября 2011

Это потому, что вы начинаете обновлять свой интерфейс еще до того, как закрыли или закрыли свой диалог. Это причина вашего прогресса.

Так что измени свой код так,

     pd.dismiss();  
    runOnUiThread(t);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...