একটি অ্যান্ড্রয়েড অ্যাপের লাইফসাইকেল পরিচালনা করার সময়, ব্যাকগ্রাউন্ডে রিসোর্স পুনরুদ্ধারের সময় ব্যবহারকারীর স্টেট সংরক্ষণ করা একটি নির্বিঘ্ন ইউজার এক্সপেরিয়েন্সের মূল উপাদান। যেসব অ্যাপে ওয়েব ওয়ার্কফ্লো অন্তর্ভুক্ত থাকে, সেখানে WebView.saveState(Bundle) আপনাকে একটি WebView-এর নেভিগেশন হিস্ট্রি এবং স্টেটকে একটি Bundle এ সিরিয়ালাইজ করতে দেয়। এই ডেটা পরবর্তীতে WebView.restoreState(Bundle) ব্যবহার করে পুনরুদ্ধার করা যেতে পারে।
তবে, ভারী ব্রাউজিং সেশনের সময় স্ট্যান্ডার্ড বাস্তবায়নগুলো ট্রানজ্যাকশন আকারের সীমাবদ্ধতার সম্মুখীন হতে পারে। এই পৃষ্ঠাটি এই স্থাপত্যগত সীমাবদ্ধতাগুলো বর্ণনা করে এবং নেভিগেশন ইতিহাস বজায় রেখে মেমরি-সম্পর্কিত ব্যতিক্রম প্রতিরোধ করার কৌশল প্রদান করে।
১ মেগাবাইট লেনদেনের সীমা এবং অবস্থা মুছে ফেলা
অ্যান্ড্রয়েড savedInstanceState মধ্যে সংরক্ষিত ডেটার মোট পরিমাণের উপর একটি কঠোর ১ মেগাবাইট সীমা আরোপ করে। এই ১ মেগাবাইটের বাজেটটি সম্পূর্ণ অ্যাপ প্রসেস জুড়ে ভাগ করা থাকে। যদি কোনো অ্যাপে একাধিক WebView ইনস্ট্যান্স থাকে, তবে তাদের সম্মিলিত নেভিগেশন স্টেট এবং হিস্ট্রি অবশ্যই এই একক ভাগ করা জায়গার মধ্যে থাকতে হবে। এই সীমা অতিক্রম করলে একটি TransactionTooLargeException ট্রিগার হয়, যার ফলে অ্যাপটি ক্র্যাশ করে।
একটি প্রচলিত কিন্তু সমস্যাযুক্ত প্রশমন কৌশল হলো WebView স্টেট বান্ডেলের আকার পর্যবেক্ষণ করা এবং যদি তা একটি নির্দিষ্ট সুরক্ষা সীমা (যেমন ৩০০ কিলোবাইট) অতিক্রম করে, তবে WebView-এর হিস্ট্রি সম্পূর্ণরূপে মুছে ফেলা। যদিও এটি ক্র্যাশ প্রতিরোধ করে, তবে এটি ব্যবহারকারীর অভিজ্ঞতায় গুরুতর অবনতি ঘটায়:
ব্যাকওয়ার্ড নেভিগেশন হারিয়ে যাওয়া : অ্যান্ড্রয়েড প্রায়শই অন্যান্য কাজের জন্য মেমরি পুনরুদ্ধার করতে ব্যাকগ্রাউন্ড অ্যাপ প্রসেসগুলো বন্ধ করে দেয়। নেভিগেশন হিস্ট্রি সংরক্ষণ করার জন্য আপনি
onSaveInstanceState()লাইফসাইকেল কলব্যাকের মধ্যেsaveState(Bundle)ব্যবহার করতে পারেন। যদি আপনি ১ মেগাবাইট ট্রানজ্যাকশন লিমিট এড়ানোর জন্য এই হিস্ট্রি মুছে ফেলেন, তাহলে সম্পূর্ণ নেভিগেশন স্ট্যাকটি হারিয়ে যায়। যখন ব্যবহারকারী অ্যাপে ফিরে আসেন, তখন সিস্টেমের ব্যাক বাটনটি সাথে সাথে কম্পোনেন্ট বা অ্যাপ থেকে বেরিয়ে যায়, কারণ ব্যাকওয়ার্ড নেভিগেশন সমর্থন করার জন্য কোনো ঐতিহাসিক প্রেক্ষাপট অবশিষ্ট থাকে না, প্রসেসটি পুনরায় চালু হয়েছে কি না তা নির্বিশেষে।BFCache বাতিলকরণ : হিস্ট্রি মুছে ফেললে অ্যাপটি ব্যাক-ফরোয়ার্ড ক্যাশ (BFCache) ব্যবহার করতে পারে না, ফলে পূর্বে ভিজিট করা পেজগুলো তাৎক্ষণিকভাবে রেন্ডার করার ক্ষমতা নষ্ট হয়ে যায়।
বর্ধিত লেটেন্সি : ব্যবহারকারীরা ওয়েবভিউ-এর মধ্যে তাদের বর্তমান অবস্থা হারিয়ে ফেলেন, যার ফলে সম্পূর্ণ নতুন করে নেভিগেশন এবং পুনরায় ইনিশিয়ালাইজেশনের প্রয়োজন হয়। এই প্রক্রিয়াটি নেটওয়ার্ক ওভারহেড এবং ট্রানজ্যাকশন লেটেন্সি উল্লেখযোগ্যভাবে বাড়িয়ে দেয়।
স্থাপত্য প্রশমন কৌশল
সম্পূর্ণ হিস্ট্রি মুছে ফেলার মাধ্যমে ব্যবহারকারীর অভিজ্ঞতা নষ্ট না করে TransactionTooLargeException ক্র্যাশ প্রতিরোধ করতে, আপনাকে স্টেট রিটেনশন এবং মেমরি এফিসিয়েন্সির মধ্যে একটি কঠোর ভারসাম্য বজায় রাখতে হবে। নিম্নলিখিত অপটিমাইজেশন কৌশলগুলো প্রয়োগ করার মাধ্যমে, আপনি অপরিহার্য ন্যাভিগেশন হিস্ট্রি এবং সেশন ইন্টিগ্রিটি অক্ষুণ্ণ রেখে নিরাপদে ১ মেগাবাইট ট্রানজ্যাকশন বাজেট পরিচালনা করতে পারবেন।
রাষ্ট্রীয় সিরিয়ালাইজেশনের উপর আকারের সীমা প্রয়োগ করুন
ন্যাভিগেশন স্ট্যাক খুব বড় হয়ে গেলে সেটিকে পুরোপুরি মুছে ফেলার পরিবর্তে, ঐতিহাসিক ডেটা ছেঁটে ফেলা একটি আরও কার্যকর পদ্ধতি:
নির্দিষ্ট ড্রপ নীতি : একটি নির্দিষ্ট বাইট সীমা প্রয়োগ করার সময় স্টেটকে সিরিয়ালাইজ করতে
WebViewCompat.saveState()ব্যবহার করুন (উদাহরণস্বরূপ,WebViewCompat.saveState(webView, outState, maxSizeBytes))। এই API স্বয়ংক্রিয়ভাবে পুরোনো নেভিগেশন এন্ট্রিগুলিকে ক্রমানুসারে ড্রপ করে যতক্ষণ না মোট পেলোড আপনার সংজ্ঞায়িত বরাদ্দের মধ্যে ধরে যায়। সবচেয়ে গুরুত্বপূর্ণ বিষয় হলো, এটি সক্রিয়WebViewএর লাইভ হিস্ট্রি পরিবর্তন বা মুছে না ফেলে শুধুমাত্র সিরিয়ালাইজডBundleছোট করে, যা নিশ্চিত করে যে তাৎক্ষণিক ব্যাকওয়ার্ড নেভিগেশন সম্পূর্ণ অক্ষত থাকে।ফরোয়ার্ড এন্ট্রি অপসারণ : যদি অ্যাপ্লিকেশন ইন্টারফেসে একটি ব্যাক বাটন থাকে কিন্তু সামনে যাওয়ার জন্য কোনো নির্দিষ্ট বাটন না থাকে, তাহলে আপনি
saveStateAPI-এরincludeForwardStateপ্যারামিটারটিকেfalseসেট করে সামনে যাওয়ার সমস্ত এন্ট্রি বাতিল করতে পারেন। এটি ব্যবহারকারীর উপলব্ধ নেভিগেশন পাথগুলোকে প্রভাবিত না করেই পেলোডের আকার উল্লেখযোগ্যভাবে হ্রাস করে।
HTTP Cache Quota API ব্যবহার করে রিসোর্স লেটেন্সি পরিচালনা করুন।
saveState যেখানে ক্ষণস্থায়ী নেভিগেশন হিস্টোরির জন্য ১ মেগাবাইট Bundle সীমা পরিচালনা করে, সেখানে HTTP Cache Quota API প্রতিটি প্রোফাইলের ভিত্তিতে স্থায়ী ওয়েব রিসোর্স (ডিস্ক ক্যাশে)-এর ওপর ম্যানুয়াল নিয়ন্ত্রণ প্রদান করে। এটি স্বল্পমেয়াদী নেভিগেশন কনটেক্সট এবং দীর্ঘমেয়াদী ক্যাশ করা অ্যাসেটের মধ্যে একটি সুস্পষ্ট পার্থক্য তৈরি করে।
উপযুক্ত কোটা বেছে নেওয়ার ক্ষেত্রে কর্মক্ষমতার সাথে একটি আপস জড়িত থাকে:
- উচ্চতর কোটা ডিস্কে আরও বেশি অ্যাসেট রাখার মাধ্যমে অফলাইন প্রাপ্যতা এবং রিসোর্স লোডিং ল্যাটেন্সি উন্নত করে।
- কম কোটা অ্যাপের ডিস্ক ফুটপ্রিন্ট হ্রাস করে এবং অপারেটিং সিস্টেম দ্বারা অন্যান্য গুরুত্বপূর্ণ অ্যাপ ডেটার ক্যাশে অপসারণ প্রতিরোধ করে।
এই সেটিংসগুলো অ্যাপ পুনরায় চালু করার পরেও অপরিবর্তিত থাকে এবং এগুলো অবশ্যই মূল থ্রেড থেকে কনফিগার করতে হবে।
নিম্নলিখিত বাস্তবায়নটি দেখায় কিভাবে ডিফল্ট প্রোফাইলের জন্য একটি ডিস্ক ক্যাশে কোটা কনফিগার করতে হয়:
কোটলিন
if (WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE) &&
WebViewFeature.isFeatureSupported(WebViewFeature.HTTP_CACHE)) {
val defaultProfile = ProfileStore.getInstance()
.getOrCreateProfile(Profile.DEFAULT_PROFILE_NAME)
val httpCache = defaultProfile.httpCache
// Set explicit cache size to 50MB (50 * 1024 * 1024 bytes)
httpCache.setQuotaBytes(50L * 1024 * 1024)
}
জাভা
if (WebViewFeature.isFeatureSupported(WebViewFeature.MULTI_PROFILE) &&
WebViewFeature.isFeatureSupported(WebViewFeature.HTTP_CACHE)) {
Profile defaultProfile = ProfileStore.getInstance()
.getOrCreateProfile(Profile.DEFAULT_PROFILE_NAME);
HttpCache httpCache = defaultProfile.getHttpCache();
// Set explicit cache size to 50MB (50 * 1024 * 1024 bytes)
httpCache.setQuotaBytes(50L * 1024 * 1024);
}
কোটা নির্ধারণের কৌশল, জীবনচক্র ব্যবস্থাপনা এবং প্রোফাইল সীমানা সম্পর্কে আরও তথ্যের জন্য, WebView-তে HTTP ক্যাশে কোটা পরিচালনা দেখুন।
মূল কর্মক্ষমতা বিবেচনা
নিম্নলিখিত বিষয়গুলো WebView-এর স্টেট আচরণকে নিয়ন্ত্রণকারী প্রযুক্তিগত সীমাবদ্ধতা এবং অভ্যন্তরীণ ডেটার আচরণ তুলে ধরে:
অস্বচ্ছ
PageStateব্লব :saveStateদ্বারা সংরক্ষিত ডেটার প্রায় ৭০% রেন্ডারিং ইঞ্জিনের অভ্যন্তরীণPageStateব্লব নিয়ে গঠিত। এই ডেটা ফর্ম ইনপুট এবং আইফ্রেম স্ক্রোল পজিশন সহ সেশনের সূক্ষ্ম অবস্থা ধারণ করে। এই ব্লবগুলি থেকে ম্যানুয়ালি পৃথক অংশ পার্স বা আলাদা করার চেষ্টা এড়িয়ে চলুন, কারণ এটি গুরুতর নিরাপত্তা ঝুঁকি তৈরি করে এবং সেশন পুনরুদ্ধারের অখণ্ডতা নষ্ট করে।সূক্ষ্ম ইতিহাস ব্যবস্থাপনা : স্ট্যান্ডার্ড
WebBackForwardListAPI স্বাভাবিকভাবে স্বতন্ত্র ঐতিহাসিক উপাদানগুলোকে যথেচ্ছভাবে মুছে ফেলার সুবিধা দেয় না। কঠোর স্টেট ব্যবস্থাপনার জন্য, স্থাপত্যগত নিরাপত্তা নিশ্চিত করতে আপনাকে অবশ্যইWebViewCompat.saveState()এর মধ্যেmaxSizeBytesএবংincludeForwardStateপ্যারামিটার ব্যবহার করে ট্রাঙ্কেশন কৌশল প্রয়োগ করতে হবে।