এই প্রশ্নের উত্তর দেওয়ার জন্য আপনাকে LoaderManager
কোডটি খনন করতে হবে । যদিও লোডারম্যানেজারের ডকুমেন্টেশন নিজেই যথেষ্ট পরিষ্কার নয় (বা এই প্রশ্নটি হবে না), বিমূর্ত লোডারম্যানেজারের একটি সাবক্লাস, লোডারম্যানেজারআইএমপিএল এর ডকুমেন্টেশন আরও বেশি আলোকিত করে তোলে।
initLoader
কোনও লোডার দিয়ে একটি নির্দিষ্ট আইডি শুরু করার জন্য কল করুন। যদি এই আইডিটির সাথে ইতিমধ্যে কোনও লোডার জড়িত থাকে, তবে এটি অপরিবর্তিত রেখে দেওয়া হবে এবং আগের যে কোনও কলব্যাকগুলি সদ্য সরবরাহ করা আইটেমগুলির সাথে প্রতিস্থাপিত হবে। যদি বর্তমানে আইডির জন্য কোনও লোডার না থাকে তবে একটি নতুন তৈরি করা এবং শুরু করা হয়।
কোনও উপাদান যখন আরম্ভ করা হয় তখন এটি নির্ভর করে যে কোনও লোডার তৈরি হয় তা নিশ্চিত করার জন্য সাধারণত এই ফাংশনটি ব্যবহার করা উচিত। এটি ইতিমধ্যে একটি বিদ্যমান লোডারের ডেটা পুনরায় ব্যবহারের অনুমতি দেয়, যাতে উদাহরণস্বরূপ কোনও কনফিগারেশন পরিবর্তনের পরে যখন ক্রিয়াকলাপটি পুনরায় তৈরি করা হয় তখন তার লোডারগুলি পুনরায় তৈরি করার প্রয়োজন হয় না।
restartLoader
নির্দিষ্ট আইডির সাথে যুক্ত লোডারটিকে পুনরায় তৈরি করার জন্য কল করুন। যদি বর্তমানে এই আইডির সাথে কোনও লোডার যুক্ত থাকে তবে এটি বাতিল / বন্ধ / যথাযথ হিসাবে নষ্ট হয়ে যাবে। প্রদত্ত আর্গুমেন্ট সহ একটি নতুন লোডার তৈরি করা হবে এবং এর ডেটা একবার উপলভ্য হয়ে গেলে।
[...] এই ফাংশনটি কল করার পরে, এই আইডি সম্পর্কিত কোনও পূর্ববর্তী লোডারগুলি অবৈধ হিসাবে বিবেচিত হবে এবং আপনি তাদের কাছ থেকে কোনও ডেটা আপডেট পাবেন না updates
মূলত দুটি মামলা রয়েছে:
- আইডি সহ লোডার বিদ্যমান নেই: উভয় পদ্ধতিই একটি নতুন লোডার তৈরি করবে যাতে কোনও পার্থক্য নেই
- আইডি সহ লোডার ইতিমধ্যে বিদ্যমান:
initLoader
কেবলমাত্র পরামিতি হিসাবে পাস করা কলব্যাকগুলি প্রতিস্থাপন করবে তবে লোডারটিকে বাতিল বা বন্ধ করবে না। এর জন্য CursorLoader
যেটির অর্থ দাঁড়ায় যে কার্সারটি খোলা এবং সক্রিয় থাকে (যদি initLoader
কলটির আগে এমনটি হত )। art অন্যদিকে, পুনঃসূচনা লোডার লোডারটি বাতিল, বন্ধ এবং ধ্বংস করবে (এবং কার্সারের মতো অন্তর্নিহিত ডেটা উত্সটি বন্ধ করবে) এবং একটি নতুন লোডার তৈরি করবে (যা একটি নতুন কার্সার তৈরি করে এবং কোয়েরিটি আবার চালাবে যদি লোডার থাকে একটি কার্সরলডার)।
উভয় পদ্ধতির জন্য এখানে সরলীকৃত কোড দেওয়া হয়েছে:
initLoader
LoaderInfo info = mLoaders.get(id);
if (info == null) {
// Loader doesn't already exist -> create new one
info = createAndInstallLoader(id, args, LoaderManager.LoaderCallbacks<Object>)callback);
} else {
// Loader exists -> only replace callbacks
info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
}
restartLoader
LoaderInfo info = mLoaders.get(id);
if (info != null) {
LoaderInfo inactive = mInactiveLoaders.get(id);
if (inactive != null) {
// does a lot of stuff to deal with already inactive loaders
} else {
// Keep track of the previous instance of this loader so we can destroy
// it when the new one completes.
info.mLoader.abandon();
mInactiveLoaders.put(id, info);
}
}
info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
আমরা দেখতে পাচ্ছি যে লোডারটির অস্তিত্ব নেই (তথ্য == নাল) উভয় পদ্ধতিই একটি নতুন লোডার তৈরি করবে (তথ্য = createAndInstallLoader (...))। যদি ইতিমধ্যে লোডারটি বিদ্যমান থাকে তবে initLoader
কেবলমাত্র কলব্যাকগুলি (তথ্য.এমক্যালব্যাকস = ...) প্রতিস্থাপন করে যখন restartLoader
পুরানো লোডারটিকে নিষ্ক্রিয় করে (নতুন লোডারটি কাজ শেষ করার পরে এটি ধ্বংস হয়ে যায়) এবং তারপরে একটি নতুন তৈরি করে।
এইভাবে বলা হয়েছে যে এটি কখন পরিষ্কার করতে হবে initLoader
এবং কখন ব্যবহার করতে হবে restartLoader
এবং কেন দুটি পদ্ধতির বোধগম্য হয়।
initLoader
একটি প্রারম্ভিক লোডার আছে তা নিশ্চিত করতে ব্যবহৃত হয়। যদি না থাকে তবে একটি নতুন তৈরি করা হয়, যদি ইতিমধ্যে এটি বিদ্যমান থাকে তবে এটি পুনরায় ব্যবহার করা হবে used আমরা সর্বদা এই পদ্ধতিটি ব্যবহার না করেই আমাদের একটি নতুন লোডার প্রয়োজন কারণ চালানোর ক্যোয়ারী পরিবর্তিত হয়েছে (কোনও অন্তর্নিহিত ডেটা নয় বরং আসল কোয়েরি যেমন একটি কার্সরলডার জন্য এসকিউএল স্টেটমেন্টের মতো), এক্ষেত্রে আমরা কল করব restartLoader
।
ভ্রমণ / অসম্পূর্ণ অংশ জীবনচক্র ব্যবহার করতে সিদ্ধান্ত বা অন্যান্য পদ্ধতি সঙ্গে কিছুই করার আছে (এবং এক-শটের ফ্ল্যাগ ব্যবহার কল ট্র্যাক রাখতে যেমন সাইমন প্রস্তাব দরকার নেই)! এই সিদ্ধান্তটি কেবলমাত্র একটি নতুন লোডারের "প্রয়োজন" এর উপর ভিত্তি করে করা হয়। আমরা যদি একইভাবে ব্যবহার initLoader
করি এমন ক্যোয়ারীটি চালাতে চাই, আমরা যদি ব্যবহার করি অন্য কোনও কোয়েরি চালাতে চাই restartLoader
।
আমরা সর্বদা ব্যবহার করতে পারি restartLoader
তবে তা অদক্ষ হবে। কোনও স্ক্রিন ঘোরানোর পরে বা যদি ব্যবহারকারী অ্যাপ থেকে সরে যায় এবং পরে একই ক্রিয়ায় ফিরে আসে আমরা সাধারণত একই ক্যোয়ারির ফলাফলটি দেখাতে চাই এবং তাই restartLoader
অযথা লোডারটিকে আবার তৈরি করতে হবে এবং অন্তর্নিহিত (সম্ভাব্য ব্যয়বহুল) কোয়েরি ফলাফলটি খারিজ করে দেবে।
লোড হওয়া ডেটা এবং সেই ডেটা লোড করার জন্য "ক্যোয়ারী" এর মধ্যে পার্থক্য বোঝা খুব গুরুত্বপূর্ণ। আসুন ধরে নেওয়া যাক আমরা আদেশগুলির জন্য একটি সারণী জিজ্ঞাসা করে একটি কার্সরলডার ব্যবহার করি। যদি সেই টেবিলটিতে কোনও নতুন অর্ডার যুক্ত করা হয় তবে নতুন আদেশটি আপডেট করতে এবং প্রদর্শন করতে UI কে অবহিত করতে কর্সরলডার অনকন্টচেনজড () ব্যবহার করে ( restartLoader
এই ক্ষেত্রে ব্যবহারের দরকার নেই )। আমরা যদি কেবল ওপেন অর্ডারগুলি প্রদর্শন করতে চাই তবে আমাদের একটি নতুন ক্যোয়ারী প্রয়োজন এবং আমরা restartLoader
নতুন ক্যোয়ারকে প্রতিবিম্বিত করে একটি নতুন কার্সরলডার ফেরত দিতে ব্যবহার করব ।
দুটি পদ্ধতির মধ্যে কিছু সম্পর্ক আছে কি?
তারা একটি নতুন লোডার তৈরি করার জন্য কোডটি ভাগ করে তবে কোনও লোডার ইতিমধ্যে উপস্থিত থাকলে তারা বিভিন্ন কাজ করে।
কলিং restartLoader
সবসময় কল করে initLoader
?
না, এটা কখনই করে না।
আমি ফোন restartLoader
না করে কল করতে পারি initLoader
?
হ্যাঁ.
initLoader
ডেটা রিফ্রেশ করার জন্য দু'বার কল করা কি নিরাপদ ?
initLoader
দু'বার কল করা নিরাপদ তবে কোনও ডেটা রিফ্রেশ হবে না।
আমি কখন দুজনের একটি ব্যবহার করব এবং কেন ?
উপরের আমার ব্যাখ্যাগুলির পরে এটি (আশাবাদী) পরিষ্কার হওয়া উচিত।
কনফিগারেশন পরিবর্তন
একটি লোডারম্যানেজার তার অবস্থাটি কনফিগারেশনের পরিবর্তনগুলি (ওরিয়েন্টেশন পরিবর্তনগুলি সহ) ধরে রাখে যাতে আপনি ভাবেন যে আমাদের করার কিছুই নেই। আবার চিন্তা কর...
প্রথমত, একটি লোডারম্যানেজার কলব্যাকগুলি ধরে রাখে না, সুতরাং আপনি যদি কিছু না করেন তবে আপনার কলব্যাক পদ্ধতিগুলিতে onLoadFinished()
এবং এর মতো কলগুলি পাবেন না এবং এটি সম্ভবত আপনার অ্যাপ্লিকেশনটি ভেঙে দেবে।
অতএব আমাদের initLoader
কলব্যাকের পদ্ধতিগুলি পুনরুদ্ধার করার জন্য কমপক্ষে কল করতে হবে ( restartLoader
এটি অবশ্যই সম্ভব)। ডকুমেন্টেশন পদ বলে:
কল করার সময় যদি কলারটি তার শুরু অবস্থায় থাকে এবং অনুরোধকৃত লোডারটি ইতিমধ্যে উপস্থিত থাকে এবং এর ডেটা উত্পন্ন করে থাকে, তবে সাথে সাথে কলব্যাক কল করা onLoadFinished(Loader, D)
হবে (এই ফাংশনের অভ্যন্তরে) [...]।
এর অর্থ আমরা যদি initLoader
কোনও ওরিয়েন্টেশন পরিবর্তনের পরে কল করি তবে আমরা onLoadFinished
এখনই একটি কল পেয়ে যাব কারণ ডেটা ইতিমধ্যে লোড হয়েছে (ধরে নেওয়া যায় যে পরিবর্তনের আগে এটি ছিল was যদিও এটি সরাসরি এগিয়ে শোনাচ্ছে তা জটিল হতে পারে (আমরা সকলেই অ্যান্ড্রয়েডকে ভালবাসি না ...)।
আমাদের দুটি ক্ষেত্রে পার্থক্য করতে হবে:
- হ্যান্ডলগুলি কনফিগারেশনটি নিজেই পরিবর্তিত হয়: সেট্রেটাইনইনস্ট্যান্স (সত্য) ব্যবহার করা বা ফ্যাক্টরটিতে সেই
android:configChanges
ট্যাগ হিসাবে একটি ক্রিয়াকলাপের ক্ষেত্রে এটি হ'ল । এই উপাদানগুলি যেমন একটি স্ক্রিন ঘোরানোর পরে একটি অনক্রিট কল গ্রহণ করবে না, সুতরাং initLoader/restartLoader
অন্য কলব্যাক পদ্ধতিতে (যেমন
onActivityCreated(Bundle)
:) কল করতে মনে রাখবেন
। লোডার (গুলি) আরম্ভ করার জন্য, লোডার আইডিগুলি সংরক্ষণ করতে হবে (উদাহরণস্বরূপ একটি তালিকায়)। কারণ উপাদানটি কনফিগারেশনের পরিবর্তনগুলি ধরে রাখা যায় আমরা বিদ্যমান লোডার আইডিগুলি এবং কলকে কেবল লুপ করতে পারি initLoader(loaderid,
...)
।
- কনফিগারেশনের পরিবর্তনগুলি নিজেই হ্যান্ডেল করে না: এক্ষেত্রে লোডারগুলি অনক্রিটে আরম্ভ করা যেতে পারে তবে আমাদের নিজে লোডার আইডিগুলি ধরে রাখতে হবে বা আমরা প্রয়োজনীয় initLoader / restartLoader কল করতে সক্ষম হব না।
outState.putIntegerArrayList(loaderIdsKey, loaderIdsArray)
আইডিকে যদি একটি অ্যারেলিস্টে সংরক্ষণ করা হয় তবে আমরা onSaveInstanceState এ একটি কাজ করব এবং আইডিকে onCreate এ পুনরুদ্ধার করব:
loaderIdsArray =
savedInstanceState.getIntegerArrayList(loaderIdsKey)
আমরা ইনক্লুডোডার কল করার আগে।
initLoader
(এবং সমস্ত কলব্যাকগুলি সমাপ্ত হয়ে থাকেন, লোডার নিষ্ক্রিয়) একটি ঘূর্ণনের পরে আপনিonLoadFinished
কলব্যাক পাবেন না তবে আপনি যদি ব্যবহার করেন তবেrestartLoader
কি করবেন?