Как я могу обновить основной интерфейс с информацией, полученной из другого потока?(Пока поток еще работает) - PullRequest
0 голосов
/ 20 августа 2011

Я пытаюсь обновить элемент экрана во время выполнения. Но я не могу заставить это работать.

Вот пример кода

public static TextView CurrentConnectionAttempt;
        CurrentConnectionAttempt = (TextView) findViewById(R.id.CurrentConnectionAttempt);

        IntentFilter afilter= new IntentFilter("SomeSortOfFilter"); 
        registerReceiver(SomeReceiver, afilter);

    private BroadcastReceiver SomeReceiver= new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {    
        for (int i = 0; i<100; 1++ ) 
        {           
            String connectionAttempt = "This is loop Iteration " + i;
            CurrentConnectionAttempt.setText(connectionAttempt);                    
            doSomething("Some Parameter");          
        }
       }
};

Я хочу, чтобы экран Textview обновлялся при каждом новом значении «i», а затем выполнял функцию. Я думаю, этот пример будет похож на индикатор выполнения.

Часть hard состоит в том, что информация обнаруживается внутри события трансляции. Таким образом, информация не найдена в основном потоке пользовательского интерфейса. Вот почему задача Async и другие многопоточные опции не работают для меня. (Согласно моему пониманию)

Я изучил эти решения.

  1. Создание работоспособного
  2. Я пробовал AyncTask
  3. Создание второго приемника вещания

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

Спасибо!

РЕДАКТИРОВАТЬ: Моя задача Async является чрезвычайно простой, что я пытался. Я даже пробовал варианты. Я думаю, что моя проблема может быть похожа на то, что я только что прочитал в этом блоге. Асинхронные проблемы

Здесь происходит то, что широковещательный приемник будет проходить через все итерации цикла, и функция doInBackground в задаче Async будет срабатывать одновременно, но никогда не будет функцией onProgressUpdate до тех пор, пока широковещательный приемник полностью не завершит выполнение. Затем onProgressUpdate и onPostExecute будут выполняться несколько раз. Я предполагаю, что, поскольку широковещательный приемник находится в отдельном потоке от пользовательского интерфейса, он должен полностью выполнить, прежде чем другая подпоток сможет работать.

Вот мой код,

В моем приемнике вещания:

    UpdateDynamicDisplay2 testDisplay= new UpdateDynamicDisplay2();
                    testDisplay.execute(connectionAttempt );

    // This is a sub class in my main class
class UpdateDynamicDisplay2 extends AsyncTask<String, String, String>{

    String Testing1;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... aurl) {
            publishProgress(aurl[0]);
            Testing1 = aurl[0];
                MyMainClass.CurrentConnectionAttempt.setText(Testing1);
            return Testing1;
        }

        protected void onProgressUpdate(String... progress) {
            MyMainClass.CurrentConnectionAttempt.setText(progress[0]);
        }

        @Override
        protected void onPostExecute(String unused) {   
            MyMainClass.CurrentConnectionAttempt.setText(unused);
        }
    }

Надеюсь, этого достаточно, чтобы уйти.

Ответы [ 3 ]

2 голосов
/ 23 августа 2011

Проблема в том, что вы пытаетесь обновить свой интерфейс напрямую из BroadcastReceiver через статические переменные.AsyncTask предназначен для использования Activity, а не BroadcastReceiver.

Лучше всего, чтобы ваш BroadcastReceiver обновил источник данных, и ваш Activity Activity следил за этим источником данных.

Если вы имеете дело с большим количеством данных, лучше всего создать ContentProvider , а затем зарегистрировать ContentObserver , чтобы получать уведомления при изменении данных.

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

Наконец, вы можете создать синглтон и хранить ваши данные в памяти, используя структуру данных.Вы можете реализовать собственную версию шаблона Observer , чтобы получать уведомления об изменениях данных.Вероятно, это не очень хорошее долгосрочное решение, поскольку среда Android не дает никаких долгосрочных гарантий относительно ваших объектов в памяти.

1 голос
/ 20 августа 2011

Этот вопрос и его ответ помогут вам понять, где именно вы должны быть!Обработчики работают, но не рекомендуется.В Android AsycTask намного лучше и удобочитаемее.

Как позволить Asynctask обновлять пользовательский интерфейс различными способами

Счастливое кодирование!

EDITED

Эта ссылка содержит некоторый исходный код для обновления индикатора выполнения, например, от 1 до 100,

http://ketankantilal.blogspot.com/2011/05/how-to-update-progress-bar-using-thread.html

Удачи

0 голосов
/ 20 августа 2011

Самый простой способ, вероятно, через обработчик

private Handler handler; //Global Decalration
...
handler = new Handler(); //This is declared in the Main UI thread (onCreate)

Тогда в вашем потоке, который выполняет работу:

handler.post(new Runnable() {
@Override
public void run() {
   CurrentConnectionAttempt.setText(ConnectionAttempt);
}
});

Надеюсь, это сработает.

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