2014-05-14 57 views
1

我在Android上定义了一个按钮,点击后我需要 来读取一些数据。在这样做的步骤如下所示:将handleMessage中的参数传递给点击后的按钮

1-的OnStart(),我打电话给一个线程如下:

mConnectedThread = new ConnectedThread(mmSocket); 
mConnectedThread.start(); 

2-“运行”以上线程的公共函数使得一些计算,然后将结果发送回消息处理程序如下所示:

msg_handler.obtainMessage(READ_BUF_HAS_UP_STATUS, num_of_read_bytes, -1).sendToTarget(); 

3-消息处理程序已经被定义为在的onCreate如下:

 msg_handler = new Handler() { 
     public void handleMessage(android.os.Message msg) { 
      switch (msg.what) { 
       // if received buffer has any data, then process it here: 

       case READ_BUF_HAS_UP_STATUS: 

        up_idle_status_byte = readBuf[0]; 
        n_bytes = msg.arg1; 
        Log.d(TAG, "....We have received the up status! And it is: "+up_idle_status_byte); 

        break; 
      } 
     } 

     ; 
    }; 

4-从上述线程读取状态的“readStatus”按钮在“onCreate”中定义如下。如下面所示,为了mConnectedThread.readStatusReg()的调用将导致状态被读取从其随后被移交给上述消息处理线程的“运行”过程回:

 readStatus.setOnClickListener(new View.OnClickListener(){ 
     @Override 
     public void onClick(View v){ 
      mConnectedThread.readStatusReg(); 
      while (!msg_handler.hasMessages(READ_BUF_HAS_UP_STATUS)) { 
        try { 
         Log.d(TAG, "There is NO message from msg_handler yet"); 
         TimeUnit.MILLISECONDS.sleep(80); 
        } catch (InterruptedException e) { 
         String msg = "clicked readStatus and an exception occurred when sleeping for some time" + e.getMessage(); 
         errorExit("Fatal Error", msg); 
        } 
       } 
      } 
      if (up_idle_status_byte == (byte) 0x01){ 
        //do something 
      } 
      else{ 
        //do something else 
      } 
    }); 

的问题是由消息处理程序捕获的“up_idle_status_byte”值不会被此按钮事件看到[它总是在上面的“else”语句中结束)。如果消息处理程序与按钮活动并行 - 我怀疑是这样 - 我会想象按钮处理程序应该能够最终看到正确的状态值。但事实并非如此,消息处理程序似乎是按顺序运行的。这意味着无论我在按钮处理程序循环中暂停多少次,我都不会看到通过“if(up_idle_status_byte ==(byte)0x01)”正在执行的路径。 只要按钮活动退出,消息处理程序的顺序方式就会显示up_idle_status_byte的值被正确设置为1! [请注意,up_idle_status_byte被定义为全局变量]

那么,为什么我不能看到在handleMessage中创建的任何参数,同时在按钮中单击[单击[抱歉,如果这是一个新手问题,但我再也没有声明!! ...]

非常感谢您的意见和建议。

+0

我对你使用此方法有点困惑。所以你想完成的是一些后台工作,然后让它可以访问UI?为什么当你点击readStatus时要等待实际的工作? –

+0

我正在尝试读取设备的状态,可能需要一段时间。但无论如何,问题不在于我在等待某些读取数据,但我为什么消息处理程序设置此全局“up_idle_status_byte”,而按钮活动(或您所说的UI)无法设置检测到。 – user3637785

+0

从你的代码看来,处理程序和点击处理程序都在同一个线程上运行 - 因此被同一个Looper消息队列服务,这就是为什么它们按照你说的行事。总的来说,我不知道这是你尝试实现的伟大架构。你可以考虑使用类似于IntentService的东西来处理阻塞调用,然后使用PendingIntent在完成时通知主Activity活动线程。 –

回答

0

问题出在这里:没有与消息处理程序并行运行的“按钮活动”。按钮的onClick()代码在主处理程序的消息内部运行,就像您的代码读取状态一样。

你在这里要做什么 - 做出网络请求在同一个按钮监听器中接收到该请求的结果是不可能的。主线程上的每个工作单元都必须很小,因此您需要让按钮发出请求,然后在请求完成时(可能在消息处理程序内部)完成剩余工作。

如果您指的是我们的书(强制性插件:Big Nerd Ranch Guide to Android Programming),我强烈建议根据说明和理解它们的工作原理构建第26章和第27章的示例练习。做这件事和试图阅读和樱桃选择一小块理解之间有一个世界的区别。

+0

我同意。在Android上进行线程化意味着要对APK中给出的所有底层机制有深入的了解。编写完整的示例并充分了解这些工具应该如何使用真的没有替代品。否则,很容易迷路并错误地实现模式。 –

+0

比尔感谢您的回复(和顺便说一句,这本书是一本很棒的书)。很高兴知道为什么我的方法不起作用,但我现在面临的问题是我的程序中的不同按钮会对不同的内存段进行不同的读取操作。对这些阅读的回应将因世卫组织启动阅读而有所不同。因此,如果我的方法不起作用,那么无论我使用“单独的部分”还是“消息处理程序内部”,这些方法都需要以某种方式查明世卫组织启动了阅读并采取适当行动。 – user3637785

+0

当你说世界卫生组织在这里你是指启动呼叫的按钮?那么每个按钮都会导致与设备的不同读取是否正确? –

0

好吧我真的认为你应该考虑这个应用程序的以下架构。 有三个主要步骤:

  1. 当一个按钮被点击,发送(按钮特定的)信号到IntentService
  2. 的IntentService执行取决于OPCODE
  3. 的IntentService完成工作后,将适当的动作,它将结果返回给调用活动

如果您使用PendingIntents,则在该服务完成之后,您将使用onActivityResult在您的活动中获得回调。在onActivityResult中,你会知道它是哪个结果,因为当你从按钮启动服务时,你发送了一个唯一的int值来标识调用者。因此,您可以根据调用者的身份以不同的方式处理您获得的每个结果的回报。

至于代码去,再次我是指你http://blog.vaporstream.com/blog/2013/07/09/concurrency-patterns-intent-service/

相关问题