Android 建立多个连接的 WebSocket 服务
Android WebSocket Services making multiple connections
我已经创建了一个网络套接字服务。但它一直在建立多个连接
我只想让应用建立一个连接,除非网络连接断开然后建立另一个。
但是现在,如果我按下 phone 上的主页按钮,它就会建立一个连接。然后返回应用程序,它将建立另一个连接。
谢谢大家的帮助。
onCreate... 我的 MainActivity
Intent startServiceIntent = new Intent(this, WebSocketServices.class);
startService(startServiceIntent);
清单
<!-- WebSocket -->
<receiver
android:name="com.example.basicplayerapp.core.NetworkReceiver">
<intent-filter >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.example.basicplayerapp.core.WebSocketServices"></service>
网络接收器
public class NetworkReceiver extends BroadcastReceiver {
public static final String TAG = HomeActivity.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
Log.i(TAG, "connected");
Intent startServiceIntent = new Intent(context, WebSocketServices.class);
context.startService(startServiceIntent);
}
else if(networkInfo != null){
NetworkInfo.DetailedState state = networkInfo.getDetailedState();
Log.i(TAG, state.name());
}
else {
Log.i(TAG, "lost connection");
}
}//end onReceive
};//end NetworkReceiver
WebsocketServices
public class WebSocketServices extends IntentService {
public static final String TAG = WebSocketServices.class.getSimpleName();
private static String SOCKET_ADDR = "http://171.0.0.1:8080";
private String message = null;
private WebSocket socket = null;
public WebSocketServices() {
super("DownloadService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "onHandleIntent");
//SOCKET_ADDR = intent.getStringExtra("ip");
if(socket==null || !socket.isOpen() || socket.isPaused())
connectToPASocket(SOCKET_ADDR);
Log.d(TAG,"Service Invoke Function");
}//end onHandleIntent
//=====================================================================================
// Socket connection
//=====================================================================================
private void connectToPASocket(String SOCKET_ADDR) {
Log.i(TAG, "connectToPASocket()");
// Checking
if (socket != null && socket.isOpen()) return;
// Initiate web socket connection
AsyncHttpClient.getDefaultInstance().websocket(SOCKET_ADDR, null,
new AsyncHttpClient.WebSocketConnectCallback() {
@Override
public void onCompleted(Exception ex, WebSocket webSocket) {
Log.i(TAG, "onCompleted");
if (ex != null) {
Log.i(TAG, "onCompleted > if (ex != null)");
ex.printStackTrace();
return;
}
socket = webSocket;
socket.setStringCallback(new StringCallback() {
public void onStringAvailable(String s) {
Log.i(TAG, "socket.setStringCallback > onStringAvailable - s => " + s);
System.out.println("I got a string: " + s);
message = s;
}// end onStringAvailable
});// end socket.setStringCallback
socket.setDataCallback(new DataCallback() { // Find out what this does
@Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
Log.i(TAG, "socket.setDataCallback > onDataAvailable | emitter=> " + emitter + " | bb => " + bb);
System.out.println("I got some bytes!");
// note that this data has been read
bb.recycle();
}
});// end webSocket.setDataCallback
}// end onCompleted
});// end AsyncHttpClient.getDefaultInstance()
}// end connectToPASocket
}//end WebSocketServices
尝试过滤 onReceive 方法中的操作 - 类似于
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()))
发生这种情况是因为在您返回应用程序后 onCreate 将被第二次调用,并且它会与 socket 建立另一个连接。
所以如果您的 IntentService 仍然是 运行 ,您可以简单地不要启动其他服务,就像这样:
onCreate... of MainActivity
if(isMyServiceRunning(WebSocketServices.class)){
Intent startServiceIntent = new Intent(this, WebSocketServices.class);
startService(startServiceIntent);
}
方法看你的服务是不是运行
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
您应该使用常规服务,而不是意图服务。一旦意图服务完成,它就结束了。一个服务可以启动一个后台线程来维持网络套接字连接,直到你明确地杀死它;或者 OS 回收服务的内存(您需要在其中重新启动它)。
楼主,我也有类似的问题。
不要使用 intentService。只需使用服务。因为一旦 intentService 完成,它就会自行完成。
改成服务后,你可以做的是使用布尔值来检查你的服务是否已经启动,如下所示:
boolean isSockeStarted = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
if (socket == null || !socket.isOpen() || socket.isPaused()) {
if (isSockeStarted) { //not started
} else {
isSockeStarted = true;
}
}
....
也就是说,该服务只会启动一次。直到你手动杀死它。
它对我有用,试着让我知道。
我已经创建了一个网络套接字服务。但它一直在建立多个连接
我只想让应用建立一个连接,除非网络连接断开然后建立另一个。 但是现在,如果我按下 phone 上的主页按钮,它就会建立一个连接。然后返回应用程序,它将建立另一个连接。
谢谢大家的帮助。
onCreate... 我的 MainActivity
Intent startServiceIntent = new Intent(this, WebSocketServices.class);
startService(startServiceIntent);
清单
<!-- WebSocket -->
<receiver
android:name="com.example.basicplayerapp.core.NetworkReceiver">
<intent-filter >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.example.basicplayerapp.core.WebSocketServices"></service>
网络接收器
public class NetworkReceiver extends BroadcastReceiver {
public static final String TAG = HomeActivity.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
Log.i(TAG, "connected");
Intent startServiceIntent = new Intent(context, WebSocketServices.class);
context.startService(startServiceIntent);
}
else if(networkInfo != null){
NetworkInfo.DetailedState state = networkInfo.getDetailedState();
Log.i(TAG, state.name());
}
else {
Log.i(TAG, "lost connection");
}
}//end onReceive
};//end NetworkReceiver
WebsocketServices
public class WebSocketServices extends IntentService {
public static final String TAG = WebSocketServices.class.getSimpleName();
private static String SOCKET_ADDR = "http://171.0.0.1:8080";
private String message = null;
private WebSocket socket = null;
public WebSocketServices() {
super("DownloadService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "onHandleIntent");
//SOCKET_ADDR = intent.getStringExtra("ip");
if(socket==null || !socket.isOpen() || socket.isPaused())
connectToPASocket(SOCKET_ADDR);
Log.d(TAG,"Service Invoke Function");
}//end onHandleIntent
//=====================================================================================
// Socket connection
//=====================================================================================
private void connectToPASocket(String SOCKET_ADDR) {
Log.i(TAG, "connectToPASocket()");
// Checking
if (socket != null && socket.isOpen()) return;
// Initiate web socket connection
AsyncHttpClient.getDefaultInstance().websocket(SOCKET_ADDR, null,
new AsyncHttpClient.WebSocketConnectCallback() {
@Override
public void onCompleted(Exception ex, WebSocket webSocket) {
Log.i(TAG, "onCompleted");
if (ex != null) {
Log.i(TAG, "onCompleted > if (ex != null)");
ex.printStackTrace();
return;
}
socket = webSocket;
socket.setStringCallback(new StringCallback() {
public void onStringAvailable(String s) {
Log.i(TAG, "socket.setStringCallback > onStringAvailable - s => " + s);
System.out.println("I got a string: " + s);
message = s;
}// end onStringAvailable
});// end socket.setStringCallback
socket.setDataCallback(new DataCallback() { // Find out what this does
@Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
Log.i(TAG, "socket.setDataCallback > onDataAvailable | emitter=> " + emitter + " | bb => " + bb);
System.out.println("I got some bytes!");
// note that this data has been read
bb.recycle();
}
});// end webSocket.setDataCallback
}// end onCompleted
});// end AsyncHttpClient.getDefaultInstance()
}// end connectToPASocket
}//end WebSocketServices
尝试过滤 onReceive 方法中的操作 - 类似于
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()))
发生这种情况是因为在您返回应用程序后 onCreate 将被第二次调用,并且它会与 socket 建立另一个连接。 所以如果您的 IntentService 仍然是 运行 ,您可以简单地不要启动其他服务,就像这样:
onCreate... of MainActivity
if(isMyServiceRunning(WebSocketServices.class)){
Intent startServiceIntent = new Intent(this, WebSocketServices.class);
startService(startServiceIntent);
}
方法看你的服务是不是运行
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
您应该使用常规服务,而不是意图服务。一旦意图服务完成,它就结束了。一个服务可以启动一个后台线程来维持网络套接字连接,直到你明确地杀死它;或者 OS 回收服务的内存(您需要在其中重新启动它)。
楼主,我也有类似的问题。
不要使用 intentService。只需使用服务。因为一旦 intentService 完成,它就会自行完成。
改成服务后,你可以做的是使用布尔值来检查你的服务是否已经启动,如下所示:
boolean isSockeStarted = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
if (socket == null || !socket.isOpen() || socket.isPaused()) {
if (isSockeStarted) { //not started
} else {
isSockeStarted = true;
}
}
....
也就是说,该服务只会启动一次。直到你手动杀死它。
它对我有用,试着让我知道。