gpt4 book ai didi

android - 2个关于Android套接字编程的问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:07:18 24 4
gpt4 key购买 nike

我采用了在 Internet 上找到的套接字编程示例,并尝试为支持以太网的 Arduino 服务器构建我自己的 Android 客户端。但是我有两个问题。首先,我的主要 Activity 的代码:

package com.domiflichi.TesterProject;

import java.io.BufferedWriter; // output
import java.io.BufferedReader; // input
import java.io.InputStreamReader; // input
import java.io.OutputStreamWriter; // output
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;







public class TesterProjectMain extends Activity implements OnClickListener
{

private Button connectPhones;

private TextView myTextView; // represents the 'status text'

private String serverIpAddress = "";

private boolean connected = false;


private Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);


connectPhones = (Button) findViewById(R.id.connect_phones);

connectPhones.setOnClickListener(connectListener);
connectPhones.setOnClickListener(this);



myTextView = (TextView) findViewById(R.id.text1);

}



// This was created when using the 'implements OnClickListener' in the class
public void onClick(View v) {
if (v.getId() == R.id.connect_phones) {
if (!connected) {
serverIpAddress = "192.168.0.178";
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
connectPhones.setEnabled(false); // Once the button is pressed, disable it. :)
}
}

} else if (v.getId() == R.id.status_req) {
// CODE HERE FOR STATUS REQUEST BUTTON?

} else if (v.getId() == R.id.cmd_toggle) {
// CODE HERE FOR TOGGLE DOOR BUTTON?

} else if (v.getId() == R.id.cmd_crack) {
// CODE HERE FOR CRACK BUTTON?

} else if (v.getId() == R.id.disconnect) {
// CODE HERE FOR DISCONNECT BUTTON?

}
}





public class ClientThread implements Runnable {

public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, 23);
connected = true;

while (connected) {
try {
Log.d("ClientActivity", "C: Sending command.");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println("mypass*");
Log.d("ClientActivity", "C: Sent.");





BufferedReader r = new BufferedReader(new InputStreamReader(socket.getInputStream()));
final StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
Log.d("Server response", line.toString());

}





handler.post(new Runnable() {
public void run() {


if (total.toString().contentEquals("status:open")) {

myTextView.setText(R.string.status_open);
} else {
myTextView.setText(R.string.status_closed);
}

}
});







connected = false;

} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}

}


socket.close();
Log.d("ClientActivity", "C: Closed.");


} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
}

所以我的两个问题是:

  1. 我不知道如何让我的按钮与我向服务器发送命令的套接字交互。连接后,我有 (4) 个按钮需要通过套接字发送各种命令(它在一个单独的线程中运行,通过单击我拥有的“连接”按钮启动)。 (寻找“//CODE HERE FOR STATUS REQUEST BUTTON?”评论,我希望将各种按钮的代码放在哪里)

  2. 我需要移动

    'handler.post(new Runnable() {'

进入我的主循环的代码块:

(while ((line = r.readLine()) != null) {
total.append(line);
Log.d("Server response", line.toString());
}

但是,当我这样做并更改时:

if (total.toString().contentEquals("status:open")) {

if (line.toString().contentEquals("status:open")) {

(因为我实际上一次只想读一行),Eclipse 提示以下消息:不能在不同方法中定义的内部类中引用非最终变量行

如果我尝试更改上面的行...: 弦线;至 静态字符串行;

Eclipse 在下一行提示:

while ((line = r.readLine()) != null) {

说:最终的局部变量行可能已经被赋值

我什至不敢相信我已经走到这一步,因为我是一个完全的新手,但现在我碰壁了。

最佳答案

对于你的第二个问题:创建一个新的 final 用于你的 runnable

while ((line = r.readLine()) != null) {
total.append(line);
Log.d("Server response", line.toString());
final String status = line;
handler.post(new Runnable() {
public void run() {
if (status.contentEquals("status:open")) {
myTextView.setText(R.string.status_open);
} else {
myTextView.setText(R.string.status_closed);
}
}
});
}

第一个问题:你选择了一项相当复杂的任务。您的线程需要检查您从外部设置的某些条件,以便线程可以决定下一步需要做什么。从这些按钮你可以改变例如一个AtomicInteger只要无事可做就为 0,如果你想开灯则为 1,2 ...等等

您的线程将检查该值,将其重置为 0(在一个 .getAndSet(0) 中)并执行他应该执行的操作。

编辑:这就是它的样子

线程

public class LoopingNetworkThread extends Thread {
public static final int TASK_END = -1;
public static final int TASK_NOOP = 0;
public static final int TASK_LIGHTS_ON = 1;
public static final int TASK_LIGHTS_OFF = 2;

private final AtomicInteger mNextTask = new AtomicInteger(0);

/* Executed in this threads context */
@Override
public void run() {
openSocket();
int currentTask;
while ((currentTask = mNextTask.getAndSet(TASK_NOOP)) != TASK_END) {
switch (currentTask) {
case TASK_LIGHTS_ON:
sendLightsOn();
break;
case TASK_LIGHTS_OFF:
sendLightsOff();
break;
default:
keepAlive();
break;
}
// depending on your requirements sleep some time inbetween.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// ignore
}
}
// the while ends once you set task to TASK_END
closeSocket();
}

private void openSocket() { }
private void closeSocket() { }
private void keepAlive() { }
private void sendLightsOn() { }
private void sendLightsOff() { }

/* Executed in a different thread context */
public int setNextTask(int task){
// return what we overwrite here, maybe that is useful.
return mNextTask.getAndSet(task);
}
}

您的 Activity

public class YourActivity extends Activity {
private LoopingNetworkThread mThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mThread = new LoopingNetworkThread();
View startButton = findViewById(R.id.button1);
View stopButton = findViewById(R.id.button2);
startButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mThread.start();
}
});
stopButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mThread.setNextTask(LoopingNetworkThread.TASK_END);
}
});
}
}

关于android - 2个关于Android套接字编程的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9762759/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com