服务中的Android Socket IO,获得NullPointerException

时间:2014-04-14 03:12:07

标签: android sockets nullpointerexception socket.io

我正在为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)

2 个答案:

答案 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错误。