java - 在主线程上运行在android中意味着什么
问题描述
我正在尝试通过 TCP 从 android 应用程序(客户端)连接到 PC 服务器(使用 Hercules),但我真的迷路了,不知道去哪里。没有一个教程完全适合我,它们中的大多数都可以让我将消息从客户端发送到服务器,但反之则不行。
我读到了不应该从“主线程”运行的连接,但这意味着什么?
此外,任何来自 android 的 TCP 连接示例都会很棒。
谢谢!
解决方案
就像@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();
}
}
并且不要使用 AsyncTask =))不推荐使用异步任务
此外,您需要向您的 AndroidManifest 文件添加权限。
<uses-permission android:name="android.permission.INTERNET"/>
希望它会帮助你))祝你好运!
推荐阅读
- css - 页面加载动画在鼠标离开时第二次执行
- javascript - Express-Server 从 MYSQL-database 接收到错误的数据
- c# - 隐藏 windows 窗体后无法显示它
- vue.js - 如何在 vue js 中监听 eventBus 值
- java - Redis SUBSCRIBE 命令停止应用程序
- oauth-2.0 - ROPC - 出现“invalid_grant”错误,描述为“AADSTS50126:用户名或密码无效”
- c# - 为什么这个字段无效?
- ios - 如何从swift4中的json数组中获取值
- mysql - 更新列以值 'st'% 开头的表
- linkedin - 领英 API。如何从视频 ugcPost 中检索展示次数