基于API 33的Kotlin WebView应用编译错误求助
求助:WebView集成编译错误及签名打包问题
我翻遍了网络教程、YouTube视频,没找到可行方案——要么教程有错要么已经过时,只能来社区求最新解决办法,问题解决后会更新主帖贴正确代码。
我参考了一个较新的视频教程,模拟器上能跑,但生成不了签名应用包;连Android Studio官方文档的方案都出现未解析引用错误。
参考来源:
- 某YouTube视频
- Android Studio官方WebView文档
我的代码
MainActivity.kt
package com.sloth.hub import android.R import android.graphics.Bitmap import android.os.Bundle import android.view.View import android.webkit.WebView import android.webkit.WebViewClient import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.sloth.hub.ui.theme.SlothHubTheme class MainActivity : ComponentActivity() { private var myWebView: WebView? = findViewById<View>(R.id.webView) as WebView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { SlothHubTheme { // A surface container using the 'background' color from the theme Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { Greeting("Android") } } } myWebView.setWebViewClient(WebViewClient()) myWebView.loadUrl("https://app.sloths.one") val webSettings = myWebView.getSettings() webSettings.javaScriptEnabled = true } class myWebClient : WebViewClient() { override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) { super.onPageStarted(view, url, favicon) } override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { view.loadUrl(url) return true } } override fun onBackPressed() { if (myWebView!!.canGoBack()) { myWebView!!.goBack() } else { super.onBackPressed() } } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { SlothHubTheme { Greeting("Android") } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
编译错误信息
e: /home/dgriffin/AndroidStudioProjects/SlothHub/app/src/main/java/com/sloth/hub/MainActivity.kt: (23, 63): 未解析引用: webview e: /home/dgriffin/AndroidStudioProjects/SlothHub/app/src/main/java/com/sloth/hub/MainActivity.kt: (28, 18): 仅允许对WebView?类型的可空接收者使用安全调用(?.)或非空断言(!!.) e: /home/dgriffin/AndroidStudioProjects/SlothHub/app/src/main/java/com/sloth/hub/MainActivity.kt: (29, 18): 仅允许对WebView?类型的可空接收者使用安全调用(?.)或非空断言(!!.) e: /home/dgriffin/AndroidStudioProjects/SlothHub/app/src/main/java/com/sloth/hub/MainActivity.kt: (30, 36): 仅允许对WebView?类型的可空接收者使用安全调用(?.)或非空断言(!!.) --- org.gradle.api.GradleException: 编译错误。详见日志获取更多详情 Caused by: org.gradle.api.GradleException: 编译错误。详见日志获取更多详情
请求帮助解决这些编译问题,使应用能够正常编译并生成签名应用包。
错误修复方案
1. 解决「未解析引用: webview」问题
- 删掉
import android.R,改成导入自己项目的R文件:import com.sloth.hub.R(Android Studio通常会自动导入,手动补也行) - 不能在类初始化阶段调用
findViewById——此时Activity还没加载布局,获取到的WebView必然是空的,要把WebView初始化移到onCreate方法里,且必须在加载布局之后执行。
2. 解决可空类型调用错误
myWebView被声明为可空类型WebView?,调用它的方法时必须用安全调用?.或者非空断言!!.,推荐用安全调用+let来避免空指针风险。
3. 修复布局冲突问题
你现在同时用了Compose的setContent和XML布局,两者不能共存,二选一:
方案一:保留XML布局
修改MainActivity,先加载XML布局再初始化WebView:
package com.sloth.hub import android.graphics.Bitmap import android.os.Bundle import android.webkit.WebView import android.webkit.WebViewClient import androidx.activity.ComponentActivity import com.sloth.hub.R class MainActivity : ComponentActivity() { private var myWebView: WebView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 先加载XML布局 myWebView = findViewById(R.id.webView) // 用安全调用+let处理可空对象 myWebView?.let { webView -> webView.webViewClient = myWebClient() // 使用自定义的WebViewClient webView.loadUrl("https://app.sloths.one") val webSettings = webView.settings webSettings.javaScriptEnabled = true } } // 改成inner class才能访问Activity上下文 inner class myWebClient : WebViewClient() { override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) } override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { view.loadUrl(url) return true } } override fun onBackPressed() { myWebView?.let { if (it.canGoBack()) { it.goBack() } else { super.onBackPressed() } } ?: super.onBackPressed() } }
方案二:改用Compose实现WebView
如果想继续用Compose,移除XML布局,用AndroidView包裹WebView:
package com.sloth.hub import android.graphics.Bitmap import android.webkit.WebView import android.webkit.WebViewClient import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView import com.sloth.hub.ui.theme.SlothHubTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { SlothHubTheme { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { WebViewScreen() } } } } } @Composable fun WebViewScreen() { AndroidView(modifier = Modifier.fillMaxSize(), factory = { context -> WebView(context).apply { webViewClient = object : WebViewClient() { override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) } override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { view.loadUrl(url) return true } } loadUrl("https://app.sloths.one") settings.javaScriptEnabled = true } }) }
4. 生成签名应用包
编译错误修复后,按正常流程生成即可:
- 点击Android Studio菜单栏
Build > Generate Signed Bundle / APK - 选择
App Bundle(推荐)或APK,跟着向导完成密钥库配置即可。
内容的提问来源于stack exchange,提问作者David Griffin
相关产品推荐
相关产品推荐

