安卓收到BOOT_COMPLETED广播时能否调用JS函数及访问localStorage?
方案解答
- 直接在
BOOT_COMPLETED广播接收器的onReceive方法中调用JS函数的方案不可行,核心原因如下:- WebView实例绑定MainActivity的生命周期,设备重启后你的App未被启动时,MainActivity、WebView均未完成初始化,没有可执行JS的运行环境
- localStorage是WebView的专属存储,和加载的页面域名、WebView实例绑定,未加载对应H5页面的前提下无法读取localStorage内的闹钟数据
- 你提供的参考代码中
MainActivity.this的调用逻辑无法生效,BroadcastReceiver是独立的系统组件,无法直接持有未启动的Activity实例
- 不改动H5侧存储逻辑的折中实现方案:
安卓10及以上版本先申请SYSTEM_ALERT_WINDOW悬浮窗权限,收到开机广播后启动一个透明无UI的Activity,在该Activity中初始化WebView并加载你的H5页面,等页面加载完成后调用JS方法完成闹钟重注册,流程结束后销毁该透明Activity即可。 - 更推荐的高稳定方案:
直接采用你设想的原生持久化存储方案,将闹钟数据同步存储到SharedPreferences中,开机广播触发后直接在接收器内读取存储的闹钟数据,通过原生AlarmManager完成注册,不需要依赖WebView和JS运行环境,也不需要额外申请后台启动权限,稳定性远高于依赖WebView的方案。
原参考代码格式化
public class DeviceBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("DeviceBootReceiver", "DeviceBootReceiver.onReceive"); if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // 原写法无法直接生效,需要调整为启动透明Activity的逻辑 // MainActivity.this.getWebViewInterface().reRegisterAllAlarm(); } } } public class WebViewInterface { private Context mContext; private WebView mWebView; public WebViewInterface(Context context, WebView webView) { mContext = context; mWebView = webView; } public void reRegisterAllAlarm() { mWebView.loadUrl("javascript:reRegisterAllAlarm()"); } }
内容的提问来源于stack exchange,提问作者Junyoung Oh
相关产品推荐
相关产品推荐

