如何在OneSignal设备ID准备完成后才加载Android应用的WebView
解决方案
推荐最简单的改动方案如下,不需要调整原有WebView加载逻辑,仅需在onPageFinished中补充ID就绪监听即可:
核心思路
原来的问题是onPageFinished的触发时机和OneSignal设备ID生成时机没有固定先后关系,所以经常出现ID为空的情况。我们可以在ID未就绪时,临时注册OneSignal状态监听,等ID生成后再执行JS注入,注入完成后自动移除监听避免内存泄漏。
代码实现
public void onPageFinished(WebView view, String url) { // 先尝试获取现有ID OSDeviceState deviceState = OneSignal.getDeviceState(); String oneSignalDeviceID = deviceState != null ? deviceState.getUserId() : null; if (oneSignalDeviceID != null) { // ID已就绪直接注入 injectOneSignalJs(view, oneSignalDeviceID); return; } // ID未就绪,注册一次性监听等待ID生成 OneSignal.getDeviceState().addObserver(new Observer<OSDeviceState>() { @Override public void onChanged(OSDeviceState state) { String userId = state.getUserId(); if (userId != null) { injectOneSignalJs(view, userId); // 注入完成后移除监听,避免内存泄漏 OneSignal.getDeviceState().removeObserver(this); } } }); } // 抽离注入逻辑复用 private void injectOneSignalJs(WebView view, String deviceId) { String jsCodeInsert = "javascript:document.getElementById('wp-submit').onclick = function() { jQuery.post( ajax_object.ajax_url, {action: 'onesignal_add', id: '" + deviceId + "', mode: 'mymode'}, function( response ) {console.log(response);});} "; view.loadUrl(jsCodeInsert); }
可选优化方案(适合首次启动场景)
如果是APP首次启动需要申请通知权限的场景,也可以等用户同意通知权限、拿到OneSignal ID之后再加载WebView,逻辑更顺:
- 页面启动后先展示加载占位UI,同时初始化OneSignal、请求通知权限
- 监听拿到有效OneSignal ID后,再调用
webView.loadUrl(目标页面地址) - 后续
onPageFinished触发时ID必然已就绪,直接注入JS即可
内容的提问来源于stack exchange,提问作者ElonMuskofBadIdeas
相关产品推荐
相关产品推荐

