লোডারম্যানেজারে initLoader এবং পুনঃসূচনা লোডার মধ্যে পার্থক্য


129

এর initLoaderএবং restartLoaderকার্যকারিতাগুলির মধ্যে পার্থক্য সম্পর্কে আমি পুরোপুরি হারিয়েছি LoaderManager:

  • তাদের দুজনেরই একই স্বাক্ষর রয়েছে।
  • restartLoader এছাড়াও একটি লোডার তৈরি করে, যদি এটি বিদ্যমান না থাকে ("এই ম্যানেজারটিতে একটি নতুন শুরু হয় বা বিদ্যমান লোডার পুনরায় চালু করা হয়")।

দুটি পদ্ধতির মধ্যে কিছু সম্পর্ক আছে কি? কলিং restartLoaderসবসময় কল করে initLoader? আমি ফোন restartLoaderনা করে কল করতে পারি initLoader? initLoaderডেটা রিফ্রেশ করার জন্য দু'বার কল করা কি নিরাপদ ? আমি কখন দুজনের একটি ব্যবহার করব এবং কেন ?

উত্তর:


202

এই প্রশ্নের উত্তর দেওয়ার জন্য আপনাকে LoaderManagerকোডটি খনন করতে হবে । যদিও লোডারম্যানেজারের ডকুমেন্টেশন নিজেই যথেষ্ট পরিষ্কার নয় (বা এই প্রশ্নটি হবে না), বিমূর্ত লোডারম্যানেজারের একটি সাবক্লাস, লোডারম্যানেজারআইএমপিএল এর ডকুমেন্টেশন আরও বেশি আলোকিত করে তোলে।

initLoader

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

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

restartLoader

নির্দিষ্ট আইডির সাথে যুক্ত লোডারটিকে পুনরায় তৈরি করার জন্য কল করুন। যদি বর্তমানে এই আইডির সাথে কোনও লোডার যুক্ত থাকে তবে এটি বাতিল / বন্ধ / যথাযথ হিসাবে নষ্ট হয়ে যাবে। প্রদত্ত আর্গুমেন্ট সহ একটি নতুন লোডার তৈরি করা হবে এবং এর ডেটা একবার উপলভ্য হয়ে গেলে।

[...] এই ফাংশনটি কল করার পরে, এই আইডি সম্পর্কিত কোনও পূর্ববর্তী লোডারগুলি অবৈধ হিসাবে বিবেচিত হবে এবং আপনি তাদের কাছ থেকে কোনও ডেটা আপডেট পাবেন না updates

মূলত দুটি মামলা রয়েছে:

  1. আইডি সহ লোডার বিদ্যমান নেই: উভয় পদ্ধতিই একটি নতুন লোডার তৈরি করবে যাতে কোনও পার্থক্য নেই
  2. আইডি সহ লোডার ইতিমধ্যে বিদ্যমান: 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 যদিও এটি সরাসরি এগিয়ে শোনাচ্ছে তা জটিল হতে পারে (আমরা সকলেই অ্যান্ড্রয়েডকে ভালবাসি না ...)।

আমাদের দুটি ক্ষেত্রে পার্থক্য করতে হবে:

  1. হ্যান্ডলগুলি কনফিগারেশনটি নিজেই পরিবর্তিত হয়: সেট্রেটাইনইনস্ট্যান্স (সত্য) ব্যবহার করা বা ফ্যাক্টরটিতে সেই android:configChangesট্যাগ হিসাবে একটি ক্রিয়াকলাপের ক্ষেত্রে এটি হ'ল । এই উপাদানগুলি যেমন একটি স্ক্রিন ঘোরানোর পরে একটি অনক্রিট কল গ্রহণ করবে না, সুতরাং initLoader/restartLoaderঅন্য কলব্যাক পদ্ধতিতে (যেমন onActivityCreated(Bundle):) কল করতে মনে রাখবেন । লোডার (গুলি) আরম্ভ করার জন্য, লোডার আইডিগুলি সংরক্ষণ করতে হবে (উদাহরণস্বরূপ একটি তালিকায়)। কারণ উপাদানটি কনফিগারেশনের পরিবর্তনগুলি ধরে রাখা যায় আমরা বিদ্যমান লোডার আইডিগুলি এবং কলকে কেবল লুপ করতে পারি initLoader(loaderid, ...)
  2. কনফিগারেশনের পরিবর্তনগুলি নিজেই হ্যান্ডেল করে না: এক্ষেত্রে লোডারগুলি অনক্রিটে আরম্ভ করা যেতে পারে তবে আমাদের নিজে লোডার আইডিগুলি ধরে রাখতে হবে বা আমরা প্রয়োজনীয় initLoader / restartLoader কল করতে সক্ষম হব না।
    outState.putIntegerArrayList(loaderIdsKey, loaderIdsArray)আইডিকে যদি একটি অ্যারেলিস্টে সংরক্ষণ করা হয় তবে আমরা onSaveInstanceState এ একটি কাজ করব এবং আইডিকে onCreate এ পুনরুদ্ধার করব: loaderIdsArray = savedInstanceState.getIntegerArrayList(loaderIdsKey)আমরা ইনক্লুডোডার কল করার আগে।

: +1: একটি শেষ পয়েন্ট। আপনি যদি initLoader(এবং সমস্ত কলব্যাকগুলি সমাপ্ত হয়ে থাকেন, লোডার নিষ্ক্রিয়) একটি ঘূর্ণনের পরে আপনি onLoadFinishedকলব্যাক পাবেন না তবে আপনি যদি ব্যবহার করেন তবে restartLoaderকি করবেন?
ব্লুন্ডেল

ত্রুটিপূর্ণ. InitLoader পদ্ধতিটি ফিরে আসার পূর্বে onLoadFinished () পদ্ধতিটি কল করে (যদি লোডার শুরু হয় এবং ডেটা থাকে)। এটি আরও বিস্তারিতভাবে ব্যাখ্যা করতে আমি কনফিগারেশন পরিবর্তনগুলি সম্পর্কে একটি অনুচ্ছেদ যুক্ত করেছি।
ইমানুয়েল মোইকলিন 16'14

6
হ্যাঁ, আপনার উত্তর এবং @ অ্যালেক্সলউডের সংমিশ্রণটি পুরো চিত্র দেয়। আমি অনুমান করি অন্যের জন্য উত্তরটি হ'ল, আপনার কোয়েরিটি যদি স্থির থাকে তবে ডিগ্রোডারটি ব্যবহার করুন এবং আপনি যদি ক্যোয়ারীটি পরিবর্তন করতে চান তবে পুনরায় চালু করুন
ব্লুন্ডেল

1
এটি এটিকে সুন্দরভাবে তলব করে: "আপনার প্রশ্নটি যদি স্থির থাকে তবে ডিগ্রিলোডারটি ব্যবহার করুন এবং আপনি যদি কোয়েরিটি পরিবর্তন করতে চান তবে পুনরায় চালু করুন"
ইমানুয়েল মোইকলিন

1
@Mhd। তাহাওয়ী আপনি কলব্যাকগুলি পরিবর্তন করছেন না, আপনি কেবল সেদিকেই যান they স্ক্রিন ঘোরার পরে তাদের পুনরায় সেট করা দরকার কারণ অ্যান্ড্রয়েড মেমরি ফাঁস রোধ করতে এগুলি তাদের আশেপাশে রাখে না। যতক্ষণ না তারা সঠিক কাজ করেন ততক্ষণ এগুলিকে সেট করতে আপনি নির্দ্বিধায়।
ইমানুয়েল মোকলিন

46

initLoaderলোডার ইতিমধ্যে তৈরি হয়ে গেলে কল করা (এটি সাধারণত কনফিগারেশনের পরিবর্তনের পরে ঘটে থাকে, উদাহরণস্বরূপ) লোডার ম্যানেজারকে লোডারটির সাম্প্রতিক ডেটা onLoadFinishedঅবিলম্বে সরবরাহ করতে বলে। যদি লোডার ইতিমধ্যে তৈরি না হয়ে থাকে (যখন ক্রিয়াকলাপ / খণ্ডটি প্রথম প্রবর্তন করে, উদাহরণস্বরূপ) initLoaderলোডারম্যানেজারকে onCreateLoaderনতুন লোডার তৈরি করার জন্য কল করতে কল call

কলিং restartLoaderইতিমধ্যে বিদ্যমান লোডারটিকে ধ্বংস করে দেয় (পাশাপাশি এটি সম্পর্কিত কোনও বিদ্যমান ডেটা) এবং লোডারম্যানেজারকে onCreateLoaderনতুন লোডার তৈরি করতে এবং একটি নতুন লোড শুরু করার জন্য কল করতে বলে ।


ডকুমেন্টেশন এ সম্পর্কে খুব পরিষ্কার:

  • initLoaderনিশ্চিত করে যে কোনও লোডার আরম্ভ এবং সক্রিয় রয়েছে। যদি লোডার ইতিমধ্যে বিদ্যমান না থাকে তবে একটি তৈরি হয় এবং (যদি ক্রিয়াকলাপ / খণ্ডটি বর্তমানে চালু হয়) লোডার শুরু করে। অন্যথায় সর্বশেষ নির্মিত লোডারটি পুনরায় ব্যবহৃত হয়।

  • restartLoaderএই ম্যানেজারটিতে একটি নতুন লোড শুরু করে বা একটি বিদ্যমান লোডার পুনরায় চালু করে, এতে কলব্যাকগুলি নিবন্ধন করে এবং (যদি ক্রিয়াকলাপ / খণ্ডটি বর্তমানে শুরু হয়) এটি লোড করা শুরু করে। যদি একই আইডি সহ কোনও লোডার আগে শুরু করা হয় তবে নতুন লোডার এর কাজ শেষ করলে এটি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যাবে। পুরানো লোডারটি ধ্বংস হওয়ার আগে কলব্যাক বিতরণ করা হবে।


@ তোমনমনি আমার উত্তরে এর অর্থ কী তা আমি ব্যাখ্যা করেছি। আপনি কোন অংশ সম্পর্কে বিভ্রান্ত?
অ্যালেক্স লকউড

আপনি কেবল দস্তাবেজটিকে পুনঃস্থাপন করেছেন। তবে ডকটি কোনও পদ্ধতি কোথায় ব্যবহার করা উচিত এবং কেন এটিকে জগাখিচু করা উচিত তা সম্পর্কে কোনও ইঙ্গিত দেয় না। আমার অভিজ্ঞতায়, কেবল রিস্টার্টলুডারকে কল করা এবং কখনই ইনফোলেডারকে কল করা ভাল কাজ করে না। সুতরাং এটি এখনও বিভ্রান্তিকর।
টম আনমনি

3
@TomanMoney সাধারণত আপনি ব্যবহার initLoader()মধ্যে onCreate()/ onActivityCreated()যখন কার্যকলাপ / টুকরা প্রথমে শুরু হয়। এইভাবে, যখন ব্যবহারকারী প্রথমে কোনও ক্রিয়াকলাপ খুলবে, লোডার প্রথমবারের জন্য তৈরি করা হবে ... তবে পরবর্তী কোনও কনফিগারেশন পরিবর্তনে যেখানে পুরো ক্রিয়াকলাপ / খণ্ডটি ধ্বংস করতে initLoader()হবে , নিম্নলিখিত কলটি Loaderপরিবর্তে কেবল পুরানোটি ফিরিয়ে দেবে একটি নতুন তৈরি। সাধারণত আপনি restartLoader()যখন আপনার Loaderপ্রশ্নের ক্যোয়ার পরিবর্তন করতে চান (তখন আপনি ফিল্টার / সাজানো ডেটা ইত্যাদি পেতে চান) ব্যবহার করেন।
অ্যালেক্স লকউড

4
আমি এখনও দুটি পদ্ধতি থাকার এপিআই সিদ্ধান্ত সম্পর্কে বিভ্রান্ত, কারণ তাদের স্বাক্ষর একই। কেন এপিআই একক স্টার্টলোডার () পদ্ধতি হতে পারে না যা প্রতিবার "সঠিক জিনিস" করে? আমি মনে করি এটি সেই অংশ যা অনেক লোককে বিভ্রান্ত করে।
টম আনমনি

1
@ তোমানমনি ডকুমেন্টেশনটি এখানে বলেছে: developer.android.com/guide/components/loaders.html । "একটি কনফিগারেশন পরিবর্তনের পরে পুনরায় তৈরি করার সময় এগুলি স্বয়ংক্রিয়ভাবে শেষ লোডার কার্সারের সাথে পুনরায় সংযোগ স্থাপন করে Thus সুতরাং তাদের তাদের ডেটা পুনরায় জিজ্ঞাসা করার দরকার নেই।"
ইগরগানাপলস্কি

16

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

onCreate: call initLoader(s)
          set a one-shot flag
onResume: call restartLoader (or later, as applicable) if the one-shot is not set.
          unset the one-shot in either case.

(অন্য কথায়, কিছু পতাকা যাতে সেট initLoader হয় সবসময় একবার & যে restartLoader চালানো হয় চালানো 2nd & পরবর্তী পাস মাধ্যমে onResume )

এছাড়াও, ক্রিয়াকলাপের মধ্যে আপনার প্রতিটি লোডারের জন্য বিভিন্ন আইডির বরাদ্দ করতে ভুলবেন না (যদি আপনি নিজের নম্বর দেওয়ার বিষয়ে সাবধান না হন তবে সেই ক্রিয়াকলাপের মধ্যে টুকরো টুকরো হয়ে যাওয়ার বিষয়টি কিছুটা হতে পারে)


আমি কেবল ইনডলোডার ব্যবহার করার চেষ্টা করেছি .... কার্যকরভাবে কাজ করছে বলে মনে হচ্ছে না।

চেষ্টা করা হয়েছে initLoader উপর onCreate নাল args সঙ্গে (ডক্স বলে এই ঠিক আছে) & restartLoader মধ্যে (বৈধ args সঙ্গে) onResume .... ডক্স ভুল & initLoader একটি nullpointer ব্যতিক্রম ছোঁড়ার।

কেবলমাত্র পুনঃসূচনা লোডার চেষ্টা করা হয়েছে ... কিছুক্ষণের জন্য কাজ করে তবে 5 বা 6 তম স্ক্রিনটির পুনরায় দৃষ্টিভঙ্গিতে ফুঁক দেয়

চেষ্টা করা হয়েছে initLoader মধ্যে onResume ; আবার কিছুক্ষণের জন্য কাজ করে & (বিশেষত "যখন শুরু করা হবে না তখন ডলিটেন বলা হবে:" ... ত্রুটি)

নিম্নলিখিতগুলি চেষ্টা করে দেখুন: (একটি কভার ক্লাসের অংশ যা লোডার আইডিটি কনস্ট্রাক্টরে প্রবেশ করেছে)

/**
 * start or restart the loader (why bother with 2 separate functions ?) (now I know why)
 * 
 * @param manager
 * @param args
 * @deprecated use {@link #restart(LoaderManager, Bundle)} in onResume (as appropriate) and {@link #initialise(LoaderManager, Bundle)} in onCreate 
 */
@Deprecated 
public void start(LoaderManager manager, Bundle args) {
    if (manager.getLoader(this.id) == null) {
        manager.initLoader(this.id, args, this);
    } else {
        manager.restartLoader(this.id, args, this);
    }
}

(যা আমি কোথাও স্ট্যাক-ওভারফ্লোতে পেয়েছি)

আবার এটি কিছুক্ষণের জন্য কাজ করেছে তবে এখনও মাঝে মাঝে ভুলত্রুটি ফেলে দিয়েছে।


ডিবাগ করার সময় আমি যা বুঝতে পারি তা থেকে, আমি মনে করি সেভ / রিস্টোর ইন্সট্যান্স স্টেটের সাথে কিছু করার দরকার আছে যা চক্রের একটি স্পিন থেকে বেঁচে থাকতে হলে লাইফসাইকেলের অনক্রিট অংশে initLoader (/ s) চালানো দরকার requires । ( আমার ভুল হতে পারে.)

পরিচালকের যে শুরু করা যাবে না যতক্ষণ না ফলাফল অন্য পরিচালক অথবা টাস্ক থেকে ফিরে আসা ক্ষেত্রে (যেমন। এ ইনিশিয়ালাইজ করা যাবে না onCreate ), আমি শুধু ব্যবহার initLoader । (আমি এটিতে সঠিক নাও হতে পারি তবে এটি কাজ করছে বলে মনে হচ্ছে These এই মাধ্যমিক লোডারগুলি তাত্ক্ষণিক উদাহরণ-রাজ্যের অংশ নয় তাই ইনিগ্রোডার ব্যবহার করে বাস্তবে এই ক্ষেত্রে সঠিক হতে পারে)

জীবনচক্র


ডায়াগ্রাম এবং ডকসটি দেখে, আমি ভেবেছিলাম যে ইনক্রিটিউটের জন্য আরআরলডারটি অনক্রিট এবং পুনরায় চালু করতে হবে তবে এটি কিছু আলাদা প্যাটার্ন ব্যবহার করে টুকরো টুকরো টুকরো করে ফেলেছে এবং এটি আসলে স্থিতিশীল কিনা তা খতিয়ে দেখার সময় আমার হাতে নেই। ক্রিয়াকলাপগুলির জন্য এই প্যাটার্ন দিয়ে সাফল্য পেলে অন্য কেউ মন্তব্য করতে পারেন?


/ @ সাইমন 100% সঠিক এবং এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। আমি তার উত্তরে যথেষ্ট বিশ্বাস করি না এবং বেশ কয়েক ঘন্টা এই কাজটি করার বিভিন্ন উপায় খুঁজতে চেষ্টা করেছিলাম। আমি যখনই ইল্ডোডারকে কলটি অনির্তে স্থানান্তরিত করলাম তখন কাজ শুরু করল। তারপরে
অন ​​স্টার্ট

2
"শুধুমাত্র পুনরায় চালু হওয়া লোডার চেষ্টা করা হয়েছে ... কিছুক্ষণের জন্য কাজ করে তবে 5 বা 6 তম স্ক্রিনটির পুনরায় দৃষ্টিভঙ্গিতে ফুঁক দেয়" " এটা করে? আমি কেবল এটি চেষ্টা করেছিলাম এবং একশ বার স্ক্রিনটি ঘোরালাম এবং কোনও ফলস্বরূপ পাইনি। আপনি কি ধরনের ব্যতিক্রম পাচ্ছেন?
টম আনমনি

-1 আমি এই উত্তরের পিছনে গবেষণা প্রচেষ্টার প্রশংসা করি তবে বেশিরভাগ ফলাফলই ভুল।
ইমানুয়েল মেকলিন 4'14

1
@ ইগরগানাপলস্কি প্রায় সব কিছু। আপনি যদি আমার উত্তরটি পড়েন এবং বুঝতে পারবেন তবে আপনি বুঝতে পারবেন যে ইনডিলোডার এবং রিস্টার্টলয়েডার কী করবে এবং কখন কখন ব্যবহার করবে এবং আপনিও বুঝতে পারবেন কেন সিমনের প্রায় সমস্ত সিদ্ধান্তে ভুল wrong কোনও খণ্ড / ক্রিয়াকলাপের জীবনচক্র এবং ইনিগ্রোডার / রিস্টার্টলোডার ব্যবহার করার সিদ্ধান্তের (কনফিগারেশনের পরিবর্তনের অধীনে আমি যে ক্যাভিয়েট দিয়েছি) সাথে কোনও সংযোগ নেই। সাইমন বিচার ও ত্রুটি থেকে শেষ করেছেন যে জীবনচক্র দুটি পদ্ধতি বোঝার সূত্র কিন্তু এটি তা নয়।
ইমানুয়েল মোইকলিন

@ ইগোরগানাপলস্কি আমি নিজের উত্তরের বিজ্ঞাপন দেওয়ার চেষ্টা করছি না। আমি কেবল অন্য বিকাশকারীদের সাহায্য করার চেষ্টা করছি এবং তাদের নিজস্ব অ্যাপ্লিকেশনের জন্য সাইমন এর ফলাফল ব্যবহার থেকে বিরত রাখতে। একবার আপনি দুটি পদ্ধতি কী বোঝাতে চেয়েছেন তা বোঝার পরে পুরো বিষয়টি মোটামুটি সুস্পষ্ট এবং বাস্তবায়নের জন্য সরাসরি এগিয়ে যায়।
ইমানুয়েল মোইকলিন

0

initLoaderলোডার ইতিমধ্যে বিদ্যমান থাকলে একই পরামিতিগুলি পুনরায় ব্যবহার করবে। পুরানো ডেটা ইতিমধ্যে লোড করা থাকলে তা অবিলম্বে ফিরে আসে, আপনি নতুন প্যারামিটার দিয়ে কল করলেও। লোডারটি আদর্শভাবে নতুন ডেটার ক্রিয়াকলাপটি স্বয়ংক্রিয়ভাবে অবহিত করে। যদি স্ক্রিনটি ঘোরানো হয়, initLoaderআবার কল করা হবে এবং পুরানো ডেটা অবিলম্বে প্রদর্শিত হবে।

restartLoaderআপনি যখন পুনরায় লোড করতে এবং প্যারামিটারগুলিও পরিবর্তন করতে চান তখন এর জন্য। আপনি যদি লোডারগুলি ব্যবহার করে কোনও লগইন স্ক্রিন তৈরি করতে চান তবে restartLoaderপ্রতিটি সময় বোতামটি ক্লিক করার সময় আপনি কল করবেন । (ভুল শংসাপত্র ইত্যাদির কারণে বোতামটি একাধিকবার ক্লিক করা যেতে পারে)। আপনি initLoaderযখনই লগইন প্রক্রিয়া চলাকালীন পর্দাটি ঘোরানো ইভেন্টের ক্রিয়াকলাপের সংরক্ষিত উদাহরণ স্থিতি পুনরুদ্ধার করবেন তখনই আপনি কল করবেন ।


-1

যদি লোডার ইতিমধ্যে বিদ্যমান থাকে তবে পুনঃসূচনা লোডারটি পুরানোটিকে বন্ধ / বাতিল / ধ্বংস করবে, যখন initLoader প্রদত্ত কলব্যাকের সাহায্যে এটিকে আরম্ভ করবে। এই ক্ষেত্রে পুরানো কলব্যাকগুলি কী করে তা আমি খুঁজে পেতে পারি না তবে আমি অনুমান করি যে তারা কেবল পরিত্যক্ত হবে।

আমি http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/LoaderManager.java- এর মাধ্যমে স্ক্যান করেছি তবে সঠিকটি আমি খুঁজে পাই না পার্থক্য হ'ল পদ্ধতিগুলি বিভিন্ন কাজ করে। সুতরাং আমি বলব, প্রথমবার initLoader ব্যবহার করুন এবং নিম্নলিখিত সময়ের জন্য পুনরায় চালু করুন, যদিও তাদের প্রত্যেকে ঠিক কী করবে তা আমি নিশ্চিত করে বলতে পারি না।


এবং initLoaderএই ক্ষেত্রে কি করবে ?
থিওমেগা

-1

প্রথম শুরুতে ইনিশ লোডার লোডইনব্যাকগ্রাউন্ড () পদ্ধতিটি ব্যবহার করে, দ্বিতীয় শুরুতে এটি বাদ দেওয়া হবে। সুতরাং, আমার মতে, আরও ভাল সমাধান হ'ল:

Loader<?> loa; 
try {
    loa = getLoaderManager().getLoader(0);
} catch (Exception e) {
    loa = null;
}
if (loa == null) {
    getLoaderManager().initLoader(0, null, this);
} else {
    loa.forceLoad();
}

////////////////////////////////////////////////// /////////////////////////

protected SimpleCursorAdapter mAdapter;

private abstract class SimpleCursorAdapterLoader 
    extends AsyncTaskLoader <Cursor> {

    public SimpleCursorAdapterLoader(Context context) {
        super(context);
    }

    @Override
    protected void onStartLoading() {
        if (takeContentChanged() || mAdapter.isEmpty()) {
            forceLoad();
        }
    }

    @Override
    protected void onStopLoading() {
        cancelLoad();
    }

    @Override
    protected void onReset() {
        super.onReset();
        onStopLoading();
    }
}

আমি এই সমাধানটি খুঁজে পেতে অনেক সময় ব্যয় করেছি - পুনঃসূচনা লোডার (...) আমার ক্ষেত্রে সঠিকভাবে কাজ করে নি। একমাত্র ফোর্সলোড () কলব্যাক ছাড়াই পূর্ববর্তী লোডিং থ্রেডটি শেষ করতে দেয় (যাতে আপনার সমস্ত ডিবি লেনদেন সঠিকভাবে শেষ হয়ে যায়) এবং আবার নতুন থ্রেড শুরু হয়। হ্যাঁ, এটি কিছু অতিরিক্ত সময় দাবি করে, তবে এটি আরও স্থিতিশীল। শুধুমাত্র শেষ শুরু হওয়া থ্রেড কলব্যাক নেবে। সুতরাং, আপনি যদি আপনার ডিবি লেনদেনের মধ্যে বাধা দিয়ে পরীক্ষা করতে চান - আপনার স্বাগতম, পুনরায় চালু করার চেষ্টা করুন লোডার (...), অন্যথায় জোরপূর্বক লোড ()। রিস্টার্টলডার (...) এর একমাত্র সুবিধাই হল নতুন প্রাথমিক ডেটা সরবরাহ করা, মানে পরামিতি। এবং দয়া করে এক্ষেত্রে উপযুক্ত টুকরাটির onDetach () পদ্ধতিতে লোডারটি ধ্বংস করতে ভুলবেন না। এছাড়াও মনে রাখবেন, যে আপনার যখন কোনও ক্রিয়াকলাপ হয় এবং কিছু সময় তাদের বলে দেয়, লোডার সহ প্রতিটি অন্তর্ভুক্ত ক্রিয়াকলাপের সাথে 2 টি টুকরো - আপনি কেবল 2 লোডার পরিচালককে পৌঁছাতে পারেন, তাই ক্রিয়াকলাপ লোডিংয়ের সময় স্ক্রিনে দেখানো ফ্র্যাগমেন্ট (গুলি) এর সাথে তার লোডারম্যানেজারটি ভাগ করে। LoaderManager.enableDebugLogging (সত্য) চেষ্টা করুন; প্রতিটি নির্দিষ্ট ক্ষেত্রে বিশদ দেখতে।


2
-1 থেকে কল মোড়কে জন্য getLoader(0)একটি try { ... } catch (Exception e) { ... }
অ্যালেক্স লকউড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.