我在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中创建的任何参数同时在按钮单击中可用[对不起,如果这是一个新手问题,但我再也没有声明!! ...]
非常感谢您的意见和建议。
答案 0 :(得分:0)
问题在于:没有与按钮处理程序并行运行的“按钮活动”。按钮的onClick()代码在主处理程序的消息内运行,就像您的代码一样,可以读取状态。
您要在此处执行的操作 - 使网络请求和在同一个按钮侦听器中接收该请求的结果 - 是不可能的。主线程上的每个工作单元必须很小,因此您需要让按钮发出请求,然后在请求完成时(可能在消息处理程序中)有一个单独的部分执行剩余的工作。
如果您指的是我们的书(强制性插件:Big Nerd Ranch Guide to Android Programming),我强烈建议您根据说明并了解其工作原理,为第26章和第27章构建示例练习。这样做之间存在着天壤之别,尝试阅读和挑选一小部分理解。
答案 1 :(得分:0)
好吧我真的认为你应该考虑这个应用程序的以下架构。 主要有三个步骤:
如果您使用PendingIntents,在服务完成后,您将使用onActivityResult在Activity中获得回调。在onActivityResult中,您将知道它是什么结果,因为当您从按钮启动服务时,您发送了一个唯一的int值来标识调用者。因此,您可以根据呼叫者的身份,以不同的方式处理您获得的每个结果的回报。
就代码而言,我再次推荐您http://blog.vaporstream.com/blog/2013/07/09/concurrency-patterns-intent-service/