Là `nênOverrideUrlLoading` thực sự không dùng nữa? Tôi có thể sử dụng cái gì thay thế?


138

"NênOverrideUrlLoading" có thực sự không dùng nữa không? Nếu vậy, tôi có thể sử dụng những gì thay thế?

Có vẻ như shouldOverrideUrlLoadingkhông được nhắm mục tiêu vào Android N và tôi cần làm cho ứng dụng hoạt động kể từ API 19 cho đến phiên bản mới nhất là Android N (beta), tôi sử dụng một số tính năng mới trong Android N (như Data Saver), vì vậy, nhắm mục tiêu Marshmallow sẽ không giúp đỡ vấn đề này vì tôi cần sử dụng các tính năng mới đó, đây là một phần của mã tôi sử dụng:

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

Và đây là thông điệp mà Android Studio đưa ra cho tôi:

Ghi đè phương thức không dùng nữa trong 'android.webkit.WebViewClient' Kiểm tra này báo cáo trong đó mã không dùng nữa được sử dụng trong phạm vi kiểm tra được chỉ định.

Google không nói gì về sự phản đối đó .

Tôi tự hỏi nếu sử dụng @SuppressWarnings("deprecation")sẽ cho phép tôi làm việc trên tất cả các thiết bị kể từ API 19 cho đến Android N Beta mới nhất (và phiên bản cuối cùng của nó khi được phát hành), tôi không thể tự kiểm tra, tôi không bao giờ sử dụng nó và tôi cần chắc chắn Nó hoạt động, vì vậy, bất cứ ai có thể nói?


1
Có hai phiên bản của phương thức gọi lại đó. Cái cũ bị phản đối. Trong trường hợp này, "không dùng nữa" có nghĩa là "này, chúng tôi có một thứ khác mà bạn có thể muốn thử, nếu nó phù hợp với bạn". Cuộc gọi lại cũ sẽ tiếp tục hoạt động, vì cuộc gọi lại cũ là bắt buộc đối với các phiên bản tiền N của Android.
CommonsWare

Đầu tiên, cảm ơn vì nhận xét, phiên bản tôi đang sử dụng tôi nghĩ là phiên bản tốt, vì nó giống hệt với Tài liệu dành cho nhà phát triển Android, ngoại trừ tên của chuỗi, họ đã sử dụng "view" và tôi đã sử dụng "webview" , đối với phần còn lại là như nhau, vậy tại sao tôi phải làm để làm cho nó hoạt động trên tất cả các phiên bản?
Minion

Câu trả lời:


95

Phiên bản tôi đang sử dụng Tôi nghĩ là phiên bản tốt, vì giống hệt như Tài liệu dành cho nhà phát triển Android, ngoại trừ tên của chuỗi, họ đã sử dụng "view" và tôi đã sử dụng "webview", phần còn lại là như nhau

Không có nó không phải là.

Phiên bản mới của N Developer Preview có chữ ký phương thức này:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

Phiên bản được hỗ trợ bởi tất cả các phiên bản Android, bao gồm N, có chữ ký phương thức này:

public boolean shouldOverrideUrlLoading(WebView view, String url)

Vậy tại sao tôi phải làm để làm cho nó hoạt động trên tất cả các phiên bản?

Ghi đè tham số không dùng nữa, Stringtham số lấy tham số thứ hai.


Xin chào, và cảm ơn vì câu trả lời, vẫn không tương thích kể từ API 19, vì để có được chuỗi URL, tôi phải sử dụng "url.getUrl (). ToString ()" và nó đã được thêm vào API 21, bằng mọi cách để thực hiện Nó hoạt động kể từ API 19?
Minion

3
@Minion: "vẫn chưa tương thích kể từ API 19" - đúng vậy. "bởi vì để có được chuỗi URL, tôi phải sử dụng" url.getUrl (). toString () "" - không, URL được cung cấp dưới dạng tham số thứ hai, dưới dạng a String. Ví dụ: ứng dụng mẫu này , được biên dịch dựa trên API cấp 19, hoạt động tốt, chẳng hạn như trên Nexus 5. được hỗ trợ Android 6.0
CommonsWare

Xin chào, sử dụng "Yêu cầu WebResourceRequest" không có tham số Chuỗi
Minion

2
@Minion: Đúng. Điều đó chỉ hoạt động trên Android N (và, có lẽ, cao hơn). Bạn hỏi "vậy tại sao tôi phải làm để nó hoạt động trên tất cả các phiên bản?". Tôi đã nói với bạn để ghi đè lên cái không dùng nữa, cái lấy Stringtham số thứ hai. Ví dụ: ứng dụng mẫu mà tôi đã liên kết, ghi đè cuộc gọi lại không dùng nữa, hoạt động tốt trên Nexus 6 chạy N Preview Preview 1.
CommonsWare

6
Nếu bạn muốn là bằng chứng trong tương lai, bạn thực sự có thể ghi đè các phương thức BÓNG. Bằng cách đó, ứng dụng của bạn sẽ tiếp tục hoạt động vào <21, nhưng bạn sẽ sẵn sàng sử dụng một khi chúng hoàn toàn không dùng phương thức cũ. Và bạn sẽ không phải lo lắng getUrl()vì phương thức mới sẽ chỉ được gọi cho 24+
yuval

187

Tài liệu chi tiết cho độc giả tương lai:

Câu trả lời ngắn gọn là bạn cần ghi đè cả hai phương thức. Các shouldOverrideUrlLoading(WebView view, String url)phương pháp được tán thành trong API 24 và các shouldOverrideUrlLoading(WebView view, WebResourceRequest request)phương pháp được thêm vào trong API 24. Nếu bạn đang nhắm mục tiêu các phiên bản cũ của Android, bạn cần phương pháp cũ, và nếu bạn đang nhắm mục tiêu 24 (hoặc mới hơn, nếu ai đó đang đọc bài viết này trong tương lai xa) bạn cũng nên ghi đè phương thức sau.

Dưới đây là bộ xương về cách bạn sẽ thực hiện điều này:

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;
        }
    }
}

Giống như shouldOverrideUrlLoading, bạn có thể đưa ra một cách tiếp cận tương tự cho shouldInterceptRequestphương pháp.


6
@ webo80 Trên thực tế, nó được thêm vào trong API24 / N developer.android.com/reference/android/webkit/
Henry

3
Tốt hơn là nên sử dụng @RequiresApithay cho @TargetApi tại đây để sử dụng trong tương lai
Hibbem

1
Vấn đề với việc ghi đè cả hai phương thức, ít nhất là với shouldInterceptRequest, trên các thiết bị Android N +, cả hai đều được gọi và bạn sẽ xử lý mỗi uri hai lần! Để khắc phục điều đó, tôi đã thêm một Build.VERSION.SDK_INT < Build.VERSION_CODES.Nđiều kiện trong phiên bản không dùng nữa.
Jonik

8
@JohnLee Thông thường chỉ có một trong các phương thức sẽ được gọi. Nhưng nếu bạn đã đưa super. shouldOverrideUrlLoading(view,request)vào phương thức không được khấu hao, thì có, cả phương pháp không được khấu hao và phương pháp không dùng nữa sẽ được gọi. Điều này là do việc triển khai mặc định của phương thức không được dùng nữa là để gọi bên trong phương thức không dùng nữa. Chỉ cần nhìn vào WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request). Vì vậy, hãy chắc chắn rằng bạn không gọi super.shouldOverrideUrlLoading().
Henry

1
Chỉ cần chỉ ra rằng chức năng của cả hai phương thức được gọi là không được ghi lại. Tôi sẽ không dựa vào điều đó luôn luôn như vậy vì nó không được đề cập trong tài liệu.
Austyn Mahoney

15

Sử dụng

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

2
đó là view.loadUrl (request.getUrl (). toString ());
Hibbem

nó hoạt động nhưng nếu chúng tôi sử dụng trở lại thì nó sẽ đóng ứng dụng
MRRaja

4
điều này sẽ không hỗ trợ api dưới 21
mumair 15/03/2017

-1

Thực hiện cả hai phương pháp không dùng nữa và không dùng nữa như dưới đây. Thứ nhất là xử lý API cấp 21 trở lên, cấp hai xử lý thấp hơn API cấp 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
Đây dường như là một bản sao một phần câu trả lời của Henry, nhưng điều này loại bỏ giá trị được trả về bởi Uri.parseparseUri. Câu trả lời mới nên thêm thông tin mới hữu ích và hiểu biết mới về chủ đề.
AdrianHHH

Làm tôi mất thời gian vì api chỉ bị phản đối trên API 24 chứ không phải 21
Gustavo Baiocchi Costa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.