从服务中更新UI(使用处理程序?)

5
我正在尝试在接收到通知时更新FirstActivity的用户界面,但是对于runOnUiThreadRunnableHandler感到困惑。以下是我的代码:我运行FirstActivityNotificationService。当NotificationService收到通知时,它将更新FirstActivity的用户界面。

我还有另一个服务AlarmService在运行。

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

通知服务

    //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中添加额外的代码吗?

你能展示一下你从logcat获取的日志信息吗?另外,你是如何声明Looper的? - Alan Moore
1
我遇到了“无法在未调用Looper.prepare()的线程内创建处理程序”的错误。 Looper在上面的“showNotification”方法中声明。 - newbie
你会得到这个错误是因为你在UI线程上运行代码,这个线程已经拥有了Looper的生命周期。为了避免这个错误,你可以删除 Looper.prepare(),但这样做没有任何意义,因为 Looper.loop() 会阻塞整个线程,你的应用程序的UI将不再工作或响应! - Davide Cannizzo
3个回答

6

5

我一直都是让服务发送广播,然后在我的Activity中有一个BroadcastReciever监听这个广播。这种方法比你上面概述的方法简单得多。


0

我不知道你为什么要放一个Looper。

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

    }
});

因为UI(主)线程已经有一个Looper/Handler等等..

即使它能够工作,Looper.loop()也会阻塞,由于您正在UI线程上运行它,它将阻塞UI线程,这不是您想要的。

你真正想做的是

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

你其实不需要做所有这些花哨的东西来获取Activity

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

假设服务和活动都在同一个进程中运行,您可以只保存对活动的引用,但要注意在活动被销毁时更新引用。

服务和活动都在同一进程中运行。保存活动的引用是什么意思?我尝试使用FirstActivity.runOnUiThread - newbie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接