`ShouldOverrideUrlLoading` è davvero deprecato? Cosa posso usare invece?


138

"ShouldOverrideUrlLoading" è davvero deprecato? In tal caso, cosa posso usare invece?

Sembra che shouldOverrideUrlLoadingsia obsoleto il targeting per Android N e devo far funzionare un'app dall'API 19 fino all'ultimo in questo momento che è Android N (beta), utilizzo alcune funzionalità che sono nuove in Android N (come Risparmio dati), quindi il targeting Marshmallow non aiuterà con il problema poiché ho bisogno di usare quelle nuove funzionalità, ecco la parte del codice che uso:

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

E questo è il messaggio che Android Studio mi ha dato:

Sovrascrive il metodo obsoleto in "android.webkit.WebViewClient" Questa ispezione indica dove viene utilizzato il codice obsoleto nell'ambito di ispezione specificato.

Google non dice nulla di tale deprecazione .

Mi chiedo se l'utilizzo @SuppressWarnings("deprecation")mi consentirà di funzionare su tutti i dispositivi dall'API 19 fino all'ultima versione di Android N Beta (e la sua versione finale quando viene rilasciato), non posso provarlo da solo, non l'ho mai usato e devo essere sicuro che funziona, quindi, chiunque può dirlo?


1
Esistono due versioni di quel metodo di callback. Quello vecchio è deprecato. In questo caso, "deprecato" significa "ehi, abbiamo qualcos'altro che potresti voler provare, se è appropriato per te". Il vecchio callback dovrebbe continuare a funzionare, poiché il vecchio callback è richiesto per le versioni pre-N di Android.
Commons War

Innanzitutto, grazie per il commento, penso che la versione che sto usando sia quella giusta, dato che è esattamente la stessa dei Documenti per sviluppatori Android, ad eccezione del nome della stringa, hanno usato "view" e ho usato "webview" , per il resto è lo stesso, quindi perché dovrei farlo per farlo funzionare su tutte le versioni?
Minion

Risposte:


95

Penso che la versione che sto usando sia quella giusta, dato che è esattamente la stessa dei Documenti per sviluppatori Android, ad eccezione del nome della stringa, hanno usato "view" e io ho usato "webview", per il resto è lo stesso

No non lo è.

Quello che è nuovo in N Developer Preview ha questa firma del metodo:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

Quello supportato da tutte le versioni di Android, incluso N, ha questa firma del metodo:

public boolean shouldOverrideUrlLoading(WebView view, String url)

Quindi perché dovrei farlo per farlo funzionare su tutte le versioni?

Sostituisci quello deprecato, quello che accetta a Stringcome secondo parametro.


Ciao, e grazie per la risposta, che non è ancora compatibile dall'API 19, perché per ottenere la stringa URL devo usare "url.getUrl (). ToString ()" ed è stato aggiunto su API 21, comunque funziona dall'API 19?
Minion

3
@Minion: "che non è ancora compatibile dall'API 19" - sì, lo è. "perché per ottenere la stringa URL devo usare" url.getUrl (). toString () "" - no, l'URL viene fornito come secondo parametro, sotto forma di a String. Ad esempio, questa app di esempio , compilata in base al livello API 19, funziona benissimo, come su un Nexus 5. basato su Android 6.0
CommonsWare

Ciao, l'uso della "richiesta WebResourceRequest" non ha un parametro String
Minion

2
@Minion: corretto. Funziona solo su Android N (e, presumibilmente, più in alto). Hai chiesto "quindi perché dovrei farlo per farlo funzionare su tutte le versioni?". Ti ho detto di sovrascrivere quello deprecato, quello che prende a Stringcome secondo parametro. Ad esempio, l'app di esempio a cui ho collegato, che sovrascrive il callback deprecato, funziona perfettamente su un Nexus 6 con N Developer Preview 1.
CommonsWare

6
Se vuoi essere a prova di futuro, potresti effettivamente scavalcare ENTRAMBI i metodi. In questo modo la tua app continuerà a funzionare su <21, ma sarai pronto per andare dopo che avranno completamente deprecato il vecchio metodo. E non dovrai preoccuparti getUrl()perché il nuovo metodo verrà chiamato solo per 24+
yuval

187

Documentare in dettaglio per i futuri lettori:

La risposta breve è che è necessario sovrascrivere entrambi i metodi. Il shouldOverrideUrlLoading(WebView view, String url)metodo è deprecato in API 24 e il shouldOverrideUrlLoading(WebView view, WebResourceRequest request)metodo è aggiunto in API 24. Se stai prendendo di mira le versioni precedenti di Android, hai bisogno del metodo precedente e se stai prendendo di mira il 24 (o più tardi, se qualcuno lo sta leggendo in un futuro lontano) è consigliabile sostituire anche quest'ultimo metodo.

Di seguito è riportato lo scheletro su come realizzare questo:

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

Proprio come shouldOverrideUrlLoading, puoi trovare un approccio simile per il shouldInterceptRequestmetodo.


6
@ webo80 In realtà è aggiunto in API24 / N developer.android.com/reference/android/webkit/…
Henry

3
È meglio usare @RequiresApial posto di @TargetApi qui per un uso futuro
Hibbem,

1
Il problema con l'override di entrambi i metodi, almeno con shouldInterceptRequest, è che sui dispositivi Android N + sono entrambi richiamati e gestirai ogni uri due volte! Per rimediare, ho aggiunto una Build.VERSION.SDK_INT < Build.VERSION_CODES.Ncondizione nella versione obsoleta.
Jonik,

8
@JohnLee Normalmente verrà invocato solo uno dei metodi. Ma se dovessi inserire super. shouldOverrideUrlLoading(view,request)il metodo non deprecato, allora verranno invocati sia il metodo non deprecato che il metodo deprecato. Questo perché l'implementazione predefinita del metodo non deprecato è di invocare internamente il metodo deprecato. Dai un'occhiata a WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request). Quindi assicurati di non chiamare super.shouldOverrideUrlLoading().
Henry,

1
Basta sottolineare che la funzionalità di avere entrambi i metodi chiamati non è documentata. Non farei affidamento sul fatto che sia sempre il caso poiché non è menzionato nella documentazione.
Austyn Mahoney,

15

Uso

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

2
è view.loadUrl (request.getUrl (). toString ());
Hibbem,

funziona ma se riusciamo a usarlo, chiuderà l'app
MRRaja,

4
questo non supporterebbe api meno di 21
mumair

-1

Implementare metodi deprecati e non deprecati come di seguito. Il primo è gestire il livello API 21 e superiore, il secondo è gestire il livello API 21 inferiore

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
Questa sembra essere una copia parziale della risposta di Henry, ma questo scarta il valore restituito da Uri.parsee parseUri. Nuove risposte dovrebbero aggiungere utili nuove informazioni e nuove intuizioni sull'argomento.
AdrianHHH,

Mi ha fatto perdere tempo poiché api è deprecato solo su API 24 e non 21
Gustavo Baiocchi Costa
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.