You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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,逻辑更顺:

  1. 页面启动后先展示加载占位UI,同时初始化OneSignal、请求通知权限
  2. 监听拿到有效OneSignal ID后,再调用webView.loadUrl(目标页面地址)
  3. 后续onPageFinished触发时ID必然已就绪,直接注入JS即可

内容的提问来源于stack exchange,提问作者ElonMuskofBadIdeas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 04:54:05