Обновление пользовательского интерфейса из streamа

Я хочу обновить свой пользовательский интерфейс из streamа, который обновляет Progressbar. К сожалению, при обновлении индикатора progressbar от «runnable» индикатор прогресса исчезает! Изменяется onCreate() progressbars в onCreate() с другой стороны!

Какие-либо предложения?

 public void onCreate(Bundle savedInstanceState) { res = getResources(); super.onCreate(savedInstanceState); setContentView(R.layout.gameone); pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); //**Works**/ handler.postDelayed(runnable, 1); } private Runnable runnable = new Runnable() { public void run() { runOnUiThread(new Runnable() { public void run() { //* The Complete ProgressBar does not appear**/ pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); } }); } } 

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

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

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

4 шага

Когда выполняется асинхронная задача, задача выполняет 4 этапа:

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

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

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

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

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

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

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

 private class PrepareAdapter1 extends AsyncTask { 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(); } } 

Самое простое решение, которое я видел для короткого выполнения streamа UI, – это метод post () представления. Это необходимо, так как методы пользовательского интерфейса не являются повторными. Метод для этого:

 package android.view; public class View; public boolean post(Runnable action); 

Метод post () соответствует SwingUtilities.invokeLater (). К сожалению, я не нашел чего-то простого, что соответствует SwingUtilities.invokeAndWait (), но можно построить более позднюю версию с помощью монитора и флага.

Итак, что вы сохраняете, это создание обработчика. Вам просто нужно найти свое мнение, а затем опубликовать его. Вы можете найти свое мнение через findViewById (), если вы склонны работать с id-ed ресурсами. Полученный код очень прост:

 /* inside your non-UI thread */ view.post(new Runnable() { public void run() { /* the desired UI update */ } }); } 

Примечание. По сравнению с SwingUtilities.invokeLater () метод View.post () возвращает логическое значение, указывающее, имеет ли представление связанную очередь событий. Поскольку я использовал invokeLater () соответственно. post () в любом случае только для огня и забыть, я не проверял значение результата. В основном вы должны вызывать post () только после того, как onAttachedToWindow () был вызван в представлении.

С наилучшими пожеланиями

Если вы используете Handler (я вижу, что вы делаете и, надеюсь, вы создали свой экземпляр в streamе пользовательского интерфейса), тогда не используйте runOnUiThread() внутри вашей runnable . runOnUiThread() используется, когда вы делаете что-л. из streamа, runnable от UI, однако Handler уже выполнит вашу runnable в streamе пользовательского интерфейса.

Попробуйте сделать что-то вроде этого:

 private Handler mHandler = new Handler(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gameone); res = getResources(); // pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); **//Works** mHandler.postDelayed(runnable, 1); } private Runnable runnable = new Runnable() { public void run() { pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); pB.invalidate(); // maybe this will even not needed - try to comment out } }; 

Используйте class AsyncTask (вместо Runnable). У него есть метод под названием onProgressUpdate, который может повлиять на пользовательский интерфейс (он вызывается в streamе пользовательского интерфейса).

Вам нужно создать Handler в streamе пользовательского интерфейса, а затем использовать его для публикации или отправки сообщения из другого streamа для обновления пользовательского интерфейса

Если вам не нравится AsyncTask, вы можете использовать шаблон наблюдателя . В этом примере используйте ResponseHandler в качестве внутреннего classа в вашей деятельности, затем введите строковое сообщение, в котором будет задан процент выполнения баров … Вам нужно убедиться, что любые изменения в пользовательском интерфейсе выполняются в ResponseHandler, чтобы избежать замораживания UI, тогда ваш рабочий stream (EventSource в примере) может выполнить требуемые задачи.

Я бы использовал AsyncTask tho, однако шаблон наблюдателя может быть полезен по причинам настройки, а также его легче понять. Также я не уверен, что этот способ широко принят или будет работать на 100%. Im, загружающий и плагин Android, чтобы проверить его

Как рекомендовано официальной документацией , вы можете использовать AsyncTask для обработки рабочих элементов длиной менее 5 мс . Если ваша задача займет больше времени, найдите другие альтернативы.

HandlerThread – одна из альтернатив Thread или AsyncTask . Если вам нужно обновить пользовательский интерфейс из HandlerThread , HandlerThread сообщение в теме Looper и пользовательский интерфейс обработчика streamов может обрабатывать обновления пользовательского интерфейса.

Пример кода:

Android: Тост в streamе

  • Как обновить графический интерфейс из другого streamа?
  • Предоставление имени JMenuItem его ActionListener
  • Java swing JComponent "размер"
  • Как создать RecyclerView с несколькими типами просмотра?
  • Отправка сообщений между двумя объектами JPanel
  • Как создать приложение C ++ / CLI Winforms в VS2012?
  • Как сделать фотокамеру доступным?
  • Приложение C # как GUI, так и командная строка
  • Как я могу складывать / накладывать jPanels в Java?
  • java - Как бы я динамически добавлял компонент swing в gui при нажатии?
  • Сериализовать компоненты JavaFX
  • Давайте будем гением компьютера.