簡體   English   中英

在主線程上運行在android中意味着什么

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

我正在嘗試通過 TCP 從 android 應用程序(客戶端)連接到 PC 服務器(使用 Hercules),但我真的迷路了,不知道該去哪里。 沒有一個教程完全適合我,它們中的大多數都可以讓我從客戶端向服務器發送消息,反之亦然。

我讀到了不應該從“主線程”運行的連接,但這意味着什么?

任何來自 android 的 TCP 連接的例子都會很棒。

謝謝!

我懷疑這個上下文中的“主線程”意味着管理用戶界面的線程。 如果你在這個線程中做了很多事情,你就會冒着 Android 殺死你的應用程序的風險,因為它似乎已經掛了。

就個人而言,我認為讓用戶界面線程阻塞幾毫秒來執行 TCP 操作並不是什么大問題。 您需要確保對操作進行編碼以具有合理的超時,因此您不會以死應用程序結束,因為遠程服務器需要很長時間才能響應。

處理這種情況的官方方法是在服務中或在單獨的線程中定義網絡操作,並讓用戶界面線程使用短期操作與這些服務或線程進行通信。

此過程在此處通過示例進行了記錄:

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

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

就像@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"/>

希望它會幫助你))祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM