【问题标题】:Android Handler doesn't handle messagesAndroid Handler 不处理消息
【发布时间】:2014-06-14 22:49:48
【问题描述】:

我对此感到很困惑。我正在接受this Coursera course,并正在处理Assignment 5。我能够以最小的困难完成任务,然后继续尝试使代码达到我自己的目的。我也对其进行了一些调整,但我遇到了一个重大问题,我终生无法弄清楚。处理程序似乎根本不接收消息......知道我做错了什么吗?

这是我的一些代码。如果你还有什么想看的,请告诉我。

处理程序:

public class DownloadHandler extends Handler {
private WeakReference<Context> mContext;
public DownloadHandler(Context context) {
    super();
    mContext = new WeakReference<Context>(context);
    Log.v(TAG,"Created! "+this);
}
    // Handle any messages that get sent to this Handler
    @Override
    public void handleMessage(Message msg) {
        Log.v(TAG, "" + msg); //Never reached
                ...
       }
}

在我继续之前,我已经通过发送一个简单的消息 (handler.sendEmptyMessage(0);,没有成功。有什么想法吗?

Log.v(TAG,"handler="+handler);
Log.v(TAG,"Sending test "+handler.sendEmptyMessage(0));

还有日志猫:

06-14 22:47:34.700: V/DownloadAddOnProducts(7406): handler=Handler (com.kd7uiy.hamfinder.DownloadHandler) {527724dc}
06-14 22:47:34.700: V/DownloadAddOnProducts(7406): Sending test true

为了进一步减少这种情况,我进行了单元测试:

public class DownloadTester extends InstrumentationTestCase {
    public void setUp() {
        targetContext=getInstrumentation().getTargetContext();
    }

    public void testDownloadHandler() {
        Looper.myLooper().setMessageLogging(new LogPrinter(Log.VERBOSE,"DownloadLooper"));
        DownloadHandler handler=new DownloadHandler(targetContext,Looper.myLooper());
        Log.v(TAG,"handler="+handler);
        handler.sendEmptyMessage(0);
        Log.v(TAG,"Send empty message");
    }

logcat 显示:

06-14 23:03:46.068: V/DownloadHandler(8337): Created! Handler (com.kd7uiy.hamfinder.DownloadHandler) {52770be8}
06-14 23:03:46.068: V/DownloadHandler(8337): Created! Handler (com.kd7uiy.hamfinder.DownloadHandler) {52770f60}
06-14 23:03:46.068: V/DownloadTester(8337): handler=Handler (com.kd7uiy.hamfinder.DownloadHandler) {52770f60}
06-14 23:03:46.068: V/DownloadTester(8337): Send empty message

它创建了两个 DownloadHandler,因为另一个用于我的单元测试集中的另一个单元测试。

【问题讨论】:

  • 处理程序在哪里声明?
  • “没有成功”是什么意思?你的意思是你从来没有看到来自handleMessage()的日志?
  • 您在何处、何时以及如何实例化Handler
  • 您是否进行了任何测试以确保处理程序确实被分配?也许显示您在问题中实例化处理程序的工作流程,以提供更多线索。
  • 您的处理程序在 Activity 上下文中创建时是否工作?

标签: android service handler


【解决方案1】:

引用the documentation for Handler:

处理程序允许您发送和处理与线程的 MessageQueue 关联的 Message 和 Runnable 对象。每个 Handler 实例都与单个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它会绑定到创建它的线程的线程/消息队列——从那时起,它会将消息和可运行对象传递到该消息队列并在它们从消息中出来时执行它们队列。

引用您正在使用的the documentation for the zero-argument Handler constructor

默认构造函数将此处理程序与当前线程的 Looper 相关联。如果该线程没有 Looper,则该处理程序将无法接收消息,因此会引发异常。

如果您没有崩溃,并且您还没有创建自己的HandlerThread(或等效项),那么您的DownloadHandler 可能会将自己绑定到主应用程序线程。您发送给DownloadHandler 的消息只会在主应用程序线程处理完其消息队列中的所有其他消息后,才被传递给handleMessage() 方法。而且,只要您使用主应用程序线程(例如,执行 onCreate()Service),该消息就不会出现(并且您的 UI 将被冻结以启动)。

【讨论】:

    【解决方案2】:

    问题是我在非 UI 线程上使用了处理程序。这可以做到,但需要一些工作。完成这项工作的诀窍是确保您在有问题的线程上调用Looper.loop(),因为this question 也会引用。所以这个单元测试代码有效:

    public void testDownloadHandler() {
        Looper.myLooper().setMessageLogging(new LogPrinter(Log.VERBOSE,"DownloadLooper"));
        DownloadHandler handler=new DownloadHandler(targetContext,Looper.myLooper());
        Log.v(TAG,"handler="+handler);
        handler.sendEmptyMessage(0);
        Log.v(TAG,"Send empty message");
        Log.v(TAG,"Looper="+handler.getLooper());
        Log.v(TAG,""+Looper.myQueue());
        Looper.loop();
    }
    

    事实上,就我而言,我想在收到文件后对文件进行一些相当重要的处理,所以我不希望它在 UI 线程中运行。但我不想弄乱 Looper.loop() 并可能阻塞我的辅助线程(它是 ThreadPoolExecutioner 线程池的一部分,我不希望它挂起)。所以我决定使用 Main Looper 消息池来管理 Handler,然后让 Handler 管理一组 ThreadPoolExecutioner 池,以便在 Service 处理完数据后对数据进行后处理。

    【讨论】:

      【解决方案3】:

      尝试在活动的 onCreate() 上测试您的处理程序。

      类似于以下内容:

      protected void onCreate(Bundle savedInstanceState) { 
          super.onCreate(savedInstanceState);
      
          DownloadHandler dh = new DownloadHandler(getMainLooper());
          dh.sendEmptyMessage(0);
      }
      

      【讨论】:

      • 是的,没错,你不必在 onCreate() 上传递 mainLooper() 至少因为 onCreate() 保证在主 ui 线程上运行
      猜你喜欢
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多