我有这个代码在android .my代码是为了回复多播msg.it正常工作当我打开这个应用程序的第一个。但我使用按钮返回Android和我打开第二,这个应用程序工作不止一个并回复多个回复。
public class MainActivity extends Activity {
TextView info, infoip, msg;
String message = "";
ServerSocket serverSocket;
String s;
String ipserver;
String replyip;
int i;
int j;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
i=0;
j=1;
infoip.setText(getIpAddress());
WifiManager manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo infor =manager.getConnectionInfo();
String addr=infor.getMacAddress();
this.s=addr;
Thread t = new Thread (new SocketServerThread());
if(!t.isAlive()){
t.start();
}
}
@Override
protected void onRestart(){
}
@Override
protected void onDestroy() {
super.onDestroy();
i=1;
j=0;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
static final int SocketServerPORT = 7000;
int count = 0;
@Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
info.setText("\n+I'm waiting here: "
+ serverSocket.getLocalPort()+"\n \n");
}
});
while (true) {
MulticastSocket sock = new MulticastSocket(12345);
InetAddress addr = InetAddress.getByName("224.0.0.1");
sock.joinGroup(addr);
DatagramPacket packet;
byte [] buffer= new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
sock.receive(packet);
String Message = new String (packet.getData(),0,packet.getLength());
replyip =packet.getSocketAddress().toString().substring(0, 13);
message+=Message+replyip;
sock.close();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(replyip, count);
if(i==0 )
{
socketServerReplyThread.run();
}
if(j==0){
socketServerReplyThread.run();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
String ips;
SocketServerReplyThread(String ip, int c) {
ips=ip;
}
@Override
public void run() {
try {
Socket s=new Socket(ips.toString(),12345);
DataOutputStream dos =new DataOutputStream(s.getOutputStream());
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String a = telephonyManager.getDeviceId();
dos.writeUTF(a);
dos.flush();
dos.close();
s.close();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong! " + e.toString() + "\n";
}
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}
答案 0 :(得分:0)
当您按下后退按钮时,您的应用程序仍在内存中(使用“adb shell ps”验证)。再次启动时,会调用onCreate。现在你有两个消耗传入连接的SocketServerThread实例。
Android会因为您可能没有预料到的许多原因而破坏并重新创建活动,例如当您旋转屏幕时。因此,您必须小心将数据保存在活动中。
您应该将您的网络代码移出Activity并进入自己的类。使用单例或工厂模式来确保只有一个SocketServerThread。
答案 1 :(得分:0)
这里的问题是你的线程的run方法中的while(true)行。创建Activity的次数很多,正在创建新的Thread并在无限循环中执行它。如果您启动app&#34; n&#34;次,将创建n个线程。
isAlive签入下面的代码是无用的,因为在它上面创建了一个新的Thread对象。
线程t =新线程(新的SocketServerThread()); if(!t.isAlive()){ t.start(); }
要解决此问题,您可以使用一个标志来检查活动是否已销毁。并运行循环直到活动被破坏。这将确保一旦活动被销毁,Thread就没有任务。
而(isDestroyed){ //做任务 }
protected void onDestroy(){ super.onDestroy(); isDestroyed = true; }
我已经编辑了下面的代码,以确保不会创建多个线程。
public class MainActivity extends Activity {
TextView info, infoip, msg;
String message = "";
ServerSocket serverSocket;
String s;
String ipserver;
String replyip;
int i;
int j;
private boolean mIsDestroyed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
i=0;
j=1;
infoip.setText(getIpAddress());
WifiManager manager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo infor =manager.getConnectionInfo();
String addr=infor.getMacAddress();
this.s=addr;
Thread t = new Thread (new SocketServerThread());
if(!t.isAlive()){
t.start();
}
}
@Override
protected void onRestart(){
}
@Override
protected void onDestroy() {
super.onDestroy();
mIsDestroyed = true;
i=1;
j=0;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
static final int SocketServerPORT = 7000;
int count = 0;
@Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
info.setText("\n+I'm waiting here: "
+ serverSocket.getLocalPort()+"\n \n");
}
});
while (mIsDestroyed == false) {
MulticastSocket sock = new MulticastSocket(12345);
InetAddress addr = InetAddress.getByName("224.0.0.1");
sock.joinGroup(addr);
DatagramPacket packet;
byte [] buffer= new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
sock.receive(packet);
String Message = new String (packet.getData(),0,packet.getLength());
replyip =packet.getSocketAddress().toString().substring(0, 13);
message+=Message+replyip;
sock.close();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(replyip, count);
if(i==0 )
{
socketServerReplyThread.run();
}
if(j==0){
socketServerReplyThread.run();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
String ips;
SocketServerReplyThread(String ip, int c) {
ips=ip;
}
@Override
public void run() {
try {
Socket s=new Socket(ips.toString(),12345);
DataOutputStream dos =new DataOutputStream(s.getOutputStream());
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String a = telephonyManager.getDeviceId();
dos.writeUTF(a);
dos.flush();
dos.close();
s.close();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong! " + e.toString() + "\n";
}
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
msg.setText(message);
}
});
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
}
答案 2 :(得分:0)
尝试使用Singleton模式,如下所述:
public class MySingleton implements Runnable {
private static MySingleton sInstance;
private boolean mIsThreadStarted = false;
// Use this method to access object of this class. Only single object of
// this class will be created and thread will be started only once.
public static synchronized MySingleton getInstance() {
if (sInstance == null) {
sInstance = new MySingleton();
}
return sInstance;
}
private MySingleton() {
// Remove below call if you want start it later.
startThread();
}
// Call this method whenever thread is to be started.
public void startThread() {
if (mIsThreadStarted) {
// Already started.
return;
}
Thread t = new Thread(this);
t.start();
mIsThreadStarted = true;
}
@Override
public void run() {
// Your logic here, which should be running continuously.
while (true) {
// This loop will be running continuously till the app is running.
// You will need to Implement Callback/Listener mechanism to pass
// events to Activity.
}
}
}