简体   繁体   English

在主线程上运行在android中意味着什么

[英]What does running on main thread mean in android

I'm trying to connect to a PC server (using Hercules) through TCP from an android app (client) but I'm really lost and don't know where to go.我正在尝试通过 TCP 从 android 应用程序(客户端)连接到 PC 服务器(使用 Hercules),但我真的迷路了,不知道该去哪里。 None of the tutorials are fully working for me, most of them can allow me to send messages from client to server but not vice versa.没有一个教程完全适合我,它们中的大多数都可以让我从客户端向服务器发送消息,反之亦然。

I read about connections not supposed to be run from the "main thread" but what does that mean?我读到了不应该从“主线程”运行的连接,但这意味着什么?

Also any examples of a TCP connection from android would be great.任何来自 android 的 TCP 连接的例子都会很棒。

Thanks!谢谢!

I suspect that the "main thread" in this context means that thread that is managing the user interface.我怀疑这个上下文中的“主线程”意味着管理用户界面的线程。 If you do anything much in this thread, you run the risk of Android killing your app because it appears to have hung.如果你在这个线程中做了很多事情,你就会冒着 Android 杀死你的应用程序的风险,因为它似乎已经挂了。

Personally, I don't think it's a huge problem to have the user interface thread block for a few milliseconds to do a TCP operation.就个人而言,我认为让用户界面线程阻塞几毫秒来执行 TCP 操作并不是什么大问题。 You'd need to make sure that you code the operation to have sensible timeouts, so you don't end with a dead app because the remote server takes too long to respond.您需要确保对操作进行编码以具有合理的超时,因此您不会以死应用程序结束,因为远程服务器需要很长时间才能响应。

The official way to handle situations like this is to define the network operations in services, or in separate threads, and have the user interface thread communicate with those services or threads using short-lived operations.处理这种情况的官方方法是在服务中或在单独的线程中定义网络操作,并让用户界面线程使用短期操作与这些服务或线程进行通信。

This process is documented with examples here:此过程在此处通过示例进行了记录:

https://developer.android.com/training/basics/network-ops/connecting https://developer.android.com/training/basics/network-ops/connecting

Main thread in android is responsible to create and display UI on screen android中的主线程负责在屏幕上创建和显示UI

to perform task related to connection strictly need to use background thread otherwise UI become laggy.执行与连接相关的任务严格需要使用后台线程,否则 UI 会变得滞后。

There are two method available to perform background Task有两种方法可以执行后台任务

  1. Runnable:可运行:

     new Thread(new Runnable() { public void run() { ..... // code here } }).start();
  2. Android AsyncTask: https://developer.android.com/reference/android/os/AsyncTask Android AsyncTask: https : //developer.android.com/reference/android/os/AsyncTask

Like @Kevin Boone said, Main thread means UI thread in Android.就像@Kevin Boone 所说的,主线程是指 Android 中的 UI 线程。

You can't do networking operations in the Main thread, otherwise you will get NetworkOnMainThreadException .不能在主线程中进行网络操作,否则会得到NetworkOnMainThreadException You can create a new thread and then pass result back to the Main thread using Handler.您可以创建一个新线程,然后使用 Handler 将结果传回主线程。 Code could look like this:代码可能如下所示:

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();
    }
}

read ThreadPoster: Multi-Threading in Android阅读ThreadPoster:Android 中的多线程

And don't use AsyncTask =)) Async task is deprecated并且不要使用 AsyncTask =))不推荐使用异步任务

Also, you need to add permision to your AndroidManifest file.此外,您需要在 AndroidManifest 文件中添加权限。

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

Hope it will help you)) Good luck!希望它会帮助你))祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM