我正在尝试做客户端/服务器 但是服务器中存在问题 代码停在" server.accept()"并停止工作 这是服务器代码:
package com.example.do2do2messanger;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Codes extends Activity {
private ServerSocket server;
private Socket connection;
private ObjectInputStream input;
private ObjectOutputStream output;
EditText sended;
TextView mirrored,chatwindow;
Button copied;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gui);
// text view of the messages
mirrored = (TextView) findViewById(R.id.mirror_id);
sended = (EditText) findViewById(R.id.send_id);
copied = (Button) findViewById(R.id.copy_id);
chatwindow = (TextView) findViewById(R.id.chat_id);
try
{
server = new ServerSocket(4444);
mirrored.setText("c1");
waitforconnection();
}
catch(IOException e)
{
mirrored.setText("c2");
e.printStackTrace();
}
}
private void waitforconnection() throws IOException
{
showmessage("waiting for someone to connect ... \n");
connection = server.accept(); // acts as infinte loop for listening
//showmessage("Now connected to " + connection.getInetAddress().getHostName());
}
输出: 如果我评论server.accept() 它将给c1然后等待某人正常连接 但如果我离开它,它将停止应用程序并给出消息: "不幸的是,app停止了工作"
logcat的: 你的意思是:
09-07 06:48:44.430: E/AndroidRuntime(4777): FATAL EXCEPTION: main
09-07 06:48:44.430: E/AndroidRuntime(4777): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.do2do2messanger/com.example.do2do2messanger.Codes}: java.lang.NullPointerException
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread.access$600(ActivityThread.java:130)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.os.Handler.dispatchMessage(Handler.java:99)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.os.Looper.loop(Looper.java:137)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread.main(ActivityThread.java:4745)
09-07 06:48:44.430: E/AndroidRuntime(4777): at java.lang.reflect.Method.invokeNative(Native Method)
09-07 06:48:44.430: E/AndroidRuntime(4777): at java.lang.reflect.Method.invoke(Method.java:511)
09-07 06:48:44.430: E/AndroidRuntime(4777): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
09-07 06:48:44.430: E/AndroidRuntime(4777): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-07 06:48:44.430: E/AndroidRuntime(4777): at dalvik.system.NativeStart.main(Native Method)
09-07 06:48:44.430: E/AndroidRuntime(4777): Caused by: java.lang.NullPointerException
09-07 06:48:44.430: E/AndroidRuntime(4777): at com.example.do2do2messanger.Codes.waitforconnection(Codes.java:67)
09-07 06:48:44.430: E/AndroidRuntime(4777): at com.example.do2do2messanger.Codes.onCreate(Codes.java:52)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.Activity.performCreate(Activity.java:5008)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
09-07 06:48:44.430: E/AndroidRuntime(4777): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
答案 0 :(得分:0)
您似乎发布了错误的logcat,因为它没有描述您遇到的问题。但我知道你的问题是什么。针对Android 3.0或更高版本的应用不允许在主线程上进行网络连接。
参见 NetworkOnMainThread | Android Developers
应用程序尝试执行时抛出的异常 在其主线程上进行网络操作。
这仅适用于针对Honeycomb SDK或。的应用程序 更高。允许使用早期SDK版本的应用程序 他们的主要事件循环线程上的网络,但它很重要 泄气。请参阅文档设计响应性。
我建议您使用Service
进行各种网络操作。我根据你自己的代码为你创建了这个例子:
<强> Codes.java 强>
package com.example.do2do2messanger;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.nillerr.stackoverflow.R;
public class Codes extends Activity {
/**
* Service sends broadcasts, which are received by this BroadcastReceiver
*/
private final BroadcastReceiver mSocketServerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String action = intent.getAction();
if (action.equals(SocketServerService.ACTION_STATUS_CHANGED)) {
onStatusChanged(extras.getString("message"));
}
}
};
EditText sended;
TextView mirrored, chatwindow;
Button copied;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gui);
// text view of the messages
mirrored = (TextView) findViewById(R.id.btn_start_service);
sended = (EditText) findViewById(R.id.send_id);
copied = (Button) findViewById(R.id.copy_id);
chatwindow = (TextView) findViewById(R.id.chat_id);
// Start the ServerSocket
startService(new Intent(this, SocketServerService.class));
}
@Override
protected void onResume() {
super.onResume();
// Register our broadcast receiver to listen for ACTION_STATUS_CHANGED broadcasts
LocalBroadcastManager.getInstance(this).registerReceiver(mSocketServerReceiver, new IntentFilter(SocketServerService.ACTION_STATUS_CHANGED));
}
@Override
protected void onPause() {
super.onPause();
// I consider unregistering the receiver, when the activity is not visible, as good practice.
LocalBroadcastManager.getInstance(this).unregisterReceiver(mSocketServerReceiver);
if (isFinishing()) {
stopService(new Intent(this, SocketServerService.class));
}
}
protected void onStatusChanged(String message) {
// Update your message here
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
<强> SocketServerService.java 强>
package com.example.do2do2messanger;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServerService extends Service implements Runnable {
public static final String ACTION_STATUS_CHANGED = "com.example.do2do2messanger.SocketServerService.STATUS_CHANGED";
private Thread mThread;
private boolean mRunning;
private ServerSocket mServerSocket;
private Socket mClientSocket;
private InputStream mInputStream;
private OutputStream mOutputStream;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
if (mThread != null) {
return;
}
log("Starting thread");
// Start a background thread for networking
mRunning = true;
mThread = new Thread(this);
mThread.start();
}
@Override
public void run() {
try {
sendStatusChanged("Starting server...");
mServerSocket = new ServerSocket();
mServerSocket.bind(new InetSocketAddress(4444));
while (mRunning) {
try {
sendStatusChanged("Waiting for someone to connect...");
// Wait for connection
mClientSocket = mServerSocket.accept();
mInputStream = mClientSocket.getInputStream();
mOutputStream = mClientSocket.getOutputStream();
// Start echoing
sendStatusChanged("Client connected");
for (int c = mInputStream.read(); c > -1; c = mInputStream.read()) {
mOutputStream.write(c);
mOutputStream.flush();
}
} catch (IOException ignored) {
} finally {
closeClient();
}
}
} catch (IOException ignored) {
} finally {
// Will eventually call onDestroy()
stopSelf();
}
}
private void sendStatusChanged(String message) {
Intent intent = new Intent(ACTION_STATUS_CHANGED);
intent.putExtra("message", message);
// Send a local broadcast, which can be received by a registered BroadcastReceiver
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void closeClient() {
try {
if (mInputStream != null) {
mOutputStream.close();
}
if (mOutputStream != null) {
mOutputStream.close();
}
if (mClientSocket != null) {
mClientSocket.close();
}
} catch (IOException ignored) {
} finally {
sendStatusChanged("Client disconnected");
}
}
private void closeServer() {
try {
if (mServerSocket != null) {
mServerSocket.close();
}
} catch (IOException ignored) {
} finally {
sendStatusChanged("Server closed");
}
}
private void log(String message) {
Log.d(getClass().getSimpleName(), message);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mThread == null) {
return;
}
log("Stopping thread");
mRunning = false;
closeServer();
try {
mThread.join();
mThread = null;
} catch (InterruptedException ignored) {
}
log("Thread stopped");
}
}
<强>的AndroidManifest.xml 强>
您想在<application>
标记中添加以下内容:
<service android:name="com.example.do2do2messanger.SocketServerService" />