NativeScript Android应用请求权限时崩溃:报错'removeAllCookies must be called on a thread with a running Looper'
看起来你碰到的这个崩溃有点棘手——虽然你的代码是在请求存储权限,但Logcat里的错误指向了WebView的Cookie操作线程问题,再加上JNI错误,大概率是两个核心问题叠加导致的:
问题根源分析
- 线程上下文错误:Android的很多UI相关操作(包括WebView的内部逻辑、权限请求的某些处理)必须在UI主线程执行,而你的代码可能是在非UI线程被触发的。Logcat里的
removeAllCookies must be called on a thread with a running Looper错误,就是因为某个操作在没有Looper的后台线程调用了需要主线程的WebView方法,哪怕这个操作看起来和你的权限请求无关,可能是NativeScript上下文或系统内部的连锁反应。 - JNI调用参数错误:你原来的代码里,
requestPermissions方法传的是单个字符串,但原生Android的requestPermissions第一个参数要求是字符串数组,这个参数不匹配直接会触发JNI错误,导致崩溃。
修复方案
1. 修正权限请求代码,确保在UI主线程执行
用NativeScript提供的runOnUiThread方法包裹所有权限请求逻辑,同时修正requestPermissions的参数为数组:
import { Application } from "@nativescript/core"; const androidApp = Application.android; // 用runOnUiThread确保所有操作在UI主线程执行 androidApp.runOnUiThread(() => { try { const storagePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE; const foregroundActivity = androidApp.foregroundActivity; // 检查是否需要显示权限 rationale const shouldShowRationale = foregroundActivity.shouldShowRequestPermissionRationale(storagePermission); console.log("Need permission rationale:", shouldShowRationale); // 注意:requestPermissions第一个参数是权限数组! foregroundActivity.requestPermissions([storagePermission], 1988); } catch (err) { console.error("Error requesting permission:", err); } });
2. 正确处理权限请求回调
在NativeScript里,你需要监听权限请求的结果,避免后续逻辑混乱:
import { Application, AndroidApplication } from "@nativescript/core"; // 监听权限请求结果事件 Application.android.on(AndroidApplication.activityRequestPermissionsEvent, (args) => { const { requestCode, permissions, grantResults } = args; // 匹配你之前用的请求码1988 if (requestCode === 1988) { const isGranted = grantResults[0] === android.content.pm.PackageManager.PERMISSION_GRANTED; if (isGranted) { console.log("Storage permission granted! You can now perform your operation."); // 在这里执行需要存储权限的代码 } else { console.log("Storage permission denied. You might want to prompt the user to enable it in settings."); } } });
3. 检查WebView相关依赖(如果有)
如果你的应用里使用了WebView相关的插件或代码,确保所有WebView的操作(比如Cookie管理)都在UI主线程执行。如果是第三方插件导致的,可以尝试更新插件到最新版本,或者查看插件的社区反馈有没有类似问题的解决方案。
4. 确认权限已在Manifest中声明
确保App_Resources/Android/src/main/AndroidManifest.xml里已经添加了存储权限:
<!-- 针对Android 10及以下的存储权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <!-- 如果你需要在Android 11+访问所有文件,添加这个(否则建议用Scoped Storage) --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
为什么这能解决问题?
runOnUiThread保证了所有和Android系统交互的代码都在主线程执行,避免了Looper相关的线程错误;- 修正
requestPermissions的参数为数组,解决了JNI调用的类型不匹配问题; - 监听权限结果是NativeScript里处理权限的标准方式,能让你正确处理授权或拒绝后的逻辑。
内容来源于stack exchange
相关产品推荐
相关产品推荐

