From e89a3918c5a88932f2efb036db16081b6881fc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=9C=E6=96=B9=E5=A4=95=E9=98=B3?= Date: Thu, 29 Sep 2022 18:23:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dandroid=20sdk=20=E4=B8=80?= =?UTF-8?q?=E5=A4=84bug=20=E9=A2=91=E5=8F=91=E5=88=87=E6=8D=A2wifi?= =?UTF-8?q?=E5=92=8C=E7=A7=BB=E5=8A=A8=E7=BD=91=E7=BB=9C=EF=BC=8C=E6=A6=82?= =?UTF-8?q?=E7=8E=87=E5=87=BA=E7=8E=B0=E6=97=A0=E6=B3=95=E9=87=8D=E8=BF=9E?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cim-client-sdk/cim-android-sdk/pom.xml | 2 +- .../cim/sdk/android/CIMCacheManager.java | 4 + ...torManager.java => CIMConnectManager.java} | 78 +++++++++++-------- .../android/CIMEventBroadcastReceiver.java | 19 +---- .../cim/sdk/android/CIMPushService.java | 69 ++++++++++------ .../cim/sdk/android/constant/BundleKey.java | 2 + .../cim/sdk/android/constant/CIMConstant.java | 2 +- .../cim-client-android/app/build.gradle | 2 +- 8 files changed, 104 insertions(+), 74 deletions(-) rename cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/{CIMConnectorManager.java => CIMConnectManager.java} (86%) diff --git a/cim-client-sdk/cim-android-sdk/pom.xml b/cim-client-sdk/cim-android-sdk/pom.xml index a45c8ae..0153197 100755 --- a/cim-client-sdk/cim-android-sdk/pom.xml +++ b/cim-client-sdk/cim-android-sdk/pom.xml @@ -6,7 +6,7 @@ com.farsunset cim-android-sdk - 4.2.7 + 4.2.8 jar ${project.groupId}:${project.artifactId} diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMCacheManager.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMCacheManager.java index f4d4473..43adefa 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMCacheManager.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMCacheManager.java @@ -46,6 +46,10 @@ class CIMCacheManager { public static final String KEY_NTC_CHANNEL_NAME = "KEY_NTC_CHANNEL_NAME"; + public static final String KEY_NTC_CHANNEL_MESSAGE = "KEY_NTC_CHANNEL_MESSAGE"; + + public static final String KEY_NTC_CHANNEL_ICON = "KEY_NTC_CHANNEL_ICON"; + public static final String CONTENT_URI = "content://%s.cim.provider"; diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectorManager.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectManager.java similarity index 86% rename from cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectorManager.java rename to cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectManager.java index 630a9a1..c6bef22 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectorManager.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMConnectManager.java @@ -26,6 +26,7 @@ import android.content.Intent; import android.os.Handler; import com.farsunset.cim.sdk.android.coder.ClientMessageDecoder; import com.farsunset.cim.sdk.android.coder.ClientMessageEncoder; +import com.farsunset.cim.sdk.android.constant.BundleKey; import com.farsunset.cim.sdk.android.constant.CIMConstant; import com.farsunset.cim.sdk.android.constant.IntentAction; import com.farsunset.cim.sdk.android.logger.CIMLogger; @@ -35,18 +36,18 @@ import java.io.IOException; import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.SocketTimeoutException; +import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; /* * 连接服务端管理,cim核心处理类,管理连接,以及消息处理 */ -class CIMConnectorManager { - - private static CIMConnectorManager manager; +class CIMConnectManager { private static final int READ_BUFFER_SIZE = 2048; @@ -76,20 +77,12 @@ class CIMConnectorManager { private final Random random = new Random(); - private CIMConnectorManager(Context context) { + private final AtomicBoolean connecting = new AtomicBoolean(false); + + public CIMConnectManager(Context context) { this.context = context; } - public static synchronized CIMConnectorManager getManager(Context context) { - - if (manager == null) { - manager = new CIMConnectorManager(context); - } - - return manager; - - } - public void connect(final String host, final int port) { if (!CIMPushManager.isNetworkConnected(context)) { @@ -102,7 +95,7 @@ class CIMConnectorManager { return; } - if (isConnected()) { + if (isConnected() || connecting.get()) { return; } @@ -118,6 +111,8 @@ class CIMConnectorManager { try { + connecting.set(true); + socketChannel = SocketChannel.open(); socketChannel.configureBlocking(true); socketChannel.socket().setTcpNoDelay(true); @@ -129,6 +124,8 @@ class CIMConnectorManager { handleConnectedEvent(); + connecting.set(false); + /* *开始读取来自服务端的消息,先读取3个字节的消息头 */ @@ -141,10 +138,12 @@ class CIMConnectorManager { */ close(); - } catch (ConnectException | SocketTimeoutException ignore) { - handleConnectAbortedEvent(); - } catch (IOException ignore) { + } catch (ConnectException | SocketTimeoutException | UnknownHostException exception) { + handleConnectFailedEvent(exception); + } catch (IOException exception) { handleDisconnectedEvent(); + }finally { + connecting.set(false); } }); } @@ -155,12 +154,7 @@ class CIMConnectorManager { return; } - try { - socketChannel.close(); - } catch (IOException ignore) { - } finally { - this.onSessionClosed(); - } + this.closeForce(); } public boolean isConnected() { @@ -200,6 +194,15 @@ class CIMConnectorManager { } + private void closeForce(){ + try { + socketChannel.close(); + } catch (IOException ignore) { + } finally { + this.onSessionClosed(); + } + } + private void onSessionCreated() { LOGGER.sessionCreated(socketChannel); @@ -270,27 +273,36 @@ class CIMConnectorManager { private final Handler idleHandler = new Handler() { @Override public void handleMessage(android.os.Message m) { - workerExecutor.execute(CIMConnectorManager.this::onSessionIdle); + workerExecutor.execute(CIMConnectManager.this::onSessionIdle); } }; private void handleDisconnectedEvent() { - close(); + closeForce(); } - private void handleConnectAbortedEvent() { + private void handleConnectFailedEvent(Exception exception) { - /* - * 随机3-10秒后重连 - */ - long interval = 3000L + random.nextInt(7001) ; + long retryAfter; - LOGGER.connectFailure(interval); + if (exception instanceof UnknownHostException){ + /* + * 通常是网络由WIFI切换为移动网出现这个异常 + */ + retryAfter = 3000L; + }else { + /* + * 随机3-10秒后重连 + */ + retryAfter = 3000L + random.nextInt(7001) ; + } + + LOGGER.connectFailure(retryAfter); Intent intent = new Intent(); intent.setPackage(context.getPackageName()); intent.setAction(IntentAction.ACTION_CONNECT_FAILED); - intent.putExtra("interval", interval); + intent.putExtra(BundleKey.KEY_RECONNECT_AFTER, retryAfter); context.sendBroadcast(intent); } diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java index 67a2ed9..7905791 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMEventBroadcastReceiver.java @@ -77,7 +77,7 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { * cim连接服务器失败事件 */ if (IntentAction.ACTION_CONNECT_FAILED.equals(action)) { - long interval = intent.getLongExtra("interval", CIMConstant.RECONNECT_INTERVAL_TIME); + long interval = intent.getLongExtra(BundleKey.KEY_RECONNECT_AFTER, CIMConstant.RECONNECT_INTERVAL_TIME); onInnerConnectFailed(interval); } @@ -126,22 +126,16 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { private void onInnerConnectionClosed() { CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false); - - if (CIMPushManager.isNetworkConnected(context)) { - connect(0); - } - + connect(0L); onConnectionClosed(); } private void onInnerConnectFailed(long interval) { - if (CIMPushManager.isNetworkConnected(context)) { + onConnectFailed(); - onConnectFailed(); + connect(interval); - connect(interval); - } } private void onInnerConnectFinished() { @@ -152,11 +146,6 @@ public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver { } private void onDevicesNetworkChanged() { - - if (CIMPushManager.isNetworkConnected(context)) { - connect(0); - } - onNetworkChanged(); } diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMPushService.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMPushService.java index c155f1f..6d8bd1b 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMPushService.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/CIMPushService.java @@ -53,7 +53,8 @@ public class CIMPushService extends Service { private static final int NOTIFICATION_ID = Integer.MAX_VALUE; - private CIMConnectorManager connectorManager; + private CIMConnectManager connectManager; + private KeepAliveBroadcastReceiver keepAliveReceiver; private ConnectivityManager connectivityManager; private NotificationManager notificationManager; @@ -62,7 +63,7 @@ public class CIMPushService extends Service { @Override public void onCreate() { - connectorManager = CIMConnectorManager.getManager(this.getApplicationContext()); + connectManager = new CIMConnectManager(this); notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); @@ -84,6 +85,7 @@ public class CIMPushService extends Service { @Override public void onAvailable(Network network) { sendBroadcast(new Intent(IntentAction.ACTION_NETWORK_CHANGED)); + handleKeepAlive(); } @Override @@ -125,11 +127,11 @@ public class CIMPushService extends Service { } if (ServiceAction.ACTION_SEND_REQUEST_BODY.equals(action)) { - connectorManager.send((SentBody) newIntent.getSerializableExtra(BundleKey.KEY_SEND_BODY)); + connectManager.send((SentBody) newIntent.getSerializableExtra(BundleKey.KEY_SEND_BODY)); } if (ServiceAction.ACTION_CLOSE_CIM_CONNECTION.equals(action)) { - connectorManager.close(); + connectManager.close(); } if (ServiceAction.ACTION_ACTIVATE_PUSH_SERVICE.equals(action)) { @@ -137,12 +139,12 @@ public class CIMPushService extends Service { } if (ServiceAction.ACTION_DESTROY_CIM_SERVICE.equals(action)) { - connectorManager.close(); + connectManager.close(); this.stopSelf(); } if (ServiceAction.ACTION_CIM_CONNECTION_PONG.equals(action)) { - connectorManager.send(Pong.getInstance()); + connectManager.send(Pong.getInstance()); } if (ServiceAction.ACTION_SET_LOGGER_EATABLE.equals(action)) { @@ -195,7 +197,7 @@ public class CIMPushService extends Service { return; } - connectorManager.connect(host, port); + connectManager.connect(host, port); } @@ -203,8 +205,8 @@ public class CIMPushService extends Service { CIMLogger.getLogger().connectState(true, CIMPushManager.isStopped(this), CIMPushManager.isDestroyed(this)); - if (connectorManager.isConnected()) { - connectorManager.pong(); + if (connectManager.isConnected()) { + connectManager.pong(); return; } @@ -252,9 +254,14 @@ public class CIMPushService extends Service { if (notificationManager.getNotificationChannel(PERSIST_NTC_CHANNEL_ID) != null) { - startForeground(NOTIFICATION_ID, new Notification.Builder(this,PERSIST_NTC_CHANNEL_ID) - .setContentTitle(CIMCacheManager.getString(this,CIMCacheManager.KEY_NTC_CHANNEL_NAME)) - .build()); + + int icon = CIMCacheManager.getInt(this,CIMCacheManager.KEY_NTC_CHANNEL_ICON); + String title = CIMCacheManager.getString(this,CIMCacheManager.KEY_NTC_CHANNEL_NAME); + String message = CIMCacheManager.getString(this,CIMCacheManager.KEY_NTC_CHANNEL_MESSAGE); + + Notification notification = makeNotification(PERSIST_NTC_CHANNEL_ID,icon,title,message); + + startForeground(NOTIFICATION_ID, notification); return; } @@ -267,9 +274,9 @@ public class CIMPushService extends Service { notificationManager.createNotificationChannel(channel); } - startForeground(NOTIFICATION_ID, new Notification.Builder(this,TRANSIENT_NTC_CHANNEL_ID) - .setContentTitle(CIMPushService.class.getSimpleName()) - .build()); + Notification notification = makeNotification(TRANSIENT_NTC_CHANNEL_ID,0,CIMPushService.class.getSimpleName(),null); + + startForeground(NOTIFICATION_ID, notification); } @@ -277,6 +284,8 @@ public class CIMPushService extends Service { private void createPersistNotification(String channelName ,String message,int icon) { CIMCacheManager.putString(this,CIMCacheManager.KEY_NTC_CHANNEL_NAME,channelName); + CIMCacheManager.putString(this,CIMCacheManager.KEY_NTC_CHANNEL_MESSAGE,message); + CIMCacheManager.putInt(this,CIMCacheManager.KEY_NTC_CHANNEL_ICON,icon); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel(PERSIST_NTC_CHANNEL_ID) == null) { NotificationChannel channel = new NotificationChannel(PERSIST_NTC_CHANNEL_ID,channelName, NotificationManager.IMPORTANCE_DEFAULT); @@ -287,26 +296,40 @@ public class CIMPushService extends Service { notificationManager.createNotificationChannel(channel); } - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); - intent.setPackage(getPackageName()); + Notification notification = makeNotification(PERSIST_NTC_CHANNEL_ID,icon,channelName,message); + + startForeground(NOTIFICATION_ID,notification); + } + + + private Notification makeNotification(String channel,int icon,String title,String message){ Notification.Builder builder; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ - builder = new Notification.Builder(this,PERSIST_NTC_CHANNEL_ID); + builder = new Notification.Builder(this,channel); }else { builder = new Notification.Builder(this); } builder.setAutoCancel(false) .setOngoing(false) - .setSmallIcon(icon) .setWhen(System.currentTimeMillis()) - .setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)) - .setContentTitle(channelName) + .setContentIntent(getPendingIntent()) + .setContentTitle(title) .setContentText(message); - startForeground(NOTIFICATION_ID, builder.build()); + if (icon > 0){ + builder.setSmallIcon(icon); + } + + return builder.build(); + } + + private PendingIntent getPendingIntent(){ + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); + intent.setPackage(getPackageName()); + return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); } private class KeepAliveBroadcastReceiver extends BroadcastReceiver { diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/BundleKey.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/BundleKey.java index 6476c86..bc3151b 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/BundleKey.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/BundleKey.java @@ -35,4 +35,6 @@ public interface BundleKey { String KEY_NOTIFICATION_ICON = "KEY_NOTIFICATION_ICON"; + String KEY_RECONNECT_AFTER = "KEY_RECONNECT_AFTER"; + } diff --git a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/CIMConstant.java b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/CIMConstant.java index 582f1fe..98514cb 100644 --- a/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/CIMConstant.java +++ b/cim-client-sdk/cim-android-sdk/src/main/java/com/farsunset/cim/sdk/android/constant/CIMConstant.java @@ -23,7 +23,7 @@ package com.farsunset.cim.sdk.android.constant; public interface CIMConstant { - long RECONNECT_INTERVAL_TIME = 5 * 1000; + long RECONNECT_INTERVAL_TIME = 5000L; /* * 消息头长度为3个字节,第一个字节为消息类型,第二,第三字节 转换int后为消息长度 diff --git a/cim-use-examples/cim-client-android/app/build.gradle b/cim-use-examples/cim-client-android/app/build.gradle index 378c9e4..408bd3b 100644 --- a/cim-use-examples/cim-client-android/app/build.gradle +++ b/cim-use-examples/cim-client-android/app/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation "com.farsunset:cim-android-sdk:4.2.7" + implementation "com.farsunset:cim-android-sdk:4.2.8" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.annotation:annotation:1.1.0'