关于Android套接字编程的2个问题
我已经在互联网上找到了一些套接字编程的例子,并且正在尝试为一个支持以太网的Arduino服务器构建我自己的Android客户端。然而,我有两个问题。 首先,我的主要活动的代码:关于Android套接字编程的2个问题,android,Android,我已经在互联网上找到了一些套接字编程的例子,并且正在尝试为一个支持以太网的Arduino服务器构建我自己的Android客户端。然而,我有两个问题。 首先,我的主要活动的代码: package com.domiflichi.TesterProject; import java.io.BufferedWriter; // output import java.io.BufferedReader; // input import java.io.InputStreamReader; // inpu
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;
}
}
}
}
所以我的两个问题是:
(while ((line = r.readLine()) != null) {
total.append(line);
Log.d("Server response", line.toString());
}
然而,当我这样做,并改变:
if (total.toString().contentEquals("status:open")) {
到
(因为我一次只想读一行),
Eclipse发出以下消息:
无法在其他方法中定义的内部类内引用非最终变量行
如果我试图改变上面的线…:
弦线;
到
静态弦线
Eclipse在下一行抱怨:
而((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);
}
}
});
}
关于你的第一个问题:
您选择了一个相当复杂的任务。您的线程需要检查您从外部设置的一些条件,以便线程可以决定下一步需要执行的操作。从这些按钮中,您可以更改,例如,如果无需执行任何操作,则为0;如果要打开灯,则为1;等等
您的线程将检查该值,将其重置为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);
}
}
您的活动
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);
}
});
}
}
谢谢。第一个问题:完成,没有问题了。谢谢。不过,对于我的第二个问题,谢谢你的想法/解决方案。我正在尝试实现AtomicInteger,但我认为我做错了什么。对不起,这个评论不是很友好……我将使用“回答你的问题”链接。这不是一个不友好的评论:)请看编辑,也许这能更好地解释它。嗨@zapl,你指的是什么?嘿,看起来我的原始帖子是由@Lucifer编辑的?为什么?编辑了什么?我还有一个新问题…请看下面我的最新帖子…我刚刚注意到你在@zapl中添加了一些代码…如果我能找到答案,也许这会对我有所帮助。谢谢。
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);
}
});
}
}