Android WebView点击文件选择控件触发onShowFileChooser时App崩溃问题
WebView onShowFileChooser方法内执行操作崩溃解决方案
崩溃核心原因
- 你使用的自定义全局
Global.context存在无效引用问题:如果该全局context未正确初始化、或者指向已经销毁的Activity实例,调用时会直接触发空指针或非法状态异常,这是你执行任意操作就崩溃的核心原因。 - 你编写的Toast代码缺少
.show()调用,属于语法疏漏。 - 若在
filePathCallback.onReceiveValue()执行前你的操作抛出异常,会导致WebView的文件选择回调没有被正确响应,也会引发后续崩溃。
修复方案
1. 替换上下文引用
不要依赖自定义的全局context,直接使用当前Activity实例作为UI操作的上下文,避免无效引用问题。
2. 规范filePathCallback的调用逻辑
每次进入onShowFileChooser时先清空之前的callback引用,避免重复回调引发异常,页面销毁时也要主动触发回调避免内存泄漏。
3. 修复后的完整代码示例
package tk.anative class MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding // 全局存储文件选择回调引用 private var mFilePathCallback: ValueCallback<Array<Uri>>? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) Global.webView = binding.webView WebListener.initiate() Global.webView.webChromeClient = object : WebChromeClient() { override fun onShowFileChooser( webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams ): Boolean { // 先处理之前未完成的回调 mFilePathCallback?.onReceiveValue(null) mFilePathCallback = filePathCallback // 所有UI操作使用当前Activity作为上下文,补全Toast的show()调用 Toast.makeText(this@MainActivity, "Hello", Toast.LENGTH_LONG).show() // 不需要选择文件直接返回null mFilePathCallback?.onReceiveValue(null) mFilePathCallback = null return true } } WebSettings.setUp() } override fun onDestroy() { // 页面销毁时主动回调避免WebView异常 mFilePathCallback?.onReceiveValue(null) super.onDestroy() } }
额外注意事项
- 如果你的应用目标版本 >= 33,需要提前申请
READ_MEDIA_IMAGES、相机等相关权限,权限缺失也会触发操作崩溃 - 不要在
onShowFileChooser内执行耗时操作,所有UI操作必须在主线程执行
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

