Android 单击时将参数从handleMessage传递到按钮

Android 单击时将参数从handleMessage传递到按钮,android,multithreading,button,Android,Multithreading,Button,我已经在Android上定义了一个按钮,当被点击时,我需要 读回一些数据。执行此操作的步骤如下所示: 1-在启动时,我按如下方式调用线程: mConnectedThread = new ConnectedThread(mmSocket); mConnectedThread.start(); 2-上面线程的run public函数进行一些计算,然后将结果发送回消息处理程序,如下所示: msg_handler.obtainMessage(READ_BUF_HAS_UP_STATUS, num_of

我已经在Android上定义了一个按钮,当被点击时,我需要 读回一些数据。执行此操作的步骤如下所示:

1-在启动时,我按如下方式调用线程:

mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
2-上面线程的run public函数进行一些计算,然后将结果发送回消息处理程序,如下所示:

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_字节值不被此按钮事件看到[它总是在上面的else语句中结束]。如果消息处理程序与按钮活动并行运行(我怀疑是这样),我会认为按钮处理程序最终应该能够看到正确的状态值。但事实并非如此,消息处理程序似乎是按顺序运行的。这意味着,无论我在按钮处理程序循环中暂停了多少时间,如果执行up\u idle\u status\u byte==byte 0x01,我永远看不到路径。 一旦按钮活动退出,消息处理程序的顺序方式将显示up_idle_status_byte的值,以便正确设置为1!![请注意,up_idle_status_字节定义为全局变量]

那么,为什么我看不到在handleMessage中创建的任何参数在按钮单击中同时可用[很抱歉,如果这是一个新手问题,但我不是在声明其他!!…]


非常感谢您的输入和建议。

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

您在这里试图做的是发出网络请求并在同一个按钮侦听器中接收该请求的结果,这是不可能的。主线程上的每个工作单元都必须很小,因此您需要让按钮发出请求,然后让一个单独的部分在消息处理程序中完成请求后完成剩余的工作


如果您参考的是我们的书《必修的插件》,我强烈建议您根据说明构建第26章和第27章的示例练习,并了解它们是如何工作的。这是一个世界上的差异,这是一个世界上的差异,试图阅读和樱桃挑选一个小的理解。

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

单击按钮时,向IntentService发送特定于按钮的信号 IntentService根据操作码执行适当的操作 IntentService完成工作后,将结果返回给调用活动 如果您使用PendingEvents,在服务完成工作后,您将使用onActivityResult在活动中收到回调。在onActivityResult中,您将知道这是哪个结果,因为当您从按钮启动服务时,您发送了一个唯一的int值来标识调用方。因此,您可以根据调用方的身份以不同的方式处理每个结果的返回


就代码而言,我再次建议您参考

我对您在这里使用的方法有点困惑。那么,您只想完成一些后台工作,然后让UI访问它?当你点击readStatus时,你为什么要等着做实际的工作呢?我正在尝试读取设备的状态,这可能需要一些时间。但无论如何,问题不在于我在等待一些读取数据,而是我对消息处理程序为什么设置这个全局up\u idle\u status\u字节感到困惑,但是按钮活动或您所说的UI无法检测到这一点。从您的代码中可以看出,处理程序和单击处理程序都在同一线程上运行-因此由相同的循环器消息队列提供服务,这就是为什么它们会像您所说的那样运行。总的来说,我不知道这是一个很好的架构,可以实现您想要实现的目标。您可以考虑使用像ItTunService这样的操作来处理阻塞调用,然后在完成活动时通知主活动线程。安得烈感谢您的响应。但在我所看到的任何地方,都强烈建议将处理程序和UI都放在主线程上。所以我没有怀疑这会引起问题。你可能是对的,对于我正在尝试做的事情来说,这可能不是一个很好的架构,但我想我可以无视批评,因为我承认我在这篇文章中完全是新手!!你有没有一段代码可以告诉我你在说什么
esting?嗯,我在这里写了一篇关于这种模式的博文:我相信你也可以找到其他几种。我在网络访问中使用了这种模式,但它也可以很好地阻止设备调用,特别是当您需要发送多个请求/响应消息时。如果它真的只是一个调用,那么handler方法可能会起作用,但您可能需要重新考虑线程模型-例如,从查询字节的clickhandler生成一个后台线程。我同意。在Android上做好线程处理意味着对APK中给出的所有底层机制有一个坚定的理解。编写完整的示例并充分学习如何使用这些工具,实在是无可替代的。否则很容易丢失并错误地实现模式。Bill感谢您的回复,顺便说一句,这是一本很棒的书。很高兴知道为什么我的方法不起作用,但我现在面临的问题是,程序中的不同按钮会从内存的不同部分执行不同的数据读取。对这些读取的响应将因发起读取的人而异。因此,如果我的方法不起作用,那么无论我使用单独的部分,还是在消息处理程序中,这些方法都需要找出是谁发起了读取,然后采取适当的操作。当你说这里的谁是指启动调用的按钮?因此,每个按钮都会导致从设备读取不同的数据。正确吗?没错。每个按钮启动不同的读取,在收到读取结果后,它必须以不同的方式响应。。。这是问题的核心。