当前位置: 首页 > 知识库问答 >
问题:

Android处理程序,不在用户界面线程中执行post()

江志业
2023-03-14

从一开始,我就通过Handler的方法post()postDelayed()在与UI线程不同的线程中做了一些事情,我决定在其上创建一个TCP套接字,但它不起作用。

我正在接收抛出的< code > NetworkOnMainThreadException 。

有没有什么方法可以在UI线程中执行post()postDelayed()任务?

public class ServerHandler extends Handler {

private Socket serverSocket;   

public ServerHandler(){
    super(new MyHandlerThread("MyHandlerThread").getLooper());
}

@Override
public void handleMessage(Message msg) {
    super.handleMessage(msg);
}

public void connectServer()
{
    post(serverConnection);
}

public void writeMessage(String msg){
    try {
        serverSocket.getOutputStream().write(msg.getBytes());
        Log.d("MyLog","Message sent!");
    }
    catch (IOException io){
        Log.d("MyLog","SendMessage error");
    }
}

private Runnable serverConnection = new Runnable() {
    @Override
    public void run() {

        try {
            serverSocket = new Socket("152.168.21.24", 5001);

            Log.d("MyLog","Server connected!");

            while(true){
                Log.d("MyLog","Listening server");
                byte[] buffer = new byte[256];
                int bytesReceived = serverSocket.getInputStream().read(buffer);
                if(bytesReceived==-1) {
                    throw new IOException("Server disconnected");
                }
                else {
                  String msg = new String(buffer,0,bytesReceived);
                  Log.d("MyLog","Message received: " + msg);

                }
            }
        }

        catch (IOException io){
            Log.d("MyLog","Server connection error " + io.getMessage());
            connectServer();
        }
    }
};

}

共有1个答案

潘安平
2023-03-14

Handler#post()Looper 线程上发布 Messages 和 Runnables。处理程序的默认构造函数会将自身绑定到创建它的循环函数线程。如果它不在 Looper 线程上,那么它将引发异常。因此,要在工作线程上使用处理程序,必须首先创建一个线程并使用循环函数循环它。然后,将给定的循环函数传递给处理程序的构造函数。

幸运的是,已经有一个实用程序类为您完成了大部分工作。它叫做HandlerThread。只需创建一个< code>HandlerThread,并在需要线程的Looper时调用< code>getLooper。

编辑:默认处理程序构造函数不选择主线程。如果当前线程已经是Looper线程,它会选择它。

 类似资料:
  • 问题内容: 我对CompletableFuture方法有疑问: 事情是JavaDoc这么说的: 返回一个新的CompletionStage,当此阶段正常完成时,将使用该阶段的结果作为所提供函数的参数来执行该阶段。有关涵盖异常完成的规则​​,请参见CompletionStage文档。 那线程呢?这将在哪个线程中执行?如果将来由线程池完成怎么办? 问题答案: 文档中指定的策略可以帮助您更好地理解: 对

  • 我有一个关于CompletableFuture方法的问题: 问题是JavaDoc只说了这么一句话: 返回一个新的CompletionStage,当此阶段正常完成时,将以此阶段的结果作为所提供函数的参数执行该CompletionStage。有关例外完成的规则,请参阅CompletionStage文档。 穿线呢?这将在哪个线程中执行?如果未来是由一个线程池来完成的呢?

  • 问题内容: 我想在后台线程中运行一些Runnable。我想使用Handler,因为它便于延迟。我的意思是 凡 可运行 应当运行 后台 线程。是否可以创建这样的处理程序?是否在某个地方有“背景” Looper,或者该如何创建? PS我知道如何使用自定义类扩展Thread,但是比处理程序方式需要更多的编码工作。因此,请不要发布其他解决方案或类似的内容 如果Handler能以“干净”的方式做到这一点,我

  • 我想在后台线程中运行一些Runnable。我想使用Handler,因为它方便延迟。我的意思是 runnable应该在后台线程中运行。有可能创造这样的处理器吗?某个地方有没有“背景”Looper或者我怎么才能创建它? 附言:我知道如何使用自定义类扩展Thread来做到这一点,但它需要更多的编码工作,而不是以处理程序的方式进行。因此,请不要发布其他解决方案或类似内容 我只是想知道汉德勒是否能以“干净”

  • 问题内容: 如果我在http处理程序中启动goroutine,即使返回响应后它也会完成吗?这是一个示例代码: 在上面的示例中,goroutine是否会在所有情况下都完成?还是有什么特殊情况无法完成? 问题答案: 是的,它会完成,没有什么可以阻止它。 停止goroutine完成 “从外部” 完成的唯一事情就是从函数返回(这也意味着完成程序的执行,但是这种情况永远不会发生)。其他导致不稳定状态的情况,

  • 我知道这个问题已经被问过很多次了。但是有些事情我从来没有找到答案。所以希望有人能给我一些启发。 我们都知道,AsyncTask和Thread是执行后台任务以避免ANR问题的选项。建议asynctask只能用于短期运行的任务,而线程可以用于长期运行的任务。asynctask不应用于长任务的原因是众所周知的,这与asynctask可能导致的泄漏有关,因为它可能在活动销毁后继续运行。这很有说服力。然而,