我正在为Android运行Gottox's Socket IO client
。我正在IntentService
开始连接,并计划在同一服务中断开连接。
我在NullPointerException
行收到了socket.disconnect();
,但无法弄清楚原因。 SocketIO套接字是类级变量,当我尝试断开连接时,Socket IO
连接已经打开。
那我为什么要获得NPE?
public class SocketIOService extends IntentService {
public static final String KEY_ACTION = "action";
public static final String ACTION_START = "start";
public static final String ACTION_STOP = "stop";
private Preferences prefs;
private SocketIO socket;
public SocketIOService() {
super("com.test.test.SocketIOService");
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra(KEY_ACTION);
if (action.equalsIgnoreCase(ACTION_START)) {
Log.v("SOCKET IO SERVICE", "STARTED");
prefs = new Preferences(this);
// Socket IO connection
try {
socket = new SocketIO("http://test.test.com:8002");
SocketIO.setDefaultSSLSocketFactory(SSLContext.getDefault());
socket.connect(new IOCallback() {
@Override
public void onMessage(JSONObject json, IOAcknowledge ack) {
try { Log.v("SOCKET IO SERVER SAID", json.toString(2)); }
catch (JSONException e) { e.printStackTrace(); }
}
@Override
public void onMessage(String data, IOAcknowledge ack) {
Log.v("SOCKET IO SERVER SAID", data);
}
@Override
public void onError(SocketIOException socketIOException) {
Log.e("SOCKET IO", "ERROR");
socketIOException.printStackTrace();
}
@Override
public void onDisconnect() {
Log.v("SOCKET IO CONNECTION", "TERMINATED");
}
@Override
public void onConnect() {
Log.v("SOCKET IO CONNECTION", "ESTABLISHED");
}
@Override
public void on(String event, IOAcknowledge ack, Object... args) {
Log.v("SERVER TRIGGERED EVENT", event);
}
});
// This line is cached until the connection is established.
socket.emit("userid", prefs.getUserId());
}
catch (MalformedURLException e) { e.printStackTrace(); }
catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); }
}
if (action.equalsIgnoreCase(ACTION_STOP)) {
Log.v("SOCKET IO SERVICE", "STOPPED");
socket.disconnect();
stopSelf();
}
}
}
logcat的
04-13 20:04:49.314: E/AndroidRuntime(15025): FATAL EXCEPTION: IntentService[com.test.test.SocketIOService]
04-13 20:04:49.314: E/AndroidRuntime(15025): java.lang.NullPointerException
04-13 20:04:49.314: E/AndroidRuntime(15025): at com.test.test.SocketIOService.onHandleIntent(SocketIOService.java:89)
04-13 20:04:49.314: E/AndroidRuntime(15025): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
04-13 20:04:49.314: E/AndroidRuntime(15025): at android.os.Handler.dispatchMessage(Handler.java:99)
04-13 20:04:49.314: E/AndroidRuntime(15025): at android.os.Looper.loop(Looper.java:137)
04-13 20:04:49.314: E/AndroidRuntime(15025): at android.os.HandlerThread.run(HandlerThread.java:60)
答案 0 :(得分:0)
IntentService
的工作方式与普通服务的工作方式不同。一旦它到达onHandleIntent的末尾,它就会停止。可能发生的事情是服务使套接字连接,意识到它完成了它的工作,并停止了自己。然后,当触发动作ACTION_STOP
的Intent时,Android会创建一个新的服务实例并传递Intent,但是这个实例还没有实例化套接字。
确认这一点的方法是在onHandleIntent的开头添加android.util.Log.d("SocketIOService", "" + hashCode());
,然后照常进行。检查你的日志以查看hashCodes是否相同 - 我希望它们会有所不同,表明它们是服务的不同实例。
您可能需要使用常规服务,并在其中管理自己的工作线程。
答案 1 :(得分:0)
您应首先测试null,如下面的代码所示:
if (action.equalsIgnoreCase(ACTION_STOP)) {
if (socket != null) {
socket.disconnect();
}
stopSelf();
}
当您尝试关闭套接字时,这会阻止任何NullPointerException
错误。