Обновление пользовательского интерфейса из службы (с помощью обработчика?) - PullRequest
5 голосов
/ 30 октября 2011

Я пытаюсь обновить свой пользовательский интерфейс в FirstActivity, когда я получаю уведомление, но смущен runOnUiThread, Runnable и Handler.Вот что у меня есть: я использую FirstActivity и NotificationService.Когда NotificationService получает уведомление, оно обновляет интерфейс FirstActivity.

У меня также работает другая служба AlarmService.Первое действие

@Override
public void onResume() {
      super.onResume();
      //some other code for alarm service
}

NotificationService

    //on receiving notification
    private void showNotification(String text) {

   //Get activity
   Class<?> activityClass = null;
     try {
         activityClass = Class.forName("com.pakage.FirstActivity");
         contextActivity = (Activity) activityClass.newInstance();

         //Update UI on FirstActivity not working
         contextActivity.runOnUiThread(new Runnable() {
             public void run()
             { 
               Looper.prepare();
               TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
               Looper.loop();

             }
             });

     } catch (Exception e) {
         e.printStackTrace();
     }

            //Shows the notification
            Notification n = new Notification();    
            //... etc   
}

У меня постоянно появляется ошибка looper.prepare.Нужно ли добавлять дополнительные коды в мой FirstActivity?

Ответы [ 3 ]

6 голосов
/ 30 октября 2011

Мой первый инстинкт заключается в том, что вместо этого вы должны привязать Activity к своему сервису и обрабатывать обновление пользовательского интерфейса на его стороне, а не Service, напрямую изменяющий Activity.1004 *http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

И пример здесь:
Пример: связь между активностью и службой с использованием обмена сообщениями

5 голосов
/ 30 октября 2011

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

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

Понятия не имею, почему вы ставите Лупер в

contextActivity.runOnUiThread(new Runnable() {
    public void run()
    { 
        Looper.prepare();
        TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
        Looper.loop();

    }
});

потому что поток UI (основной) уже имеет Looper / Handler и т. Д.

Даже если это сработало, Looper.loop() будет блокироваться, и, поскольку вы запускаете его в потоке пользовательского интерфейса, оно заблокирует поток пользовательского интерфейса, что не соответствует вашим ожиданиям.

Что вы действительно хотите сделать, это

contextActivity.runOnUiThread(new Runnable() {
    public void run()
    { 
        TextView tv = (TextView ) contextActivity.findViewById(R.id.notifyTest);
        tv.setText("do something that must be on UI thread") // or whatever
    }
});

Вам не нужно делать все эти причудливые вещи, чтобы получить задание

activityClass = Class.forName("com.pakage.FirstActivity");
contextActivity = (Activity) activityClass.newInstance();

при условии, что Сервис и Действие выполняются в одном и том же процессе, вы можете просто сохранить ссылку на Действие, но будьте осторожны при обновлении ссылки, когда Действие будет уничтожено.

...