首页 > 解决方案 > 在主线程上运行在android中意味着什么

问题描述

我正在尝试通过 TCP 从 android 应用程序(客户端)连接到 PC 服务器(使用 Hercules),但我真的迷路了,不知道去哪里。没有一个教程完全适合我,它们中的大多数都可以让我将消息从客户端发送到服务器,但反之则不行。

我读到了不应该从“主线程”运行的连接,但这意味着什么?

此外,任何来自 android 的 TCP 连接示例都会很棒。

谢谢!

标签: javaandroidtcp

解决方案


就像@Kevin Boone 所说,主线程意味着Android 中的UI 线程。

不能在主线程中进行网络操作,否则会得到NetworkOnMainThreadException。您可以创建一个新线程,然后使用 Handler 将结果传递回主线程。代码可能如下所示:

public class MyActivity extends AppCompatActivity implements FetchDataUseCase.Listener {
    
    private FetchDataUseCase fetchDataUseCase;
    private TextView textView;
    private Button dataButton;

    public void onCreate() {
        textView = findViewById(R.id.textView);
        dataButton = findViewById(R.id.dataButton);
        dataButton.setOnClickListener(v -> getDataFromNetwork());

        fetchDataUseCase = new FetchDataUseCase(this);
    }

    void getDataFromNetwork() {
        fetchDataUseCase.fetchDataAndNotify();
        // start async operation! and receive result in onDataFetched()
    }

    @Override
    public void onDataFetched(String data) {
        // now you are in Main thread
        // do something with data

        textView.setText(data);
        textView.setVisibility(View.VISIBLE);
    }
    
    @Override
    public void onError() {
        textView.setText("ERROR!!!");
        textView.setVisibility(View.VISIBLE);
    }
}

public class FetchDataUseCase {
    public interface Listener {
        void onDataFetched(String data);
        void onError();
    }

    private final Listener listener;
    private final Handler handler = new Handler(Looper.getMainLooper());

    public FetchDataUseCase(Listener listener) {
        this.listener = listener;
    }

    public void fetchDataAndNotify() {
        new Thread(() -> {
            String myData = "";

            try {
                // your networking operation
                // where you receive some data
            } catch (Exception e) {
                handler.post(() -> listener.onError();
            } finally {
                // close stream, file, ...
            }

            // pass it back to Listener in Ui Thread
            handler.post(() -> listener.onDataFetched(myData);
        }).start();
    }
}

阅读ThreadPoster:Android 中的多线程

并且不要使用 AsyncTask =))不推荐使用异步任务

此外,您需要向您的 AndroidManifest 文件添加权限。

<uses-permission android:name="android.permission.INTERNET"/>

希望它会帮助你))祝你好运!


推荐阅读