Skip to content

Commit 6f97df6

Browse files
committed
fix(Android): 修复多个页面同时打开时,只能有一个页面响应热重载的问题
1 parent c8ff53d commit 6f97df6

5 files changed

Lines changed: 66 additions & 40 deletions

File tree

android/hummer-dev-tools/src/main/java/com/didi/hummer/devtools/HummerDevTools.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ public interface IParameterInjector {
3434
void injectParameter(StringBuilder builder);
3535
}
3636

37-
public interface IRefreshCallback {
38-
void onRefresh();
37+
public interface IHotReloadCallback {
38+
void onHotReload();
3939
}
4040

4141
private HummerContext hmContext;
@@ -56,8 +56,8 @@ public HummerDevTools(HummerContext context) {
5656
public HummerDevTools(HummerContext context, DevToolsConfig config) {
5757
hmContext = context;
5858
entrance = new DevToolsEntrance(context);
59-
wsManager = new WebSocketManager();
60-
logManager = new HummerLogManager(wsManager);
59+
wsManager = WebSocketManager.getInstance();
60+
logManager = new HummerLogManager();
6161
hmContext.registerInvoker(new HummerInvokerWrapper(logManager));
6262
entrance.setLogManager(logManager);
6363
netManager = new HummerNetManager();
@@ -69,28 +69,28 @@ public HummerDevTools(HummerContext context, DevToolsConfig config) {
6969
}
7070
}
7171

72-
public void release() {
73-
wsManager.close();
72+
public void release(HummerContext hmContext) {
73+
wsManager.release(hmContext.getPageUrl());
7474
}
7575

7676
/**
7777
* 初始化连接
7878
*/
79-
public void initConnection(HummerContext context, String url, IRefreshCallback callback) {
79+
public void initConnection(HummerContext context, String url, IHotReloadCallback callback) {
8080
connectWebSocket(url, callback);
8181
initRefreshView(context, callback);
8282
}
8383

8484
/**
85-
* 与CLI建立WebSocket连接,用于热更新和日志输出
85+
* 与CLI建立WebSocket连接,用于热重载和日志输出
8686
*/
87-
private void connectWebSocket(String url, IRefreshCallback callback) {
87+
private void connectWebSocket(String url, IHotReloadCallback callback) {
8888
wsManager.connect(url, msg -> {
8989
msg = getUrlFromWS(msg);
9090
if (url != null && url.equalsIgnoreCase(msg)) {
91-
// 热更新
91+
// 热重载
9292
if (callback != null) {
93-
callback.onRefresh();
93+
callback.onHotReload();
9494
}
9595
}
9696
});
@@ -99,11 +99,11 @@ private void connectWebSocket(String url, IRefreshCallback callback) {
9999
/**
100100
* 初始化刷新按钮
101101
*/
102-
private void initRefreshView(HummerContext context, IRefreshCallback callback) {
102+
private void initRefreshView(HummerContext context, IHotReloadCallback callback) {
103103
FloatLayout floatLayout = new FloatLayout(context);
104104
floatLayout.setOnClickListener(v -> {
105105
if (callback != null) {
106-
callback.onRefresh();
106+
callback.onHotReload();
107107
}
108108
});
109109
ViewCompat.setElevation(floatLayout, 9000);

android/hummer-dev-tools/src/main/java/com/didi/hummer/devtools/manager/HummerLogManager.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,9 @@ public interface ILogListener {
1919
void onLogAdd(LogBean log);
2020
}
2121

22-
private WebSocketManager wsManager;
2322
private List<LogBean> logs = new ArrayList<>();
2423
private ILogListener mListener;
2524

26-
public HummerLogManager(WebSocketManager manager) {
27-
wsManager = manager;
28-
}
29-
3025
public void registerListener(ILogListener listener) {
3126
mListener = listener;
3227
}
@@ -57,6 +52,6 @@ public void addLog(int level, String msg) {
5752
*/
5853
public void sendLog2Cli(LogBean bean) {
5954
WSMsg<LogBean> wsMsg = new WSMsg<>(WSMsg.TYPE_LOG, bean);
60-
wsManager.sendMsg(HMGsonUtil.toJson(wsMsg));
55+
WebSocketManager.getInstance().sendMsg(HMGsonUtil.toJson(wsMsg));
6156
}
6257
}

android/hummer-dev-tools/src/main/java/com/didi/hummer/devtools/ws/WebSocketManager.java

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import android.os.Looper;
66
import android.text.TextUtils;
77

8+
import java.util.HashMap;
9+
import java.util.Map;
10+
811
import okhttp3.OkHttpClient;
912
import okhttp3.Request;
1013
import okhttp3.Response;
@@ -24,32 +27,53 @@ public interface WSMsgListener {
2427

2528
private static final int RECONNECT_DELAY_MS = 2000;
2629

30+
private static volatile WebSocketManager instance = null;
2731
private static OkHttpClient client;
2832
private WebSocket webSocket;
2933
private String mWsUrl;
3034
private Handler mHandler;
3135
private boolean mClosed;
3236
private boolean mIsReconnectWaiting;
37+
private Map<String, WSMsgListener> wsMsgListeners = new HashMap<>();
38+
39+
public static WebSocketManager getInstance() {
40+
if (instance == null) {
41+
synchronized (WebSocketManager.class) {
42+
if (instance == null) {
43+
instance = new WebSocketManager();
44+
}
45+
}
46+
}
47+
return instance;
48+
}
3349

34-
public WebSocketManager() {
50+
private WebSocketManager() {
3551
mHandler = new Handler(Looper.getMainLooper());
3652
if (client == null) {
3753
client = new OkHttpClient();
3854
}
3955
}
4056

4157
public void connect(String url, WSMsgListener listener) {
58+
if (!wsMsgListeners.containsKey(url)) {
59+
wsMsgListeners.put(url, listener);
60+
}
61+
62+
if (webSocket != null) {
63+
return;
64+
}
65+
4266
mWsUrl = toWSUrl(url);
43-
doConnect(mWsUrl, listener);
67+
doConnect();
4468
}
4569

46-
private void doConnect(String url, WSMsgListener listener) {
47-
if (TextUtils.isEmpty(url)) {
70+
private void doConnect() {
71+
if (TextUtils.isEmpty(mWsUrl)) {
4872
return;
4973
}
5074

5175
okhttp3.Request request = new Request.Builder()
52-
.url(url)
76+
.url(mWsUrl)
5377
.build();
5478

5579
client.newWebSocket(request, new WebSocketListener() {
@@ -61,37 +85,40 @@ public void onOpen(okhttp3.WebSocket webSocket, Response response) {
6185
@Override
6286
public void onClosed(okhttp3.WebSocket webSocket, int code, String reason) {
6387
if (!mClosed) {
64-
reconnect(listener);
88+
reconnect();
6589
}
6690
}
6791

6892
@Override
6993
public void onFailure(okhttp3.WebSocket webSocket, Throwable t, Response response) {
7094
t.printStackTrace();
7195
if (!mClosed) {
72-
reconnect(listener);
96+
reconnect();
7397
}
7498
}
7599

76100
@Override
77101
public void onMessage(okhttp3.WebSocket webSocket, String text) {
78102
mHandler.post(() -> {
79-
if (listener != null) {
80-
listener.onMsgReceived(text);
103+
for (String url : wsMsgListeners.keySet()) {
104+
WSMsgListener l = wsMsgListeners.get(url);
105+
if (l != null) {
106+
l.onMsgReceived(text);
107+
}
81108
}
82109
});
83110
}
84111
});
85112
}
86113

87-
private void reconnect(WSMsgListener listener) {
114+
private void reconnect() {
88115
if (mClosed || mIsReconnectWaiting) {
89116
return;
90117
}
91118
mIsReconnectWaiting = true;
92119
mHandler.postDelayed(() -> {
93120
if (!mClosed) {
94-
doConnect(mWsUrl, listener);
121+
doConnect();
95122
}
96123
mIsReconnectWaiting = false;
97124
}, RECONNECT_DELAY_MS);
@@ -103,7 +130,12 @@ public void sendMsg(String msg) {
103130
}
104131
}
105132

106-
public void close() {
133+
public void release(String url) {
134+
// close();
135+
wsMsgListeners.remove(url);
136+
}
137+
138+
private void close() {
107139
mClosed = true;
108140
if (webSocket != null) {
109141
try {

android/hummer-sdk/src/main/java/com/didi/hummer/context/HummerContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,11 @@ public boolean onBack() {
188188
}
189189

190190
/**
191-
* 用于调式的时候刷新用
191+
* 用于调式时的热重载
192192
*
193193
* @return
194194
*/
195-
public void onRefresh(String url) {
195+
public void onHotReload(String url) {
196196
stop();
197197
pause();
198198
destroy();

android/hummer/src/main/java/com/didi/hummer/HummerRender.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public void onDestroy() {
124124
if (DebugUtil.isDebuggable()) {
125125
HummerDebugger.release(hmContext);
126126
if (devTools != null) {
127-
devTools.release();
127+
devTools.release(hmContext);
128128
}
129129
}
130130
}
@@ -215,7 +215,7 @@ public void renderWithUrl(String url) {
215215
// 调试插件
216216
HummerDebugger.init(hmContext, url);
217217

218-
// 热更新
218+
// 热重载
219219
if (devTools != null) {
220220
devTools.initConnection(hmContext, url, () -> {
221221
requestJsBundle(url, true);
@@ -226,8 +226,7 @@ public void renderWithUrl(String url) {
226226
requestJsBundle(url, false);
227227
}
228228

229-
private void requestJsBundle(String url, boolean isRefresh) {
230-
long startTime = System.currentTimeMillis();
229+
private void requestJsBundle(String url, boolean isHotReload) {
231230
NetworkUtil.httpGet(url, (HttpCallback<String>) response -> {
232231
if (isDestroyed.get()) {
233232
if (renderCallback != null) {
@@ -253,13 +252,13 @@ private void requestJsBundle(String url, boolean isRefresh) {
253252
perfInfo.jsFetchTimeCost = (System.currentTimeMillis() - startTime);
254253

255254
// 如果是刷新流程,那么在执行JS之前,需要先模拟走一遍生命周期,来做相关的清理工作
256-
if (DebugUtil.isDebuggable() && isRefresh) {
257-
hmContext.onRefresh(url);
255+
if (DebugUtil.isDebuggable() && isHotReload) {
256+
hmContext.onHotReload(url);
258257
}
259258

260259
render(response.data, url);
261260

262-
if (DebugUtil.isDebuggable() && isRefresh) {
261+
if (DebugUtil.isDebuggable() && isHotReload) {
263262
Toast.makeText(hmContext, "页面已刷新", Toast.LENGTH_SHORT).show();
264263
}
265264
});

0 commit comments

Comments
 (0)