`shouldOverrideUrlLoading`真的被弃用了吗?我可以用什么呢?

Min*_*ion 121 android deprecated webview android-webview deprecation-warning

"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:")) {
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是Android Studio给我的消息:

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

谷歌没有说这种弃用.

我想知道是否使用@SuppressWarnings("deprecation")将让我在API 19上工作直到最新的Android N Beta(及其发布时的最终版本),我无法自己测试,我从未使用过,我需要确定它有效,所以,任何人都能说出来?

Hen*_*nry 175

为未来的读者详细记录:

简短的回答是你需要覆盖这两种方法.该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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

就像shouldOverrideUrlLoading,您可以为shouldInterceptRequest方法提出类似的方法.

  • @JohnLee通常只会调用其中一个方法.但如果你要把'超级.在非弃用方法中,shouldOverrideUrlLoading(view,request)`,然后是,将调用未弃用和不推荐使用的方法.这是因为非弃用方法的默认实现是在内部调用已弃用的方法.只需看看`WebViewClient.shouldOverrideUrlLoading(WebView视图,WebResourceRequest请求)`.因此,请确保不要调用`super.shouldOverrideUrlLoading()`. (8认同)
  • @ webo80实际上它是在API24/N中添加的https://developer.android.com/reference/android/webkit/WebViewClient.html#shouldOverrideUrlLoading(android.webkit.WebView,%20android.webkit.WebResourceRequest) (6认同)
  • 最好使用[`@ RequiresApi`](https://developer.android.com/reference/android/support/annotation/RequiresApi.html)代替@TargetApi,以备将来使用 (3认同)
  • 重写这两个方法(至少使用“shouldInterceptRequest”)的问题是,在 Android N+ 设备上,它们*都会*被调用,并且您将处理每个 uri 两次!为了解决这个问题,我在已弃用的版本中添加了“Build.VERSION.SDK_INT < Build.VERSION_CODES.N”条件。 (2认同)
  • 为了增加讨论,我在 Pie 上尝试了代码,但只调用了其中一种方法。 (2认同)

Com*_*are 83

我正在使用的版本是好的,因为它与Android Developer Docs完全相同,除了字符串的名称,他们使用"view"而我使用"webview",其余的是相同的

不它不是.

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

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
Run Code Online (Sandbox Code Playgroud)

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

public boolean shouldOverrideUrlLoading(WebView view, String url)
Run Code Online (Sandbox Code Playgroud)

那么我为什么要让它适用于所有版本呢?

覆盖不推荐的那个,将a String作为第二个参数.

  • 如果你想要面向未来,你实际上可以覆盖两种方法.这样你的应用程序将继续工作<21,但是一旦他们完全弃用旧方法,你就会准备好了.而且你不必担心`getUrl()`因为新方法只会被调用24+ (6认同)
  • @Minion:"自API 19以来仍然不兼容" - 是的,确实如此."因为要获取我必须使用的URL字符串"url.getUrl().toString()"" - 否,URL以"String"的形式作为第二个参数提供.例如,针对API级别19编译的[此示例应用程序](https://github.com/commonsguy/cw-omnibus/tree/master/WebKit/Browser4)工作正常,例如在基于Android 6.0的Nexus上运行5. (3认同)
  • @Minion:正确.这仅适用于Android N(可能更高).你问"所以我为什么要让它适用于所有版本?".我告诉你要覆盖不推荐使用的那个,它将一个`String`作为第二个参数.例如,我链接到的示例应用程序(覆盖已弃用的回调)在运行N Developer Preview 1的Nexus 6上运行正常. (2认同)

Sal*_*lro 13

使用

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会支持api少于21 (4认同)
  • 它是view.loadUrl(request.getUrl().toString()); (2认同)