Apakah `shouldOverrideUrlLoading` benar-benar tidak digunakan lagi? Apa yang bisa saya gunakan?

146

Apakah "shouldOverrideUrlLoading" benar-benar tidak digunakan lagi? Jika ya, apa yang bisa saya gunakan?

Sepertinya shouldOverrideUrlLoadingsudah usang menargetkan Android N dan saya perlu membuat aplikasi berfungsi sejak API 19 hingga yang terbaru sekarang yaitu Android N (beta), saya menggunakan beberapa fitur yang baru di Android N (seperti Penghemat Data), jadi menargetkan Marshmallow tidak akan membantu mengatasi masalah ini karena saya perlu menggunakan fitur-fitur baru tersebut, berikut adalah bagian dari kode yang saya gunakan:

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

Dan inilah pesan yang diberikan Android Studio kepada saya:

Mengganti metode yang tidak digunakan lagi di 'android.webkit.WebViewClient' Pemeriksaan ini melaporkan di mana kode yang tidak berlaku lagi digunakan dalam cakupan inspeksi yang ditentukan.

Google tidak mengatakan apa-apa tentang penghentian itu .

Saya ingin tahu apakah menggunakan @SuppressWarnings("deprecation")akan memungkinkan saya bekerja di semua perangkat sejak API 19 hingga Android N Beta terbaru (dan versi finalnya saat dirilis), saya tidak dapat mengujinya sendiri, saya tidak pernah menggunakannya dan saya perlu memastikan bahwa itu berhasil, jadi, ada yang tahu?

Antek
sumber
2
Ada dua versi metode panggilan balik itu. Yang lama sudah tidak digunakan lagi. Dalam hal ini, "deprecated" berarti "hei, kami memiliki hal lain yang mungkin ingin Anda coba, jika sesuai untuk Anda". Callback lama akan terus berfungsi, karena callback lama diperlukan untuk Android versi pra-N.
CommonsWare
Pertama, terima kasih atas komentarnya, versi yang saya gunakan menurut saya bagus, karena sama persis dengan Android Developer Docs, kecuali untuk nama stringnya, mereka menggunakan "view" dan saya menggunakan "webview" , karena sisanya sama, jadi mengapa saya harus melakukannya untuk membuatnya berfungsi di semua versi?
Minion

Jawaban:

97

Versi yang saya gunakan menurut saya bagus, karena sama persis dengan Android Developer Docs, kecuali untuk nama stringnya, mereka menggunakan "view" dan saya menggunakan "webview", selebihnya sama

Tidak, bukan.

Yang baru di Pratinjau Pengembang N memiliki tanda tangan metode ini:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

Salah satu yang didukung oleh semua versi Android, termasuk N, memiliki tanda tangan metode ini:

public boolean shouldOverrideUrlLoading(WebView view, String url)

Jadi mengapa saya harus melakukannya untuk membuatnya berfungsi di semua versi?

Ganti yang tidak digunakan lagi, yang menggunakan a Stringsebagai parameter kedua.

CommonsWare
sumber
Halo, dan terima kasih atas jawabannya, yang masih belum kompatibel sejak API 19, karena untuk mendapatkan string URL saya harus menggunakan "url.getUrl (). ToString ()" dan telah ditambahkan di API 21, cara apa pun untuk membuatnya itu berfungsi sejak API 19?
Minion
3
@ Minion: "yang masih belum kompatibel sejak API 19" - ya, memang begitu. "karena untuk mendapatkan string URL saya harus menggunakan" url.getUrl (). toString () "" - tidak, URL disediakan sebagai parameter kedua, dalam bentuk a String. Misalnya, aplikasi contoh ini , yang dikompilasi berdasarkan API Level 19, berfungsi dengan baik, seperti pada Nexus 5 yang didukung Android 6.0
CommonsWare
Halo, menggunakan "permintaan WebResourceRequest" tidak memiliki parameter String
Minion
2
@Minion: Benar. Itu hanya berfungsi di Android N (dan, mungkin, lebih tinggi). Anda bertanya "jadi mengapa saya harus melakukannya untuk membuatnya berfungsi di semua versi?". Saya mengatakan kepada Anda untuk menimpa yang sudah usang, yang mengambil a Stringsebagai parameter kedua. Misalnya, aplikasi sampel yang saya tautkan, yang menimpa callback yang tidak digunakan lagi, berfungsi dengan baik pada Nexus 6 yang menjalankan N Developer Preview 1.
CommonsWare
6
Jika Anda ingin menjadi bukti masa depan, Anda sebenarnya bisa mengganti metode KEDUA. Dengan begitu, aplikasi Anda akan terus berfungsi pada <21, tetapi Anda akan siap untuk melanjutkan setelah mereka sepenuhnya menghentikan metode lama. Dan Anda tidak perlu khawatir getUrl()karena metode baru hanya akan dipanggil untuk 24+
yuval
193

Mendokumentasikan secara detail untuk pembaca selanjutnya:

Jawaban singkatnya adalah Anda perlu mengganti kedua metode tersebut. The shouldOverrideUrlLoading(WebView view, String url)Metode ini usang dalam API 24 dan shouldOverrideUrlLoading(WebView view, WebResourceRequest request)metode ditambahkan dalam API 24. Jika Anda menargetkan versi android, Anda perlu metode mantan, dan jika Anda menargetkan 24 (atau lambat, jika seseorang membaca ini di masa depan yang jauh) disarankan untuk mengganti metode terakhir juga.

Di bawah ini adalah kerangka tentang bagaimana Anda akan mencapai ini:

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

Sama seperti shouldOverrideUrlLoading, Anda dapat menemukan pendekatan serupa untuk shouldInterceptRequestmetode.

Henry
sumber
6
@ webo80 Sebenarnya itu ditambahkan dalam API24 / N developer.android.com/reference/android/webkit/...
Henry
3
Lebih baik digunakan @RequiresApisebagai ganti @TargetApi di sini untuk penggunaan di masa mendatang
Hibbem
1
Masalah dengan menimpa kedua metode, setidaknya dengan shouldInterceptRequest, adalah bahwa pada perangkat Android N + keduanya dipanggil dan Anda akan menangani setiap uri dua kali! Untuk memperbaikinya, saya menambahkan Build.VERSION.SDK_INT < Build.VERSION_CODES.Nketentuan di versi yang tidak digunakan lagi.
Jonik
9
@JohnLee Biasanya hanya satu metode yang akan dipanggil. Tetapi jika Anda menggunakan super. shouldOverrideUrlLoading(view,request)metode non-deprecated, maka ya metode non-deprecated dan deprecated akan dipanggil. Ini karena implementasi default dari metode yang tidak digunakan lagi adalah untuk secara internal memanggil metode yang tidak digunakan lagi. Lihat saja WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request). Jadi, pastikan Anda tidak menelepon super.shouldOverrideUrlLoading().
Henry
1
Hanya menunjukkan bahwa fungsionalitas dari kedua metode yang dipanggil tidak didokumentasikan. Saya tidak akan mengandalkan itu selalu menjadi kasus karena tidak disebutkan dalam dokumentasi.
Austyn Mahoney
16

Menggunakan

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
Saleem Kalro
sumber
2
itu view.loadUrl (request.getUrl (). toString ());
Hibbem
ini berfungsi tetapi jika kami menggunakan kembali maka itu akan menutup aplikasi
MRRaja
4
ini tidak akan mendukung api kurang dari 21
mumair
-1

Terapkan metode yang tidak digunakan lagi dan yang tidak digunakan lagi seperti di bawah ini. Yang pertama adalah menangani API level 21 dan yang lebih tinggi, yang kedua adalah menangani lebih rendah dari API level 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
        }
}
emre
sumber
1
Ini tampaknya merupakan salinan sebagian dari jawaban Henry, tetapi ini membuang nilai yang dikembalikan oleh Uri.parsedan parseUri. Jawaban baru harus menambah informasi baru yang berguna dan wawasan baru ke dalam topik.
AdrianHHH
Membuat saya kehilangan waktu karena api hanya dihentikan pada API 24 dan bukan 21
Gustavo Baiocchi Costa