অ্যান্ড্রয়েড ১৭ থেকে শুরু করে, অ্যান্ড্রয়েড ১৭ (এপিআই লেভেল ৩৭) বা তার উচ্চতর সংস্করণকে টার্গেট করা অ্যাপগুলো android.os.MessageQueue এর একটি নতুন লক-ফ্রি ইমপ্লিমেন্টেশন পাবে। এই নতুন ইমপ্লিমেন্টেশনটি পারফরম্যান্স উন্নত করে এবং মিসড ফ্রেম কমায়, কিন্তু যেসব ক্লায়েন্ট MessageQueue প্রাইভেট ফিল্ড এবং মেথড রিফ্লেক্ট করে, তাদের ক্ষেত্রে এটি সমস্যা তৈরি করতে পারে।
অ্যান্ড্রয়েড ১৭, অন্তর্নিহিত MessageQueue ক্লাসটিকে নতুন করে লেখার মাধ্যমে Looper এবং Handler কার্যপ্রণালীতে একটি উল্লেখযোগ্য পরিবর্তন এনেছে। অ্যান্ড্রয়েড অপারেটিং সিস্টেমের প্রথম সংস্করণ থেকেই, MessageQueue প্রধান থ্রেডের টাস্ক কিউ পরিচালনা করার জন্য একটিমাত্র লকের উপর নির্ভর করত। এই নকশার কারণে প্রায়শই লক কনটেনশন ঘটত; প্রধান থ্রেডটি একটি ব্যাকগ্রাউন্ড থ্রেডের দ্বারা ব্লক হয়ে যেতে পারত, যার ফলে ফ্রেম ড্রপ হতো এবং UI জ্যাঙ্ক দেখা দিত।
প্রভাব প্রশমিত করুন
আপনার অ্যাপটি এই পরিবর্তনের দ্বারা প্রভাবিত হতে পারে, যদি এটি বা এর নির্ভরতাগুলি MessageQueue অভ্যন্তর দেখার জন্য রানটাইম রিফ্লেকশনের উপর নির্ভর করে। MessageQueue পরিদর্শন করতে রানটাইম রিফ্লেকশন ব্যবহার করা থেকে বিরত থাকুন।
পুরোনো ইমপ্লিমেন্টেশনে, ডেভেলপাররা মাঝে মাঝে পেন্ডিং মেসেজগুলো দেখার জন্য MessageQueue.mMessages মতো প্রাইভেট ফিল্ড অ্যাক্সেস করতেন। নতুন লক-ফ্রি ইমপ্লিমেন্টেশনে, অভ্যন্তরীণ ডেটা স্ট্রাকচারগুলো সম্পূর্ণ বদলে গেছে। বাইনারি কম্প্যাটিবিলিটি বজায় রাখতে, অ্যান্ড্রয়েড ১৭ mMessages ফিল্ডটি রেখেছে, কিন্তু নতুন ইমপ্লিমেন্টেশনে এই ফিল্ডটি সবসময় null থাকে, কিউতে মেসেজ থাকুক বা না থাকুক।
এছাড়াও, আপনি যদি কিছু জনপ্রিয় টেস্টিং লাইব্রেরি ব্যবহার করেন, তাহলে নতুন MessageQueue ইমপ্লিমেন্টেশনের সাথে সামঞ্জস্যপূর্ণ করার জন্য আপনাকে আপনার লাইব্রেরিগুলো আপডেট করতে হবে।
এসপ্রেসো
এসপ্রেসো সাধারণত UI টেস্টিং-এর জন্য ব্যবহৃত হয়। UI স্টেট সঠিকভাবে অ্যাসার্ট করার জন্য এসপ্রেসো লাইব্রেরির জানা প্রয়োজন যে মেইন থ্রেড কখন নিষ্ক্রিয় থাকে। এসপ্রেসোর পূর্ববর্তী সংস্করণগুলো রিফ্লেকশন কৌশলের উপর নির্ভর করত, যা এখন আর লক-ফ্রি মেসেজকিউ (MessageQueue)-এর সাথে সামঞ্জস্যপূর্ণ নয়।
পদক্ষেপ
Espresso 3.7.0 বা নতুন সংস্করণে আপডেট করুন। এই সংস্করণটি TestLooperManager API, বিশেষ করে Android 16-এ প্রবর্তিত নতুন API-গুলো ব্যবহার করে, যা অভ্যন্তরীণ বাস্তবায়নের বিবরণের উপর নির্ভর না করে নিরাপদে Looper এর সাথে যোগাযোগ করতে পারে।
রোবোইলেকট্রিক
একইভাবে, আপনি যদি রোবোইলেকট্রিক ব্যবহার করে ইউনিট টেস্ট চালান, তাহলে আপনার টেস্টগুলো যদি লিগ্যাসি লুপার মোডের ওপর নির্ভরশীল হয়, তবে আপনি সমস্যার সম্মুখীন হতে পারেন।
পদক্ষেপ
Robolectric 4.17 বা নতুন সংস্করণে আপডেট করুন। আপনি যদি @LooperMode(LEGACY) ব্যবহার করে থাকেন, তাহলে আপনাকে আপনার টেস্টগুলো নতুন @LooperMode(PAUSED) এ স্থানান্তর করতে হবে। আরও তথ্যের জন্য Robolectric-এর মাইগ্রেশন গাইড দেখুন।
আচরণ পরীক্ষা করুন
নিম্নলিখিত কমান্ডটি চালিয়ে আপনি targetSDK আপডেট না করেই Android 17-এ আচরণগত পরিবর্তনসহ আপনার অ্যাপটি পরীক্ষা করতে পারেন:
adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>
এই কমান্ডটি আপনার অ্যাপে লক-ফ্রি MessageQueue সক্রিয় করে, যদি এটি একটি ডিবাগযোগ্য বিল্ড হয়।
আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১৭ (এপিআই লেভেল ৩৭) টার্গেট করে, তাহলে নতুন আচরণটি ডিফল্টরূপে সক্রিয় থাকে। এই এপিআই লেভেলটি টার্গেট করার পর যদি আপনি কোনো অপ্রত্যাশিত আচরণ বা ক্র্যাশ লক্ষ্য করেন, তবে এর কারণ MessageQueue কিনা তা যাচাই করার জন্য আপনি সাময়িকভাবে নতুন বাস্তবায়নটি নিষ্ক্রিয় করতে পারেন।
আপনি দুটি বিকল্পের যেকোনো একটি ব্যবহার করে পরিবর্তনটি চালু বা বন্ধ করতে পারেন:
নিম্নলিখিত ADB কমান্ডটি চালিয়ে:
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
এটি আপনার অ্যাপকে পুরোনো, লক-ভিত্তিক বাস্তবায়নে ফিরিয়ে দেয়, যার ফলে সমস্যাটি মেসেজ কিউ-এর আচরণের পরিবর্তনের কারণে হয়েছিল কিনা তা আপনি শনাক্ত করতে পারবেন।