我正在开发一个使用Wifi / Tcp连接与机器人通信的应用程序。目前我正在使用单个线程来管理tcp连接,使用TcpClient类和我的MainActivity中的“ConnectTask extends AsyncTask”。
到目前为止,这就是我所拥有的:
TcpClient.java
private OnMessageReceived mMessageListener = null;
private int bufferSize = 5000;
public ByteBuffer bf;
private BufferedInputStream inFromServer;
private BufferedOutputStream outFromClient;
.
.
.
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
Log.i("Debug", "inside try catch");
//receives the message which the server sends back
inFromServer = new BufferedInputStream(socket.getInputStream());
outFromClient = new BufferedOutputStream(socket.getOutputStream());
bf = ByteBuffer.allocate(bufferSize);
while (mRun) {
// Log.i("Debug", "inside while mRun");
bf.order(ByteOrder.LITTLE_ENDIAN);
for (int i=0;i<5000;i++) {
int b = inFromServer.read();
if (b == -1) {
break;
}
bf.put((byte) b);
}
if ( bf != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
// Log.i("Debug","Message received !");
mMessageListener.messageReceived(bf);
mMessageListener.updateBatteryLvl();
}
bf.position(0);
}
}
.
.
.
这是我在MainActivity中的ConnectTask:
public class ConnectTask extends AsyncTask<Void, ByteBuffer, TcpClient> {
@Override
protected TcpClient doInBackground(Void... params) {
//we create a TCPClient object and
mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
@Override
//here the messageReceived method is implemented
public void messageReceived(ByteBuffer message) throws IOException {
//this method calls the onProgressUpdate
byte[] resultat = new byte[4000];
resultat = message.array();
updateBatteryLvl();
message.clear();
我没有在tcpclient或connecttask中使用任何处理程序,但我看到一些教程使用它们进行Tcp连接,我想知道他们为什么要使用它?我已经测试了与机器人的连接,我收到它发送的数据非常好。 如果你有多线程写在同一个文件中,那么处理程序是否像信号量一样使用?
答案 0 :(得分:0)
如果您有多线程写入,那么处理程序是否像信号量一样使用 例如同一个文件?
或多或少,是的。 处理程序只能在带有Looper的线程中创建(调用其构造函数)(主线程是带有looper的线程)。
然后,您可以通过处理程序发布Runnables和Messages以便运行(将来的某个时间)。这些可运行/消息由hanlder排队,并被分派以在它们被创建的线程上运行。所以基本上,如果你在不同的线程中运行东西,并且想要在不担心竞争条件的情况下执行某些操作(或者需要在特定线程上运行这些操作,比如当你需要更新UI时),你可以发布&# 34;操作&#34;在处理程序中,这就是全部。
在您的情况下,使用AsyncTask,它会执行相同的操作,在分离的线程中执行工作,并将结果提交给MAIN THREAD。如果您需要管理不同的线程,并将结果提交到单个而不是MAIN THREAD,则您需要使用处理程序。 但是当你描述你正在做的事情时,就没有必要了。
答案 1 :(得分:0)
您无法在UI线程(主线程)中执行长时间运行操作,或者您将获得"application not responding"(ANR)。 所以你必须使用多线程和Android框架提供基础设施,以便更容易与主线程进行数据同步(Android UI工具包不是线程安全的)。
您的选择可能会导致问题,因为:
AsyncTask只能用于需要几秒钟的操作。
AsyncTasks在单个后台线程(来自API 11)上串行执行。因此,长时间跑步的工人可以阻止其他人。
AsyncTasks不尊重主机Activity的生命周期(可能会导致内存泄漏)。
查杀清单中的优先级为low。