gpt4 book ai didi

Android:将消息从后台线程传递到 UI 线程的正确方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:49:26 25 4
gpt4 key购买 nike

我已经阅读了很多关于线程、处理程序、循环程序等的内容,但我很困惑。在我的应用程序中,我想让第一个 Activity 启动后台工作程序。这个后台 worker 将不断地从 TCP 套接字请求数据,并(希望)在数据到达时将新信息发布到 UI 线程。如果用户转换到新的 Activity,后台需要继续做它的事情,但只向 UI 线程发送不同的消息,以便它可以相应地更新新布局。

这是我目前所拥有的......这是我的主要 Activity 文件

public class MyTCPTest extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set the layout
setContentView(R.layout.main);
// create a handler to handle messages from bg thread
Handler handler = new Handler();

BgWorkerThread bgw = new BgWorkerThread();
bgw.start();
}

在另一个文件中,我这样定义我的后台工作线程...

public class BgWorkerThread extends Thread {    
@Override
public void run(){

while(true)
{
try {
// simulate a delay (send request for data, receive and interpret response)
sleep(1000);

// How do I send data here to the UI thread?

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

如果 UI 切换到不同的 Activity,这个线程会保持运行吗?另外,这个线程如何知道将消息发送到哪个 Activity ?显然我希望它始终将数据发送到当前 Activity 的 Activity。那会自动发生吗?

最后,当 UI 切换到不同的 Activity 时,需要通知 bgworker 以便它可以开始请求与新 Activity 布局相关的数据。将变更通知工作人员的最佳方式是什么?难道我不能只在 BgWorkerThread 类中创建一个可以在 Activity 加载时调用的公共(public)方法吗?

最佳答案

我在下面的 SO Question 中说明了相同的代码和更详细的步骤.总而言之,为了通知您的 UI 并为其提供不同的上下文,我建议如下:

  • 有一个将 requestId 映射到 Handler 的映射(假设您有请求 ID 的上下文)。您可以在 Activity 中注册适当的处理程序,这样您就可以让处理程序对每个 Activity 的行为有所不同(例如,当它收到来自服务器的响应时更新各种 UI 元素)
  • 为线程模型更改为 AsyncTask,因为它具有 onProgressUpdate 方法,可以更轻松地编写代码以便从后台线程通知 UI 线程

这是您的 BackgroundThread 的 stub /伪代码

public class ResponseHandler extends AsyncTask<Void, String, Integer> {
boolean isConnectionClosed = false;
Map<Integer, Handler> requestIdToMapHandler;

public ResponseHandler() {
this.requestIdToMapHandler = new HashMap<Integer, Handler>();
}

@Override
protected Integer doInBackground(Void... params) {
int errorCode = 0;

try {
// while not connection is not close
while(!isConnectionClosed){
// blocking call from the device/server
String responseData = getResponse();

// once you get the data, you publish the progress
// this would be executed in the UI Thread
publishProgress(responseData);
}
} catch(Exception e) {
// error handling code that assigns appropriate error code
}

return errorCode;

}

@Override
protected void onPostExecute(Integer errorCode) {
// handle error on UI Thread
}

@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
String responseData = values[0];

// the response contains the requestId that we need to extract
int requestId = extractId(responseData);

// next use the requestId to get the appropriate handler
Handler uiHandler = getUIHandler(requestId);

// send the message with data, note that this is just the illustration
// your data not necessary be jut String
Message message = uiHandler.obtainMessage();
message.obj = responseData;
uiHandler.sendMessage(message);
}

/***
* Stub code for illustration only
* Get the handler from the Map of requestId map to a Handler that you register from the UI
* @param requestId Request id that is mapped to a particular handler
* @return
*/
private Handler getUIHandler(int requestId) {
return null;
}

/***
* Stub code for illustration only, parse the response and get the request Id
* @param responseId
* @return
*/
private int extractId(String responseId) {
return 0;
}

/***
* Stub code for illustration only
* Call the server to get the TCP data. This is a blocking socket call that wait
* for the server response
* @return
*/
private String getResponse() {
return null;
}
}

关于Android:将消息从后台线程传递到 UI 线程的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7369531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com