【问题标题】:What does running on main thread mean in android在主线程上运行在android中意味着什么
【发布时间】:2021-01-03 08:55:14
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

标签: java android tcp


【解决方案1】:

我怀疑这个上下文中的“主线程”是指管理用户界面的线程。如果您在此线程中执行任何操作,您将面临 Android 杀死您的应用程序的风险,因为它似乎已挂起。

我个人认为,让用户界面线程阻塞几毫秒来执行 TCP 操作并不是什么大问题。您需要确保对操作进行编码以具有合理的超时,这样您就不会因为远程服务器响应时间过长而导致应用程序死机。

处理此类情况的官方方法是在服务中或在单独的线程中定义网络操作,并让用户界面线程使用短期操作与这些服务或线程进行通信。

此过程在此处通过示例进行记录:

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

【讨论】:

    【解决方案2】:

    android中的主线程负责在屏幕上创建和显示UI

    要执行与连接相关的任务,必须使用后台线程,否则 UI 会变得迟钝。

    有两种方法可以执行后台任务

    1. 可运行:

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

    【讨论】:

      【解决方案3】:

      就像@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: Multi-Threading in Android

      并且不要使用 AsyncTask =)) Async task is deprecated

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

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

      希望对你有帮助))祝你好运!

      【讨论】:

        猜你喜欢
        • 2016-06-28
        • 1970-01-01
        • 2012-12-17
        • 2015-01-22
        • 2012-01-10
        • 2017-05-14
        • 2021-03-15
        • 2010-10-21
        • 2014-02-08
        相关资源
        最近更新 更多