Android Storing Socket.io对象用于多个活动 [英] Android Storing Socket.io object for multiple activities

查看:82
本文介绍了Android Storing Socket.io对象用于多个活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作我的第一个基于Socket.io的android应用程序.套接字从Web服务发送和接收数据.应用程序中有许多不同功能的屏幕.在这些不同的活动中如何使用相同的套接字连接.

I am making my first Socket.io based android application. The socket sends and receives data from a web service. There are a number of screens in the application for different features. How do i use the same socket connection in these different activities.

我尝试过将Socket对象设置和存储在Application类中,它看起来运行良好,但是当应用程序进入后台并留在后台一段时间后,该应用程序被杀死,然后套接字对象为NULL从而导致aoo因空指针异常而崩溃.

I have tried setting and storing the Socket Object in the Application class and it appears to work well but when the application goes into the background and left there for some time the application is killed and the socket object is then NULL causing the aoo to crash with a null pointer exception.

public class MyApplication extends Application {

    private Socket mSocket;

    private final String TAG = "Application Class";

    public Socket getSocket() {
        return mSocket;
    }

    public Socket createSocket() {

    try {
        Manager manager = new Manager(new URI("http://0.0.0.0"));
    } catch (URISyntaxException URIse) {
        URIse.printStackTrace();
    }

        return mSocket;
    }

}

访问活动中的套接字

MyApplication app;
app = (MyApplication ) getApplication();
app.getSocket;

推荐答案

您可以为套接字创建一个单例管理器类.它将允许您保持整个应用程序可访问的单个套接字连接.请参阅以下代码并根据您的要求进行更改

You can create a singleton manager class for socket. It will allow you to keep single socket connection accessible to entire app. See following code and change it according to your requirement

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.util.Log;

import com.myapp.app.ui.adapter.OnSocketConnectionListener;

import java.util.ArrayList;
import java.util.List;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

/**
 * Created by penguin on 6/30/2016.
 * <p/>
 * SocketManager manages socket and internet connection.
 * It also provide listeners for connection status
 */
public class SocketManager {

    /**
     * The constant STATE_CONNECTING.
     */
    public static final int STATE_CONNECTING = 1;
    /**
     * The constant STATE_CONNECTED.
     */
    public static final int STATE_CONNECTED = 2;
    /**
     * The constant STATE_DISCONNECTED.
     */
    public static final int STATE_DISCONNECTED = 3;

    /**
     * The constant CONNECTING.
     */
    public static final String CONNECTING = "Connecting";
    /**
     * The constant CONNECTED.
     */
    public static final String CONNECTED = "Connected";
    /**
     * The constant DISCONNECTED.
     */
    public static final String DISCONNECTED = "Disconnected";

    private static SocketManager instance;

    private SocketManager() {
    }

    /**
     * Gets instance.
     *
     * @return the instance
     */
    public synchronized static SocketManager getInstance() {
        if (instance == null) {
            instance = new SocketManager();
        }
        return instance;
    }

    /**
     * The constant TAG.
     */
    public static final String TAG = SocketManager.class.getSimpleName();
    private Socket socket;
    private List<OnSocketConnectionListener> onSocketConnectionListenerList;

    /**
     * Connect socket.
     *
     * @param token  the token
     * @param userId the user id
     * @param host   the host
     * @param port   the port
     */
    public void connectSocket(String token,String userId, String host, String port) {
        try {
            if(socket==null){
                String serverAddress = host+":"+port;
                IO.Options opts = new IO.Options();
                opts.forceNew = true;
                opts.reconnection = true;
                opts.reconnectionAttempts=5;
                opts.secure = true;
                opts.query = "token=" + token + "&" + "user_id=" + userId;
                socket = IO.socket(serverAddress, opts);

                socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        fireSocketStatus(SocketManager.STATE_CONNECTED);
                        Log.i(TAG, "socket connected");
                    }
                }).on(Socket.EVENT_RECONNECTING, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.e(TAG, "Socket reconnecting");
                        fireSocketStatus(SocketManager.STATE_CONNECTING);
                    }
                }).on(Socket.EVENT_RECONNECT_FAILED, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.e(TAG, "Socket reconnection failed");
//                        fireSocketStatusIntent(SocketManager.STATE_DISCONNECTED);
                    }
                }).on(Socket.EVENT_RECONNECT_ERROR, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.e(TAG, "Socket reconnection error");
//                        fireSocketStatus(SocketManager.STATE_DISCONNECTED);
                    }
                }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.e(TAG, "Socket connect error");
                        fireSocketStatus(SocketManager.STATE_DISCONNECTED);
                        socket.disconnect();
                    }
                }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.e(TAG, "Socket disconnect event");
                        fireSocketStatus(SocketManager.STATE_DISCONNECTED);
                    }
                }).on(Socket.EVENT_ERROR, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        try {
                            final String error = (String) args[0];
                            Log.e(TAG + " error EVENT_ERROR ", error);
                            if (error.contains("Unauthorized") && !socket.connected()) {
                                if (onSocketConnectionListenerList != null) {
                                    for (final OnSocketConnectionListener listener : onSocketConnectionListenerList) {
                                        new Handler(Looper.getMainLooper())
                                                .post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        listener.onSocketEventFailed();
                                                    }
                                                });
                                    }
                                }
                            }
                        } catch (Exception e) {
                            Log.e(TAG, e.getMessage() != null ? e.getMessage() : "");
                        }
                    }
                }).on("Error", new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
                        Log.d(TAG, " Error");
                    }
                });
                socket.connect();
            }else if(!socket.connected()){
                socket.connect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int lastState = -1;

    /**
     * Fire socket status intent.
     *
     * @param socketState the socket state
     */
    public synchronized void fireSocketStatus(final int socketState) {
        if(onSocketConnectionListenerList !=null && lastState!=socketState){
            lastState = socketState;
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    for(OnSocketConnectionListener listener: onSocketConnectionListenerList){
                        listener.onSocketConnectionStateChange(socketState);
                    }
                }
            });
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    lastState=-1;
                }
            },1000);
        }
    }

    /**
     * Fire internet status intent.
     *
     * @param socketState the socket state
     */
    public synchronized void fireInternetStatusIntent(final int socketState) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                if(onSocketConnectionListenerList !=null){
                    for(OnSocketConnectionListener listener: onSocketConnectionListenerList){
                        listener.onInternetConnectionStateChange(socketState);
                    }
                }
            }
        });
    }

    /**
     * Gets socket.
     *
     * @return the socket
     */
    public Socket getSocket() {
        return socket;
    }

    /**
     * Sets socket.
     *
     * @param socket the socket
     */
    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    /**
     * Destroy.
     */
    public void destroy(){
        if (socket != null) {
            socket.off();
            socket.disconnect();
            socket.close();
            socket=null;
        }
    }

    /**
     * Sets socket connection listener.
     *
     * @param onSocketConnectionListenerListener the on socket connection listener listener
     */
    public void setSocketConnectionListener(OnSocketConnectionListener onSocketConnectionListenerListener) {
        if(onSocketConnectionListenerList ==null){
            onSocketConnectionListenerList = new ArrayList<>();
            onSocketConnectionListenerList.add(onSocketConnectionListenerListener);
        }else if(!onSocketConnectionListenerList.contains(onSocketConnectionListenerListener)){
            onSocketConnectionListenerList.add(onSocketConnectionListenerListener);
        }
    }

    /**
     * Remove socket connection listener.
     *
     * @param onSocketConnectionListenerListener the on socket connection listener listener
     */
    public void removeSocketConnectionListener(OnSocketConnectionListener onSocketConnectionListenerListener) {
        if(onSocketConnectionListenerList !=null
                && onSocketConnectionListenerList.contains(onSocketConnectionListenerListener)){
            onSocketConnectionListenerList.remove(onSocketConnectionListenerListener);
        }
    }

    /**
     * Remove all socket connection listener.
     */
    public void removeAllSocketConnectionListener() {
        if(onSocketConnectionListenerList !=null){
            onSocketConnectionListenerList.clear();
        }
    }

    /**
     * The type Net receiver.
     */
    public static class NetReceiver extends BroadcastReceiver {

        /**
         * The Tag.
         */
        public final String TAG = NetReceiver.class.getSimpleName();

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager cm =
                    (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            boolean isConnected = activeNetwork != null &&
                    activeNetwork.isConnectedOrConnecting();

            SocketManager.getInstance().fireInternetStatusIntent(
                    isConnected?SocketManager.STATE_CONNECTED:SocketManager.STATE_DISCONNECTED);
            if (isConnected) {
                if(SocketManager.getInstance().getSocket()!=null
                        && !SocketManager.getInstance().getSocket().connected()){
                    SocketManager.getInstance().fireSocketStatus(SocketManager.STATE_CONNECTING);
                }
                PowerManager powerManager =
                        (PowerManager) context.getSystemService(Context.POWER_SERVICE);
                boolean isScreenOn;
                if (android.os.Build.VERSION.SDK_INT
                        >= android.os.Build.VERSION_CODES.KITKAT_WATCH) {
                    isScreenOn = powerManager.isInteractive();
                }else{
                    //noinspection deprecation
                    isScreenOn = powerManager.isScreenOn();
                }

                if (isScreenOn && SocketManager.getInstance().getSocket() !=null) {
                    Log.d(TAG, "NetReceiver: Connecting Socket");
                    if(!SocketManager.getInstance().getSocket().connected()){
                        SocketManager.getInstance().getSocket().connect();
                    }
                }
            }else{
                SocketManager.getInstance().fireSocketStatus(SocketManager.STATE_DISCONNECTED);
                if(SocketManager.getInstance().getSocket() !=null){
                    Log.d(TAG, "NetReceiver: disconnecting socket");
                    SocketManager.getInstance().getSocket().disconnect();
                }
            }
        }
    }
}

连接插座

您可以从任何活动或后台服务连接/断开套接字

You can connecting/disconnect socket from any activity or background service

    SocketManager.getInstance().connectSocket(user.getToken(), user.getUserId(),
            getResources().getString(R.string.host), "8000");

更新

如果在后台杀死您的应用,套接字也会被破坏.如果要使套接字在后台保持连接状态,则必须使用与套接字无关的后台服务来使自己拥有逻辑.

If in background your app is killed socket will also destroy. If you want socket to remain connected in background you have to make you own logic with background service which has nothing to do with socket.

实现OnSocketConnectionListener

public interface OnSocketConnectionListener {
    void onSocketEventFailed();
    void onSocketConnectionStateChange(int socketState);
    void onInternetConnectionStateChange(int socketState);
}

这篇关于Android Storing Socket.io对象用于多个活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆