繁体   English   中英

Activity.finish()不会杀死线程

[英]Activity.finish() doesn't kill the thread

我正在主要活动类中使用以下代码连接到Socket.io服务器。

private Socket socket; {
    Options opts = new IO.Options();
    opts.reconnection=true;
    socket = IO.socket("Server ip",opts);
    socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
    @Override
        public void call(Object... args) {
                 Log.w("Connection","Ok");
        }
    });
}

它会自动连接到另一个线程。然后,如果用户按下“后退”按钮,我将在以下行中运行:

this.finish();

所以,我先关闭活动,然后再使用onDestroy()方法,如下所示:

@Override
protected void onDestroy() {
     super.onDestroy();
     Log.w("Destry","ok");
     socket.disconnect();
     socket=null;
}

但是,当我再次启动我的应用程序时, socket变量的nullPointerException崩溃了。

如果我使用System.exit(0)而不是this.finish()则当我再次启动该应用程序时,它运行良好,没有NullPointerException

我认为当我调用this.finish()方法并且我不想使用System.exit(0)时,线程并没有被杀死。

我该如何解决?

编辑:崩溃日志

02-12 22:52:22.304: E/AndroidRuntime(14804): FATAL EXCEPTION: EventThread
02-12 22:52:22.304: E/AndroidRuntime(14804): java.lang.NullPointerException
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.impact.ribony.MainActivity$2.call(MainActivity.java:275)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket.access$701(Socket.java:18)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket$5.run(Socket.java:166)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.thread.EventThread.exec(EventThread.java:50)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket.emit(Socket.java:162)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket.onconnect(Socket.java:353)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket.onpacket(Socket.java:276)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket.access$100(Socket.java:18)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Socket$2$2.call(Socket.java:101)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager.ondecoded(Manager.java:377)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager.access$1200(Manager.java:20)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager$3.call(Manager.java:351)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.parser.Parser$Decoder.add(Parser.java:156)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager.ondata(Manager.java:369)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager.access$1000(Manager.java:20)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.socketio.client.Manager$2.call(Manager.java:342)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.Socket.onPacket(Socket.java:485)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.Socket.access$900(Socket.java:29)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.Socket$5.call(Socket.java:288)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.Transport.onPacket(Transport.java:121)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.transports.Polling.access$700(Polling.java:15)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.transports.Polling$2.call(Polling.java:122)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.parser.Parser.decodePayload(Parser.java:251)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.transports.Polling._onData(Polling.java:132)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.transports.Polling.onData(Polling.java:104)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.engineio.client.transports.PollingXHR$5$1.run(PollingXHR.java:113)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at com.github.nkzawa.thread.EventThread$2.run(EventThread.java:75)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-12 22:52:22.304: E/AndroidRuntime(14804):    at java.lang.Thread.run(Thread.java:841)

这是我正在运行的服务,用于处理我的SocketIO连接。 我为您清理了它,以便您可以重复使用它。

public class SocketIOConnection extends Service {
    //you need constants to tell servise and activity what you are sending a message for
    public static final int REGISTER_CHAT_ACTIVITY = 1;
    public static final int MESSAGE_RECEIVED = 2;

    final Messenger mMessenger = new Messenger(new IncomingHandler());
    Messenger chat;
    private Socket socket;

    @Override
    public void onCreate() {
        try {
            socket = IO.socket("IP HERE");

            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                }
            }).on("connected", new Emitter.Listener() {
                @Override
                public void call(Object... args) {
                    emitUserId();
                }
            })on("message", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                //for example you are receiving a message with event name "message"
                //you now send the information you need to update the UI
                // to the activity which is actually showing the UI
                //in this case i have a messenger (see above) named chat
                //which is initiated below
                //for now we just send a message
                chat.send(Message.obtain(null, MESSAGE_RECEIVED, args[0])); //if you have more than one object (it is not a json) you can send the whole args array and handle it in the activity
            }
        });
            //and add all the other on listeners here
            socket.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }


    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (socket != null) {
            socket.disconnect();
            socket.connect();
        } else {
            try {
                socket = IO.socket("IP HERE");
                socket.connect();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            //handle messages sent to service here
            //second parameter in Message.obtain() is stored in msg.what
            //so you need a switch case for the handling
            switch(){
                case REGISTER_CHAT_ACTIVITY:
                      chat = msg.replyTo;
                      break;
            }

        }
    }

    public class LocalBinder extends Binder {
        SocketIOConnection getService() {
            return SocketIOConnection.this;
        }
    }

}

在您的活动中,只需添加以下内容:

public class MyChatActivity extends Activity {

    public static Messenger mService = null;
    public final Messenger mMessenger = new Messenger(new IncomingHandler());
    public boolean mIsBound;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout_id);
        doBindService();
    }

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                                       IBinder service) {
            mService = new Messenger(service);

            try {
                Message msg = Message.obtain(null, SocketIOConnection.REGISTER_CHAT_ACTIVITY);
                msg.replyTo = mMessenger;
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            mService = null;

        }
    };

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SocketIOConnection.MESSAGE_RECEIVED:
                    //here you have the objects sent to you via the socket
                    //you passed them as the third parameter of Message.obtain()
                    Object message = msg.obj;
                    //you can cast the object to the type you want and update the UI as you wish with the object
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

public void doBindService() {
        if (!mIsBound) {
            context.bindService(new Intent(context,
                    SocketIOConnection.class), mConnection, Context.BIND_AUTO_CREATE);
            mIsBound = true;
        }
    }
}

如果你想了解如何活动和服务之间的通信是可能的,你可以阅读文章。

编辑:在您的活动中覆盖此方法:

public void doUnbindService() {
        if (mIsBound) {
            unbindService(mConnection);
            mIsBound = false;
        }
    }
@Override
    protected void onPause() {
        doUnbindService();
        stopService(new Intent(yourActivity.class, SocketIOConnection.class));
        super.onPause();
    }

@Override
    protected void onDestroy() {
        doUnbindService();
        stopService(new Intent(yourActivity.class, SocketIOConnection.class));
        super.onDestroy();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM