真的应该弃用`shouldOverrideUrlLoading`吗?我可以用什么代替呢?


138

真的不建议使用“ shouldOverrideUrlLoading”吗?如果是这样,我该怎么用呢?

似乎shouldOverrideUrlLoading已淘汰了针对Android N的应用程序,并且自API 19起直到现在为止最新的Android N(测试版),我都需要使应用程序正常工作,我使用了Android N中的一些新功能(例如Data Saver),因此定位棉花糖将无法解决该问题,因为我需要使用这些新功能,这是我使用的代码的一部分:

public boolean shouldOverrideUrlLoading(WebView webview, String url) {
    if (url.startsWith("http:") || url.startsWith("https:")) {
        ...
    } else if (url.startsWith("sms:")) {
        ...
    }
    ...
}

这是Android Studio给我的消息:

覆盖'android.webkit.WebViewClient'中不推荐使用的方法此检查报告在指定检查范围中使用不推荐使用的代码的情况。

谷歌对此不提任何说法

我想知道@SuppressWarnings("deprecation")从API 19开始直到最新的Android N Beta(以及发布时的最终版本),使用后是否可以让我在所有设备上工作,我无法自己对其进行测试,我从未使用过,我需要确保它有效,所以,任何人都可以告诉吗?


1
该回调方法有两种版本。旧的已弃用。在这种情况下,“已弃用”表示“嘿,如果您适合我们,我们可能还要尝试其他方法”。旧的回调应该继续起作用,因为N之前的Android版本需要旧的回调。
CommonsWare,2016年

首先,感谢您的评论,我使用的版本很不错,因为它与Android Developer Docs完全相同,除了字符串名称,他们使用的是“ view”,而我使用的是“ webview” ,其余部分相同,那么为什么要使它在所有版本上都起作用?
奴才2016年

Answers:


95

我使用的版本不错,因为它与Android Developer Docs完全相同,除了字符串的名称,它们使用的是“ view”,而我使用的是“ webview”,其余的都相同

不它不是。

N Developer Preview的新功能具有以下方法签名:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

所有Android版本(包括N)都支持的方法具有以下方法签名:

public boolean shouldOverrideUrlLoading(WebView view, String url)

那么,为什么要使它在所有版本上都起作用?

覆盖已弃用String的参数,将a 作为第二个参数。


您好,感谢您的回答,自API 19以来仍然不兼容,因为要获取URL字符串,我必须使用“ url.getUrl()。toString()”,并且已将其添加到API 21中,自API 19起有效吗?
奴才2016年

3
@Minion:“自API 19以来仍然不兼容” –是的。“因为要获取URL字符串,我必须使用“ url.getUrl()。toString()””-否,URL作为第二个参数以形式提供String。例如,此示例应用程序,针对API级别19编译,能正常工作,如在Android 6.0供电的Nexus 5.
CommonsWare

您好,使用“ WebResourceRequest请求”没有String参数
Minion

2
@Minion:正确。这仅适用于Android N(可能更高)。您问“为什么要使它在所有版本上都能工作?”。我告诉您覆盖已弃用String的参数,该参数以a 作为第二个参数。例如,样品应用程序,我的联系,它覆盖弃用回调,工作在一个的Nexus 6细运行的N个开发人员预览1
CommonsWare

6
如果您想适应未来的需求,则可以覆盖两种方法。这样,您的应用将继续在<21上运行,但是一旦它们完全弃用了旧方法,您就可以开始使用。而你将不必担心getUrl(),因为新的方法将只要求24+
尤瓦

187

为将来的读者详细记录:

简短的答案是您需要覆盖这两种方法。该shouldOverrideUrlLoading(WebView view, String url)方法已在API 24中弃用,并且已在API 24 shouldOverrideUrlLoading(WebView view, WebResourceRequest request)中添加了该方法。如果您要定位的是旧版android,则需要前一种方法,并且如果要定位到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方法。


6
@ webo80实际上它在API24 / N被添加 developer.android.com/reference/android/webkit/...
亨利

3
最好@RequiresApi在这里使用
@TargetApi

1
与覆盖这两种方法的问题,至少shouldInterceptRequest,是在Android N +器件中,它们被调用,你会被两次处理每个URI!为了解决这个问题,我Build.VERSION.SDK_INT < Build.VERSION_CODES.N在不推荐使用的版本中添加了一个条件。
尼克1998年

8
@JohnLee通常只调用其中一种方法。但是,如果要super. shouldOverrideUrlLoading(view,request)使用未弃用的方法,则是的,将同时调用未弃用的方法和已弃用的方法。这是因为未弃用的方法的默认实现是在内部调用已弃用的方法。只是看看WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request)。因此,请确保您不打电话super.shouldOverrideUrlLoading()
亨利

1
只是指出没有同时记录两种方法的功能。我不会一直这样,因为在文档中没有提到它。
奥斯汀·马奥尼

15

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}

2
它是view.loadUrl(request.getUrl()。toString());
Hibbem

它的工作,但如果我们使用回来,它将关闭该应用程序
MRRaja

4
这将不支持少于21的api
mumair '17

-1

实施不推荐使用和不推荐使用的方法,如下所示。第一个是处理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
        }
}

1
这似乎是亨利的回答的部分副本,但这个废弃的返回值的Uri.parseparseUri。新的答案应为该主题添加有用的新信息和新见解。
AdrianHHH

因为api仅在API 24而非21上弃用,所以让我浪费了时间
Gustavo Baiocchi Costa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.