`shouldOverrideUrlLoading` 真的被弃用了吗?我可以用啥代替?
Posted
技术标签:
【中文标题】`shouldOverrideUrlLoading` 真的被弃用了吗?我可以用啥代替?【英文标题】:Is `shouldOverrideUrlLoading` really deprecated? What can I use instead?`shouldOverrideUrlLoading` 真的被弃用了吗?我可以用什么代替? 【发布时间】:2016-07-28 19:13:05 【问题描述】:“shouldOverrideUrlLoading”真的被弃用了吗?如果是这样,我可以用什么代替?
似乎shouldOverrideUrlLoading
已弃用针对 Android N,我需要让应用程序从 API 19 开始工作,直到现在最新的 android N(测试版),我使用了一些功能是 Android N 中的新功能(如 Data Saver),因此定位 Marshmallow 对解决问题没有帮助,因为我需要使用这些新功能,这是我使用的代码部分:
public boolean shouldOverrideUrlLoading(WebView webview, String url)
if (url.startsWith("http:") || url.startsWith("https:"))
...
else if (url.startsWith("sms:"))
...
...
这是 Android Studio 给我的信息:
覆盖“android.webkit.WebViewClient”中已弃用的方法 此检查报告在指定检查范围内使用了已弃用代码的情况。
Google says nothing about that deprecation.
我想知道使用@SuppressWarnings("deprecation")
是否可以让我在从 API 19 到最新的 Android N Beta(及其发布时的最终版本)的所有设备上工作,我自己无法测试它,我从未使用过而且我需要确保它有效,所以,任何人都可以说出来吗?
【问题讨论】:
该回调方法有两个版本。旧的已弃用。在这种情况下,“不推荐使用”的意思是“嘿,如果适合你,我们还有一些你可能想尝试的东西”。旧回调应该会继续工作,因为旧的回调是前 N 版本的 Android 所必需的。 首先,感谢您的评论,我使用的版本我认为是好的版本,因为与Android开发者文档完全相同,除了字符串的名称,他们使用“ view”,我用的是“webview”,其余的都是一样的,那我为什么要让它在所有版本上都能正常工作呢? 【参考方案1】:我认为我使用的版本很好,因为它与 Android 开发者文档完全相同,除了字符串的名称,他们使用“view”,我使用“webview”,其余的是一样的
不,不是。
N 开发者预览版的新功能有这个方法签名:
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
包括N在内的所有Android版本都支持的那个有这个方法签名:
public boolean shouldOverrideUrlLoading(WebView view, String url)
那我为什么要让它在所有版本上都能正常工作呢?
覆盖已弃用的那个,即采用String
作为第二个参数的那个。
【讨论】:
您好,感谢您的回答,自 API 19 以来仍然不兼容,因为要获取 URL 字符串,我必须使用“url.getUrl().toString()”并且它已被添加在 API 21 上,从 API 19 开始有什么方法可以让它工作? @Minion:“自 API 19 以来仍然不兼容”——是的,是的。 “因为要获取 URL 字符串,我必须使用“url.getUrl().toString()””——不,URL 是作为第二个参数提供的,以String
的形式提供。例如,this sample app,针对 API 级别 19 编译,可以正常工作,例如在基于 Android 6.0 的 Nexus 5 上。
您好,使用“WebResourceRequest 请求”没有String参数
@Minion:正确。这仅适用于 Android N(并且可能更高)。您问“那我为什么要让它适用于所有版本?”。我告诉过您要覆盖已弃用的那个,即以String
作为第二个参数的那个。例如,我链接到的示例应用程序覆盖了已弃用的回调,在运行 N Developer Preview 1 的 Nexus 6 上运行良好。
如果您想要面向未来,您实际上可以覆盖这两种方法。这样,您的应用程序将继续在 getUrl(),因为新方法只会在 24+ 时被调用【参考方案2】:
使用
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
return shouldOverrideUrlLoading(view, request.getUrl().toString());
【讨论】:
是 view.loadUrl(request.getUrl().toString()); 它的工作,但如果我们使用回来,那么它会关闭应用程序 不支持小于 21 的 api【参考方案3】:为未来的读者详细记录:
简短的回答是您需要覆盖这两种方法。 shouldOverrideUrlLoading(WebView view, String url)
方法在 API 24 中已弃用,shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
方法在 API 24 中添加。如果您针对的是旧版本的 android,则需要前一种方法,如果您的目标是 24 (或者稍后,如果有人在遥远的将来阅读此内容)建议也覆盖后一种方法。
以下是您将如何完成此任务的框架:
class CustomWebViewClient extends WebViewClient
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
final Uri uri = Uri.parse(url);
return handleUri(uri);
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
final Uri uri = request.getUrl();
return handleUri(uri);
private boolean handleUri(final Uri uri)
Log.i(TAG, "Uri =" + uri);
final String host = uri.getHost();
final String scheme = uri.getScheme();
// Based on some condition you need to determine if you are going to load the url
// in your web view itself or in a browser.
// You can use `host` or `scheme` or any part of the `uri` to decide.
if (/* any condition */)
// Returning false means that you are going to load this url in the webView itself
return false;
else
// Returning true means that you need to handle what to do with the url
// e.g. open web page in a Browser
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
return true;
就像shouldOverrideUrlLoading
一样,您可以为shouldInterceptRequest
方法想出类似的方法。
【讨论】:
这里最好使用@RequiresApi
而不是@TargetApi以备将来使用
覆盖这两种方法的问题,至少在shouldInterceptRequest
中,是在Android N+ 设备上,它们被both 调用,你将处理每个uri 两次!为了解决这个问题,我在已弃用的版本中添加了 Build.VERSION.SDK_INT < Build.VERSION_CODES.N
条件。
@JohnLee 通常只会调用其中一种方法。但是,如果您将super. shouldOverrideUrlLoading(view,request)
放在非弃用方法中,那么是的,非弃用方法和弃用方法都将被调用。这是因为非弃用方法的默认实现是在内部调用弃用方法。看看WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
。所以请确保你不要打电话给super.shouldOverrideUrlLoading()
。
@AustynMahoney 我没有说我们必须依赖内部实现。上面的答案不依赖于内部实现。我引用它来解释为什么有时会在最新的 API 版本中调用已弃用和未弃用的方法。目标是覆盖这两种方法并确保仅调用其中一种。如果造成任何误解,我很抱歉
为了加入讨论,我已经尝试过 Pie 上的代码,并且只调用了其中一种方法。【参考方案4】:
同时实现已弃用和未弃用的方法,如下所示。第一个是处理 API 级别 21 及更高,第二个是处理低于 API 级别 21
webViewClient = object : WebViewClient()
.
.
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean
parseUri(request?.url)
return true
@SuppressWarnings("deprecation")
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean
parseUri(Uri.parse(url))
return true
【讨论】:
这似乎是亨利答案的部分副本,但这会丢弃Uri.parse
和 parseUri
返回的值。新答案应该为主题添加有用的新信息和新见解。
让我浪费时间,因为 api 仅在 API 24 而不是 21 上被弃用以上是关于`shouldOverrideUrlLoading` 真的被弃用了吗?我可以用啥代替?的主要内容,如果未能解决你的问题,请参考以下文章
WebView shouldOverrideUrlLoading功能
shouldOverrideUrlLoading 仅在某些网页上被调用
android webview中shouldOverrideUrlLoading方法的返回值问题
错误消息-> shouldOverrideUrlLoading Webview Android
如果在超时回调中修改了“window.location.href”,则 shouldOverrideUrlLoading(...) 不会执行