WebView অবজেক্ট পরিচালনা করুন

আপনার অ্যাপে ওয়েব কন্টেন্ট প্রদর্শন করে এমন WebView অবজেক্টগুলি পরিচালনা করতে আপনাকে সাহায্য করার জন্য Android বেশ কিছু API প্রদান করে।

এই পৃষ্ঠাটি বর্ণনা করে কিভাবে এই APIগুলিকে WebView অবজেক্টের সাথে আরও কার্যকরভাবে কাজ করতে, আপনার অ্যাপের স্থায়িত্ব এবং নিরাপত্তা উন্নত করে৷

সংস্করণ API

অ্যান্ড্রয়েড 7.0 (এপিআই স্তর 24) থেকে শুরু করে, ব্যবহারকারীরা WebView অবজেক্টে ওয়েব সামগ্রী প্রদর্শনের জন্য বিভিন্ন প্যাকেজের মধ্যে বেছে নিতে পারেন। AndroidX.webkit লাইব্রেরিতে getCurrentWebViewPackage() পদ্ধতিটি প্যাকেজের সাথে সম্পর্কিত তথ্য আনার জন্য রয়েছে যা আপনার অ্যাপে ওয়েব সামগ্রী প্রদর্শন করছে। এই পদ্ধতিটি তখনই উপযোগী যখন আপনার অ্যাপ WebView এর একটি নির্দিষ্ট প্যাকেজের বাস্তবায়ন ব্যবহার করে ওয়েব সামগ্রী প্রদর্শন করার চেষ্টা করে তখনই ঘটে এমন ত্রুটিগুলি বিশ্লেষণ করার সময়।

এই পদ্ধতিটি ব্যবহার করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো যুক্তি যোগ করুন:

কোটলিন

val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext)
Log.d("MY_APP_TAG", "WebView version: ${webViewPackageInfo.versionName}")

জাভা

PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext);
Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);

গুগল সেফ ব্রাউজিং সার্ভিস

আপনার ব্যবহারকারীদের একটি নিরাপদ ব্রাউজিং অভিজ্ঞতা প্রদান করতে, WebView অবজেক্টগুলি Google নিরাপদ ব্রাউজিং ব্যবহার করে URL গুলি যাচাই করে, যা আপনার অ্যাপ ব্যবহারকারীদের একটি সতর্কতা দেখাতে দেয় যখন তারা একটি সম্ভাব্য অনিরাপদ ওয়েবসাইটে নেভিগেট করার চেষ্টা করে৷

যদিও EnableSafeBrowsing এর ডিফল্ট মান সত্য, এমন কিছু ক্ষেত্রে আছে যখন আপনি শুধুমাত্র শর্তসাপেক্ষে নিরাপদ ব্রাউজিং সক্ষম করতে বা এটি নিষ্ক্রিয় করতে চাইতে পারেন। Android 8.0 (API স্তর 26) এবং পরবর্তীতে একটি পৃথক WebView অবজেক্টের জন্য নিরাপদ ব্রাউজিং টগল করতে setSafeBrowsingEnabled() ব্যবহার করে সমর্থন করে।

আপনি যদি সমস্ত WebView অবজেক্ট নিরাপদ ব্রাউজিং চেক থেকে অপ্ট আউট করতে চান, তাহলে আপনার অ্যাপের ম্যানিফেস্ট ফাইলে নিম্নলিখিত <meta-data> উপাদান যোগ করুন:

<manifest>
    <application>
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="false" />
        ...
    </application>
</manifest>

প্রোগ্রাম্যাটিক কর্মের সংজ্ঞা দাও

যখন WebView এর একটি উদাহরণ Google দ্বারা পরিচিত হুমকি হিসাবে শ্রেণীবদ্ধ একটি পৃষ্ঠা লোড করার চেষ্টা করে, তখন WebView ডিফল্টভাবে একটি ইন্টারস্টিশিয়াল দেখায় যা ব্যবহারকারীদের পরিচিত হুমকি সম্পর্কে সতর্ক করে। এই স্ক্রীন ব্যবহারকারীদের যেভাবেই হোক URL লোড করার বা নিরাপদ আগের পৃষ্ঠায় ফিরে যাওয়ার বিকল্প দেয়৷

আপনি যদি Android 8.1 (API লেভেল 27) বা তার পরে টার্গেট করেন, তাহলে নিচের উপায়ে আপনার অ্যাপ কীভাবে পরিচিত হুমকির প্রতি সাড়া দেয় তা আপনি প্রোগ্রাম্যাটিকভাবে সংজ্ঞায়িত করতে পারেন:

  • আপনার অ্যাপ নিরাপদ ব্রাউজিং-এর জন্য পরিচিত হুমকির রিপোর্ট করে কিনা তা আপনি নিয়ন্ত্রণ করতে পারেন।
  • আপনি আপনার অ্যাপটিকে স্বয়ংক্রিয়ভাবে একটি নির্দিষ্ট ক্রিয়া সম্পাদন করতে পারেন—যেমন নিরাপত্তায় ফিরে যাওয়া—প্রতিবার যখন এটি একটি পরিচিত হুমকি হিসাবে শ্রেণীবদ্ধ একটি URL এর মুখোমুখি হয়।

নিম্নলিখিত কোড স্নিপেটগুলি দেখায় যে কীভাবে আপনার অ্যাপের WebView -এর দৃষ্টান্তগুলিকে একটি পরিচিত হুমকির সম্মুখীন হওয়ার পরে সর্বদা নিরাপদে ফিরে যেতে নির্দেশ দিতে হয়:

MyWebActivity.java

কোটলিন

private lateinit var superSafeWebView: WebView
private var safeBrowsingIsInitialized: Boolean = false

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    superSafeWebView = WebView(this)
    superSafeWebView.webViewClient = MyWebViewClient()
    safeBrowsingIsInitialized = false

    if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
        WebViewCompat.startSafeBrowsing(this, ValueCallback<Boolean> { success ->
            safeBrowsingIsInitialized = true
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!")
            }
        })
    }
}

জাভা

private WebView superSafeWebView;
private boolean safeBrowsingIsInitialized;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    superSafeWebView = new WebView(this);
    superSafeWebView.setWebViewClient(new MyWebViewClient());
    safeBrowsingIsInitialized = false;

    if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
        WebViewCompat.startSafeBrowsing(this, new ValueCallback<Boolean>() {
            @Override
            public void onReceiveValue(Boolean success) {
                safeBrowsingIsInitialized = true;
                if (!success) {
                    Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!");
                }
            }
        });
    }
}

MyWebViewClient.java

কোটলিন

class MyWebViewClient : WebViewClientCompat() {
    // Automatically go "back to safety" when attempting to load a website that
    // Google identifies as a known threat. An instance of WebView calls this
    // method only after Safe Browsing is initialized, so there's no conditional
    // logic needed here.
    override fun onSafeBrowsingHit(
            view: WebView,
            request: WebResourceRequest,
            threatType: Int,
            callback: SafeBrowsingResponseCompat
    ) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) {
            callback.backToSafety(true)
            Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show()
        }
    }
}

জাভা

public class MyWebViewClient extends WebViewClientCompat {
    // Automatically go "back to safety" when attempting to load a website that
    // Google identifies as a known threat. An instance of WebView calls this
    // method only after Safe Browsing is initialized, so there's no conditional
    // logic needed here.
    @Override
    public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
            int threatType, SafeBrowsingResponseCompat callback) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) {
            callback.backToSafety(true);
            Toast.makeText(view.getContext(), "Unsafe web page blocked.",
                    Toast.LENGTH_LONG).show();
        }
    }
}

HTML5 জিওলোকেশন API

Android 6.0 (API লেভেল 23) এবং পরবর্তীতে লক্ষ্য করা অ্যাপগুলির জন্য, জিওলোকেশন API শুধুমাত্র নিরাপদ অরিজিনে সমর্থিত, যেমন HTTPS। অ-সুরক্ষিত উত্সের জিওলোকেশন এপিআই-এর যেকোন অনুরোধ সংশ্লিষ্ট onGeolocationPermissionsShowPrompt() পদ্ধতি ব্যবহার না করেই স্বয়ংক্রিয়ভাবে অস্বীকার করা হয়।

মেট্রিক্স সংগ্রহ থেকে অপ্ট আউট করুন

যখন ব্যবহারকারী তাদের সম্মতি দেয় তখন WebView Google-এ বেনামী ডায়াগনস্টিক ডেটা আপলোড করার ক্ষমতা রয়েছে। প্রতিটি অ্যাপের জন্য প্রতি-অ্যাপের ভিত্তিতে ডেটা সংগ্রহ করা হয় যা একটি WebView ইনস্ট্যান্টিয়েট করে। আপনি ম্যানিফেস্টের <application> উপাদানে নিম্নলিখিত ট্যাগ তৈরি করে এই বৈশিষ্ট্যটি অপ্ট আউট করতে পারেন:

<manifest>
    <application>
    ...
    <meta-data android:name="android.webkit.WebView.MetricsOptOut"
               android:value="true" />
    </application>
</manifest>

ব্যবহারকারী সম্মতি দিলে এবং অ্যাপটি অপ্ট আউট না করলে শুধুমাত্র একটি অ্যাপ থেকে ডেটা আপলোড করা হয়। ডায়াগনস্টিক ডেটা রিপোর্টিং অপ্ট আউট করার বিষয়ে আরও তথ্যের জন্য, ওয়েবভিউ রিপোর্টিং-এ ব্যবহারকারীর গোপনীয়তা দেখুন।

টার্মিনেশন হ্যান্ডলিং API

টার্মিনেশন হ্যান্ডলিং এপিআই এমন ক্ষেত্রে পরিচালনা করে যেখানে একটি WebView অবজেক্টের জন্য রেন্ডারার প্রক্রিয়া চলে যায়, কারণ সিস্টেমটি প্রয়োজনীয় মেমরি পুনরুদ্ধার করতে রেন্ডারারকে হত্যা করে বা রেন্ডারার প্রক্রিয়া ক্র্যাশ হওয়ার কারণে। এই API ব্যবহার করে, আপনি আপনার অ্যাপকে এক্সিকিউট করা চালিয়ে যেতে দেন, যদিও রেন্ডারার প্রক্রিয়া চলে যায়।

যদি একটি রেন্ডারার একটি নির্দিষ্ট ওয়েব পৃষ্ঠা লোড করার সময় ক্র্যাশ হয়ে যায়, সেই একই পৃষ্ঠাটি আবার লোড করার চেষ্টা করার ফলে একটি নতুন WebView অবজেক্ট একই রেন্ডারিং ক্র্যাশ আচরণ প্রদর্শন করতে পারে৷

নিম্নলিখিত কোড স্নিপেট ব্যাখ্যা করে কিভাবে একটি Activity মধ্যে এই API ব্যবহার করতে হয়:

কোটলিন

    
inner class MyRendererTrackingWebViewClient : WebViewClient() {
    private var mWebView: WebView? = null

    override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean {
        if (!detail.didCrash()) {
            // Renderer is killed because the system ran out of memory. The app
            // can recover gracefully by creating a new WebView instance in the
            // foreground.
            Log.e("MY_APP_TAG", ("System killed the WebView rendering process " +
                "to reclaim memory. Recreating..."))

            mWebView?.also { webView ->
                val webViewContainer: ViewGroup = findViewById(R.id.my_web_view_container)
                webViewContainer.removeView(webView)
                webView.destroy()
                mWebView = null
            }

            // By this point, the instance variable "mWebView" is guaranteed to
            // be null, so it's safe to reinitialize it.

            return true // The app continues executing.
        }

        // Renderer crashes because of an internal error, such as a memory
        // access violation.
        Log.e("MY_APP_TAG", "The WebView rendering process crashed!")

        // In this example, the app itself crashes after detecting that the
        // renderer crashed. If you handle the crash more gracefully and let
        // your app continue executing, you must destroy the current WebView
        // instance, specify logic for how the app continues executing, and
        // return "true" instead.
        return false
    }
}

জাভা

public class MyRendererTrackingWebViewClient extends WebViewClient {
    private WebView mWebView;

    @Override
    public boolean onRenderProcessGone(WebView view,
            RenderProcessGoneDetail detail) {
        if (!detail.didCrash()) {
            // Renderer is killed because the system ran out of memory. The app
            // can recover gracefully by creating a new WebView instance in the
            // foreground.
            Log.e("MY_APP_TAG", "System killed the WebView rendering process " +
                    "to reclaim memory. Recreating...");

            if (mWebView != null) {
                ViewGroup webViewContainer =
                        (ViewGroup) findViewById(R.id.my_web_view_container);
                webViewContainer.removeView(mWebView);
                mWebView.destroy();
                mWebView = null;
            }

            // By this point, the instance variable "mWebView" is guaranteed to
            // be null, so it's safe to reinitialize it.

            return true; // The app continues executing.
        }

        // Renderer crashes because of an internal error, such as a memory
        // access violation.
        Log.e("MY_APP_TAG", "The WebView rendering process crashed!");

        // In this example, the app itself crashes after detecting that the
        // renderer crashed. If you handle the crash more gracefully and let
        // your app continue executing, you must destroy the current WebView
        // instance, specify logic for how the app continues executing, and
        // return "true" instead.
        return false;
    }
}

রেন্ডারার গুরুত্ব API

যখন WebView অবজেক্টগুলি মাল্টিপ্রসেস মোডে কাজ করে , তখন আপনার অ্যাপ কীভাবে মেমরির বাইরের পরিস্থিতিগুলি পরিচালনা করে তাতে আপনার কিছুটা নমনীয়তা থাকে৷ আপনি একটি নির্দিষ্ট WebView অবজেক্টের জন্য নির্ধারিত রেন্ডারারের জন্য একটি অগ্রাধিকার নীতি সেট করতে Android 8.0 এ প্রবর্তিত Renderer Importance API ব্যবহার করতে পারেন। বিশেষ করে, আপনার অ্যাপের WebView অবজেক্টগুলিকে দেখায় এমন একটি রেন্ডারার যখন মেরে ফেলা হয় তখন আপনি আপনার অ্যাপের মূল অংশটি কার্যকর করা চালিয়ে যেতে চাইতে পারেন। আপনি এটি করতে পারেন, উদাহরণস্বরূপ, যদি আপনি দীর্ঘ সময়ের জন্য WebView অবজেক্টটি না দেখানোর আশা করেন যাতে সিস্টেমটি রেন্ডারার ব্যবহার করা মেমরি পুনরুদ্ধার করতে পারে।

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে আপনার অ্যাপের WebView অবজেক্টের সাথে যুক্ত রেন্ডারার প্রক্রিয়াকে অগ্রাধিকার দিতে হয়:

কোটলিন

val myWebView: WebView = ...
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)

জাভা

WebView myWebView;
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);

এই নির্দিষ্ট স্নিপেটে, রেন্ডারারের অগ্রাধিকার অ্যাপটির ডিফল্ট অগ্রাধিকারের মতোই—বা আবদ্ধ। true যুক্তিটি রেন্ডারারের অগ্রাধিকার RENDERER_PRIORITY_WAIVED এ হ্রাস করে যখন সংশ্লিষ্ট WebView বস্তুটি আর দৃশ্যমান হয় না। অন্য কথায়, একটি true যুক্তি ইঙ্গিত করে যে আপনার অ্যাপ সিস্টেমটি রেন্ডারার প্রক্রিয়াটিকে জীবিত রাখে কিনা তা বিবেচনা করে না। প্রকৃতপক্ষে, এই নিম্ন অগ্রাধিকারের স্তরটি মেমরির বাইরের পরিস্থিতিতে রেন্ডারার প্রক্রিয়াটি মারা যাওয়ার সম্ভাবনা তৈরি করে।

সিস্টেম কীভাবে কম মেমরির পরিস্থিতি পরিচালনা করে সে সম্পর্কে আরও জানতে, প্রসেস এবং অ্যাপ লাইফসাইকেল দেখুন।