0

Ich mache meine erste Socket.io basierte Android-Anwendung. Der Socket sendet und empfängt Daten von einem Web-Service. Es gibt eine Reihe von Bildschirmen in der Anwendung für verschiedene Funktionen. Wie verwende ich die gleiche Socket-Verbindung in diesen verschiedenen Aktivitäten.Android Storing Socket.io Objekt für mehrere Aktivitäten

Ich habe versucht, das Socket-Objekt in der Application-Klasse setzen und speichern und es scheint gut zu funktionieren, aber wenn die Anwendung in den Hintergrund geht und dort für einige Zeit bleibt die Anwendung getötet und das Socket-Objekt ist dann NULL verursacht aoo mit einer Nullzeigerausnahme abstürzen.

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; 
    } 

} 

Zugang der Sockel in den Aktivitäten

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

'Sockets', auf einer Programmierebene, sind nicht' socket.io' verwandt ... die Antworten zu einem sind normalerweise für den anderen nicht relevant. Ich habe das Etikett entfernt. Weitere Informationen finden Sie in den Tag-Tags [tag: sockets]. – Myst

Antwort

3

Sie können eine Singleton-Managerklasse für Socket erstellen. Dadurch können Sie die einzelne Socket-Verbindung für die gesamte App verfügbar halten. Siehe folgenden Code und ändern Sie es entsprechend Ihrer Anforderung

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(); 
       } 
      } 
     } 
    } 
} 

Anschlussbuchse

Sie können Verbindungs-/Trennbuchse von jeder Aktivität oder Hintergrunddienst

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

aktualisieren

Wenn im Hintergrund Ihre App Socket beendet wird wird auch zerstören. Wenn Sie möchten, dass Socket im Hintergrund verbunden bleibt, müssen Sie eine eigene Logik mit Hintergrunddienst erstellen, die nichts mit Socket zu tun hat.

Verwandte Themen