单击时将handleMessage中的参数传递给按钮

时间:2014-05-14 18:25:44

标签: android multithreading button

我在Android上定义了一个按钮,点击后我需要 阅读一些数据。这样做的步骤如下所示:

1- OnStart(),我按如下方式调用线程:

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

2-" run"上述线程的公共函数进行一些计算,然后将结果发送回消息处理程序,如下所示:

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中创建的任何参数同时在按钮单击中可用[对不起,如果这是一个新手问题,但我再也没有声明!! ...]

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

2 个答案:

答案 0 :(得分:0)

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

您要在此处执行的操作 - 使网络请求在同一个按钮侦听器中接收该请求的结果 - 是不可能的。主线程上的每个工作单元必须很小,因此您需要让按钮发出请求,然后在请求完成时(可能在消息处理程序中)有一个单独的部分执行剩余的工作。

如果您指的是我们的书(强制性插件:Big Nerd Ranch Guide to Android Programming),我强烈建议您根据说明并了解其工作原理,为第26章和第27章构建示例练习。这样做之间存在着天壤之别,尝试阅读和挑选一小部分理解。

答案 1 :(得分:0)

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

  1. 单击按钮时,将(特定于按钮的)信号发送到IntentService
  2. IntentService根据OPCODE
  3. 执行适当的操作
  4. IntentService完成工作后,会将结果返回给调用的Activity
  5. 如果您使用PendingIntents,在服务完成后,您将使用onActivityResult在Activity中获得回调。在onActivityResult中,您将知道它是什么结果,因为当您从按钮启动服务时,您发送了一个唯一的int值来标识调用者。因此,您可以根据呼叫者的身份,以不同的方式处理您获得的每个结果的回报。

    就代码而言,我再次推荐您http://blog.vaporstream.com/blog/2013/07/09/concurrency-patterns-intent-service/