0

나는 첫 번째 Socket.io 기반 안드로이드 응용 프로그램을 만들고 있습니다. 소켓은 웹 서비스에서 데이터를 보내고받습니다. 응용 프로그램에는 다양한 기능을위한 여러 화면이 있습니다. 어떻게 다른 활동에서 동일한 소켓 연결을 사용합니까?안드로이드 여러 활동을위한 Socket.io 객체 저장

소켓 클래스를 Application 클래스에 저장하려고 시도했지만 제대로 작동하는 것처럼 보입니다.하지만 응용 프로그램이 백그라운드로 들어가서 잠시 동안 남아 있으면 응용 프로그램이 종료되고 소켓 객체가 NULL이됩니다. aoo는 널 포인터 예외로 인해 충돌합니다. 활동

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

'socket '은 프로그래밍 레벨에서'socket.io'와 관련이 없습니다 ... 일반적으로 관련된 답변은 다른 것과 관련이 없습니다. 나는 그 태그를 제거했다. 자세한 내용은 [tag : sockets] 태그 세부 정보를 참조하십시오. – Myst

답변

3

에서

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

} 

액세스 소켓 당신은 소켓의 싱글 매니저 클래스를 만들 수 있습니다. 그것은 당신이 전체 애플 리케이션에 액세스 할 단일 소켓 연결을 유지하실 수 있습니다. 귀하의 요구 사항

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

연결 소켓 당신은 연결 수

/모든 활동 또는 배경 서비스

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

업데이트

에서 분리 소켓에 따라 코드를 다음 참조 변경

백그라운드에서 앱이 종료 된 경우 socket 또한 파괴 할 것이다. 소켓을 백그라운드에서 계속 연결하려면 소켓과 아무 관련이없는 백그라운드 서비스로 자신 만의 논리를 만들어야합니다.