«ShouldOverrideUrlLoading» est-il vraiment obsolète? Que puis-je utiliser à la place?

138

"ShouldOverrideUrlLoading" est-il vraiment obsolète? Si oui, que puis-je utiliser à la place?

Il semble que le ciblage d'Android NshouldOverrideUrlLoading soit obsolète et que je dois faire fonctionner une application depuis l'API 19 jusqu'à la dernière en ce moment qui est Android N (bêta), j'utilise certaines fonctionnalités qui sont nouvelles dans Android N (comme l'économiseur de données), donc le ciblage Marshmallow n'aidera pas à résoudre le problème car je dois utiliser ces nouvelles fonctionnalités, voici la partie du code que j'utilise:

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

Et voici le message que m'a donné Android Studio:

Remplace la méthode obsolète dans «android.webkit.WebViewClient» Cette inspection signale où du code obsolète est utilisé dans la portée d'inspection spécifiée.

Google ne dit rien de cette dépréciation .

Je me demande si l'utilisation @SuppressWarnings("deprecation")me permettra de travailler sur tous les appareils depuis l'API 19 jusqu'à la dernière version d'Android N Beta (et sa version finale lors de sa sortie), je ne peux pas le tester moi-même, je ne l'ai jamais utilisé et je dois être sûr que cela fonctionne, alors, tout le monde peut le dire?

Serviteur
la source
1
Il existe deux versions de cette méthode de rappel. L'ancien est obsolète. Dans ce cas, "obsolète" signifie "hé, nous avons autre chose que vous voudrez peut-être essayer, si cela vous convient". L'ancien rappel devrait continuer à fonctionner, car l'ancien rappel est requis pour les versions antérieures à N d'Android.
CommonsWare
Tout d'abord, merci pour le commentaire, je pense que la version que j'utilise est la bonne, car elle est exactement la même que la documentation pour les développeurs Android, sauf pour le nom de la chaîne, ils ont utilisé "vue" et j'ai utilisé "vue Web" , pour le reste, c'est pareil, alors pourquoi devrais-je faire pour que cela fonctionne sur toutes les versions?
Minion le

Réponses:

95

La version que j'utilise, je pense, est la bonne, car elle est exactement la même que celle de la documentation pour les développeurs Android, à l'exception du nom de la chaîne, ils ont utilisé "vue" et j'ai utilisé "vue Web", pour le reste, c'est pareil

Non, ça ne l'est pas.

Celui qui est nouveau dans N Developer Preview a cette signature de méthode:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

Celui qui est pris en charge par toutes les versions d'Android, y compris N, a cette signature de méthode:

public boolean shouldOverrideUrlLoading(WebView view, String url)

Alors, pourquoi devrais-je faire pour que cela fonctionne sur toutes les versions?

Remplacez celui qui est obsolète, celui qui prend a Stringcomme deuxième paramètre.

CommonsWare
la source
Bonjour, et merci pour la réponse, qui n'est toujours pas compatible depuis l'API 19, car pour obtenir la chaîne d'URL, je dois utiliser "url.getUrl (). ToString ()" et cela a été ajouté sur l'API 21, de toute façon ça marche depuis l'API 19?
Minion
3
@Minion: "qui n'est toujours pas compatible depuis l'API 19" - oui, ça l'est. "car pour obtenir la chaîne URL, je dois utiliser" url.getUrl (). toString () "" - non, l'URL est fournie comme deuxième paramètre, sous la forme d'un fichier String. Par exemple, cet exemple d'application , compilé avec le niveau d'API 19, fonctionne correctement, comme sur un Nexus 5 sous Android 6.0
CommonsWare
Bonjour, l'utilisation de la "requête WebResourceRequest" n'a pas de paramètre String
Minion
2
@Minion: C'est exact. Cela ne fonctionne que sur Android N (et, probablement, supérieur). Vous avez demandé "alors pourquoi devrais-je faire pour que cela fonctionne sur toutes les versions?". Je vous ai dit de remplacer celui obsolète, celui qui prend a Stringcomme deuxième paramètre. Par exemple, l'exemple d'application que j'ai lié à, qui remplace le rappel obsolète, fonctionne bien sur un Nexus 6 exécutant le N Developer Preview 1.
CommonsWare
6
Si vous voulez être à l'épreuve du temps, vous pouvez en fait remplacer les DEUX méthodes. De cette façon, votre application continuera à fonctionner sur <21, mais vous serez prêt à partir une fois qu'elle aura complètement abandonné l'ancienne méthode. Et vous n'aurez pas à vous inquiéter getUrl()car la nouvelle méthode ne sera appelée que pour 24+
yuval
187

Documenter en détail pour les futurs lecteurs:

La réponse courte est que vous devez remplacer les deux méthodes. La shouldOverrideUrlLoading(WebView view, String url)méthode est obsolète dans l'API 24 et la shouldOverrideUrlLoading(WebView view, WebResourceRequest request)méthode est ajoutée dans l'API 24. Si vous ciblez des versions plus anciennes d'Android, vous avez besoin de l'ancienne méthode, et si vous ciblez 24 (ou une version ultérieure, si quelqu'un le lit dans un avenir lointain) il est également conseillé de remplacer cette dernière méthode.

Ce qui suit est le squelette sur la façon dont vous pourriez accomplir cela:

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

Tout comme shouldOverrideUrlLoading, vous pouvez proposer une approche similaire pour la shouldInterceptRequestméthode.

Henri
la source
6
@ webo80 En fait, il est ajouté dans API24 / N developer.android.com/reference/android/webkit/…
Henry
3
Il est préférable d'utiliser @RequiresApià la place de @TargetApi ici pour une utilisation future
Hibbem
1
Le problème avec la substitution des deux méthodes, au moins avec shouldInterceptRequest, est que sur les appareils Android N +, elles sont toutes les deux appelées et vous gérerez chaque uri deux fois! Pour remédier à cela, j'ai ajouté une Build.VERSION.SDK_INT < Build.VERSION_CODES.Ncondition dans la version obsolète.
Jonik
8
@JohnLee Normalement, une seule des méthodes sera appelée. Mais si vous deviez mettre super. shouldOverrideUrlLoading(view,request)la méthode non obsolète, alors oui, la méthode non obsolète et la méthode obsolète seront invoquées. Cela est dû au fait que l'implémentation par défaut de la méthode non obsolète consiste à appeler en interne la méthode obsolète. Jetez un œil au WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request). Assurez-vous donc de ne pas appeler super.shouldOverrideUrlLoading().
Henry
1
Soulignant simplement que la fonctionnalité d'appeler les deux méthodes n'est pas documentée. Je ne me fierais pas à ce que cela soit toujours le cas car cela n'est pas mentionné dans la documentation.
Austyn Mahoney
15

Utilisation

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
Saleem Kalro
la source
2
c'est view.loadUrl (request.getUrl (). toString ());
Hibbem le
son travail mais si nous l'utilisons à l'époque, il fermera l'application
MRRaja
4
cela ne prendrait pas en charge les API de moins de 21
mumair
-1

Implémentez les méthodes obsolètes et non obsolètes comme ci-dessous. Le premier consiste à gérer le niveau d'API 21 et plus, le second est inférieur au niveau d'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
        }
}
emre
la source
1
Cela semble être une copie partielle de la réponse de Henry, mais cela rejette la valeur renvoyée par Uri.parseet parseUri. Les nouvelles réponses devraient ajouter de nouvelles informations utiles et de nouvelles perspectives sur le sujet.
AdrianHHH
M'a fait perdre du temps car l'api n'est obsolète que sur l'API 24 et non 21
Gustavo Baiocchi Costa