`ควรค่ามากเกินไป uL Loading` คัดค้านหรือไม่ ฉันจะใช้อะไรแทนได้บ้าง


138

"ควรOverrideUrlLoading" ถูกคัดออกจริงหรือ ถ้าเป็นเช่นนั้นฉันจะใช้อะไรได้บ้าง

ดูเหมือนว่า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:")) {
        ...
    }
    ...
}

และนี่คือข้อความที่ Android Studio มอบให้ฉัน:

แทนที่เมธอดที่เลิกใช้แล้วใน 'android.webkit.WebViewClient' รายงานการตรวจสอบนี้ที่ใช้รหัสที่เลิกใช้แล้วในขอบเขตการตรวจสอบที่ระบุ

Google ไม่ได้พูดอะไรเกี่ยวกับการคัดค้านนั้น

ฉันสงสัยว่าการใช้@SuppressWarnings("deprecation")จะให้ฉันทำงานกับอุปกรณ์ทั้งหมดตั้งแต่ API 19 จนถึง Android N Beta ล่าสุด (และเวอร์ชันสุดท้ายเมื่อปล่อยออกมา) ฉันไม่สามารถทดสอบตัวเองได้ฉันไม่เคยใช้มันและฉันต้องแน่ใจ มันใช้งานได้เพื่อให้ทุกคนสามารถบอกได้?


1
วิธีการติดต่อกลับนั้นมีสองรุ่น คนเก่าเลิกใช้แล้ว ในกรณีนี้ "คัดค้าน" หมายถึง "เฮ้เรามีอย่างอื่นที่คุณอาจต้องการลองถ้ามันเหมาะสมสำหรับคุณ" การโทรกลับเก่าควรทำงานต่อไปเนื่องจากจำเป็นต้องใช้การโทรกลับเก่าสำหรับ Android รุ่นก่อน N
CommonsWare

ครั้งแรกขอบคุณสำหรับความคิดเห็นรุ่นที่ฉันใช้ฉันคิดว่าเป็นรุ่นที่ดีเนื่องจากเป็นเอกสาร Android Developer ที่แน่นอนยกเว้นชื่อสตริงพวกเขาใช้ "มุมมอง" และฉันใช้ "มุมมองเว็บ" สำหรับส่วนที่เหลือเหมือนกันดังนั้นทำไมฉันถึงต้องทำให้มันใช้งานได้กับทุกเวอร์ชั่น?
Minion

คำตอบ:


95

รุ่นที่ฉันใช้ฉันคิดว่าเป็นรุ่นที่ดีเนื่องจากเป็นเอกสารของนักพัฒนาซอฟต์แวร์ Android ยกเว้นชื่อของสตริงพวกเขาใช้ "มุมมอง" และฉันใช้ "มุมมองเว็บ" สำหรับส่วนที่เหลือเหมือนกัน

ไม่มันไม่ใช่.

สิ่งที่ใหม่สำหรับ N Developer Preview มีลายเซ็นของเมธอดนี้:

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

รุ่นที่รองรับโดย Android ทุกรุ่นรวมถึง N มีลายเซ็นของวิธีการนี้:

public boolean shouldOverrideUrlLoading(WebView view, String url)

แล้วทำไมฉันถึงต้องทำให้มันใช้งานได้กับทุกเวอร์ชั่น?

แทนที่อันที่คัดค้านซึ่งStringเป็นพารามิเตอร์ตัวที่สอง


สวัสดีและขอขอบคุณสำหรับคำตอบที่ยังไม่สามารถใช้งานได้ตั้งแต่ API 19 เนื่องจากได้รับสตริง URL ฉันต้องใช้ "url.getUrl (). toString ()" และมันถูกเพิ่มลงใน API 21 ด้วยวิธีการใด ๆ มันทำงานได้ตั้งแต่ API 19?
Minion

3
@Minion: "ที่ยังใช้งานไม่ได้ตั้งแต่ API 19" - ใช่ "เพราะจะได้รับสตริง URL ที่ผมต้องใช้ 'url.getUrl () toString ()'." - ไม่มี URL Stringที่ให้ไว้เป็นพารามิเตอร์ที่สองในรูปแบบของ ตัวอย่างเช่นแอปตัวอย่างนี้รวบรวมกับ API ระดับ 19 ทำงานได้ดีเช่นบน Android 6.0 ที่ขับเคลื่อนด้วย Nexus 5
CommonsWare

สวัสดีการใช้ "คำขอ WebResourceRequest" ไม่มีพารามิเตอร์ String
Minion

2
@ Minion: ถูกต้อง ใช้งานได้กับ Android N เท่านั้น (และน่าจะสูงกว่า) คุณถามว่า "แล้วทำไมฉันต้องทำเพื่อให้มันใช้ได้กับทุกเวอร์ชั่น" ฉันบอกให้คุณแทนที่อันที่คัดค้าน, อันที่ใช้Stringเป็นพารามิเตอร์ตัวที่สอง ตัวอย่างเช่นแอปตัวอย่างที่ฉันเชื่อมโยงซึ่งแทนที่การโทรกลับที่เลิกใช้งานได้ดีบน Nexus 6 ที่รัน N Preview Preview สำหรับนักพัฒนา 1
CommonsWare

6
หากคุณต้องการพิสูจน์ในอนาคตคุณสามารถแทนที่ทั้งสองวิธีได้ ด้วยวิธีนี้แอปของคุณจะยังคงทำงานต่อใน <21 แต่คุณพร้อมที่จะไปเมื่อพวกเขาเลิกใช้วิธีเดิมอย่างสมบูรณ์ และคุณไม่ต้องกังวลgetUrl()เพราะจะมีการเรียกใช้วิธีการใหม่
ตั้งแต่ 24+ ขึ้นไป

187

เอกสารรายละเอียดสำหรับผู้อ่านในอนาคต:

คำตอบสั้น ๆ คือคุณต้องแทนที่ทั้งสองวิธี shouldOverrideUrlLoading(WebView view, String url)วิธีการจะเลิกใน API 24 และshouldOverrideUrlLoading(WebView view, WebResourceRequest request)วิธีการที่จะเพิ่มเข้ามาใน API 24. หากคุณกำหนดเป้าหมายรุ่นเก่าของหุ่นยนต์คุณต้องอดีตวิธีการและถ้าคุณกำหนดเป้าหมาย 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;
        }
    }
}

เช่นเดียวกับshouldOverrideUrlLoadingคุณสามารถหาวิธีที่คล้ายกันสำหรับshouldInterceptRequestวิธีการ


6
@ webo80 จริงๆแล้วมันจะถูกเพิ่มใน API24 / N developer.android.com/reference/android/webkit/ …
เฮนรี่

3
จะดีกว่าที่จะใช้@RequiresApiแทน @TargetApi ที่นี่เพื่อใช้ในอนาคต
Hibbem

1
ปัญหาเกี่ยวกับการเอาชนะทั้งสองวิธีอย่างน้อยด้วยshouldInterceptRequestคือว่าบน Android N + อุปกรณ์ที่พวกเขากำลังทั้งเรียกและคุณจะได้รับการจัดการในแต่ละ URI สองครั้ง! เพื่อแก้ไขปัญหานั้นฉันได้เพิ่มBuild.VERSION.SDK_INT < Build.VERSION_CODES.Nเงื่อนไขในเวอร์ชันที่เลิกใช้แล้ว
Jonik

8
@JohnLee โดยปกติจะใช้วิธีการเดียวเท่านั้น แต่ถ้าคุณจะใส่super. shouldOverrideUrlLoading(view,request)ในวิธีที่ไม่คัดค้านแล้วใช่ทั้งวิธีที่ไม่คัดค้านและวิธีเลิกใช้จะถูกเรียกใช้ นี่เป็นเพราะการใช้งานเริ่มต้นของวิธีการที่ไม่คัดค้านคือการเรียกใช้วิธีการคัดค้านภายใน WebViewClient.shouldOverrideUrlLoading(WebView view, WebResourceRequest request)เพียงแค่ดูที่ที่ super.shouldOverrideUrlLoading()เพื่อให้แน่ใจว่าคุณไม่ได้เรียก
Henry

1
เพียงแค่ชี้ให้เห็นว่าการทำงานของการมีทั้งสองวิธีที่เรียกว่าไม่มีการบันทึกไว้ ฉันจะไม่พึ่งพาสิ่งนั้นเสมอเพราะมันไม่ได้กล่าวถึงในเอกสารประกอบ
Austyn Mahoney

15

ใช้

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

2
มันคือ view.loadUrl (request.getUrl (). toString ());
Hibbem

มันใช้งานได้ แต่ถ้าเราใช้ย้อนกลับไปมันจะปิดแอพ
MRRaja

4
สิ่งนี้จะไม่สนับสนุน api น้อยกว่า 21
mumair

-1

ใช้วิธีการทั้งที่คัดค้านและไม่เลิกดังเช่นด้านล่าง อันแรกคือจัดการ API ระดับ 21 และสูงกว่าอันที่สองจัดการต่ำกว่า 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
        }
}

1
นี้ดูเหมือนจะเป็นสำเนาบางส่วนของคำตอบของเฮนรี่ แต่ทิ้งนี้ค่าส่งกลับโดยและUri.parse parseUriคำตอบใหม่ควรเพิ่มข้อมูลใหม่ที่เป็นประโยชน์และข้อมูลเชิงลึกใหม่เข้าไปในหัวข้อ
AdrianHHH

ทำให้ฉันเสียเวลาเนื่องจาก api เลิกใช้แล้วใน API 24 เท่านั้นไม่ใช่ 21
Gustavo Baiocchi Costa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.