পরিবর্তনীয় লাইভডেটে সেটওয়ালু () এবং পোস্টভ্যালু () এর পার্থক্য


115

দুটি উপায় যা পরিবর্তনের মান তৈরি করে MutableLiveData। তবে setValue()ও এর postValue()মধ্যে পার্থক্য কী MutableLiveData

আমি এর জন্য ডকুমেন্টেশন খুঁজে পাইনি।

এখানে MutableLiveDataঅ্যান্ড্রয়েডের ক্লাস রয়েছে।

package android.arch.lifecycle;

/**
 * {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.
 *
 * @param <T> The type of data hold by this instance
 */
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

উত্তর:


192

ডকুমেন্টেশনের ভিত্তিতে:

সেটভ্যালু () :

মান নির্ধারণ করে। যদি সক্রিয় পর্যবেক্ষক থাকে তবে মান তাদের কাছে প্রেরণ করা হবে। এই পদ্ধতিটি অবশ্যই মূল থ্রেড থেকে কল করা উচিত।

পোস্টভ্যালু () :

প্রদত্ত মান নির্ধারণের জন্য একটি মূল থ্রেডে একটি কার্য পোস্ট করুন। কোনও মূল থ্রেড কোনও পোস্ট কার্য সম্পাদন করার আগে আপনি যদি এই পদ্ধতিটি একাধিকবার কল করেন তবে কেবল শেষ মানটি প্রেরণ করা হবে।

সংক্ষেপে বলতে গেলে মূল পার্থক্যটি হ'ল:

setValue()মূল থ্রেড থেকে পদ্ধতিটি কল করতে হবে। তবে আপনার যদি ব্যাকগ্রাউন্ড থ্রেড থেকে কোনও মান নির্ধারণ করা প্রয়োজন, postValue()এটি ব্যবহার করা উচিত।


"কেবলমাত্র সর্বশেষ মানটি প্রেরণ করা হবে"। কোডটি পড়ে আমি এটি সম্পর্কে নিশ্চিত হতে পারি না। সুতরাং দেখে মনে হচ্ছে একবার প্রথম থ্রেডটি পোস্টভ্যালু () এর অভ্যন্তরীণ সিঙ্ক্রোনাইজড ব্লকে আঘাত করতে চলেছে, পরবর্তী সিপিইউ উইন্ডোটি সম্ভবত থ্রেড 2 কে দেওয়া যেতে পারে যা অন্য কোনও মান পোস্ট করছে। থ্রেড 2 এর পরে সিঙ্ক্রোনাইজড ব্লকটি সম্পূর্ণ করতে পারে এবং শিডিয়ুলার নিজেই চালানোর জন্য প্রথম থ্রেডটিকে একটি উইন্ডো দেয়। 2 এটি ইতিমধ্যে 2 টি থ্রেডটি কী লিখেছিল তা ওভাররাইট করে। এটা কি সম্ভব?
stdout

104

উপরের সমস্ত উত্তর সঠিক। তবে আরও একটি গুরুত্বপূর্ণ পার্থক্য। যদি আপনি postValue()এমন কোনও ক্ষেত্রটিতে কল করেন যার কোনও পর্যবেক্ষক নেই এবং তারপরে আপনি কল করেন তবে getValue()আপনি যে মানটি সেট করেছেন সেটি পাবেন না postValue()। সুতরাং আপনি যদি পর্যবেক্ষক ব্যাকগ্রাউন্ড থ্রেডে কাজ করেন তবে সাবধান হন।


4
আশা করি আমি ট্রিপল-আপভোট করতে পারতাম! এর উপর ভিত্তি করে, এটি setValue()সম্ভব হলে এটি ব্যবহার করা ভাল বলে মনে হয় এবং প্রয়োজনে সতর্কতার সাথে 'পোস্টওয়ালিউ ()' ব্যবহার করুন। ধন্যবাদ
জংলেদেব

4
না, এখানে কোনও "সেরা" উপায় নেই। আপনি যদি লাইভডাটা ব্যাকগ্রাউন্ড থ্রেড থেকে কাজ করেন তবে আপনার পোস্টভ্যালু ব্যবহার করা উচিত। এছাড়াও লাইফসাইকেল উপাদানগুলির সর্বশেষতম সংস্করণে এটি ঠিক করা হয়েছে ... সম্ভবত।
w201

"এছাড়াও লাইফসাইকেল উপাদানগুলির সর্বশেষতম সংস্করণে এটি ঠিক করা হয়েছে ... সম্ভবত probably" আপনার এ সম্পর্কে আরও কোনও তথ্য আছে? ধন্যবাদ
ক্রিস নেভিল

4
আমি কিছু পরীক্ষা করেছি এবং মনে হয় যে লিবের শেষ সংস্করণ সহ সবকিছু যেমনটি করা উচিত তেমন কাজ করে।
w201

আপনি কি আমাকে উপরের কংক্রিটলি কোডটি প্রদর্শন করতে পারেন? যদি ভিউমোডেলে, আমি কার্যকরভাবে, noObserveLiveData.postValue("sample")ক্রিয়াকলাপে, যখন আমি getValue ব্যবহার করি তখন viewModel.noObserveLiveData.getValueআপনার অর্থ কি আমি পোস্টভ্যালু () ("নমুনা") এ সেট করে রেখেছি এমন মান নয়?
kwmt

15

setValue()কলার থ্রেড থেকে সরাসরি বলা হয়, একযোগে পর্যবেক্ষককে অবহিত করে এবং LiveDataতত্ক্ষণাত মান পরিবর্তন করে। এটি কেবল মেইনথ্রেড থেকে কল করা যেতে পারে।
postValue()এই জাতীয় কিছু ভিতরে ব্যবহার করে new Handler(Looper.mainLooper()).post(() -> setValue()), তাই এটি মেইনথ্রেড setValueমাধ্যমে Handlerসঞ্চালিত হয়। এটি যে কোনও থ্রেড থেকে কল করা যেতে পারে।


11

setValue()

মান নির্ধারণ করে। যদি সক্রিয় পর্যবেক্ষক থাকে তবে মান তাদের কাছে প্রেরণ করা হবে।

এই পদ্ধতিটি অবশ্যই মূল থ্রেড থেকে কল করা উচিত

postValue

আপনার যদি ব্যাকগ্রাউন্ড থ্রেড থেকে কোনও মান সেট করতে হয় তবে আপনি ব্যবহার করতে পারেন postValue(Object)

প্রদত্ত মান নির্ধারণের জন্য একটি মূল থ্রেডে একটি কার্য পোস্ট করুন।

কোনও মূল থ্রেড কোনও পোস্ট কার্য সম্পাদন করার আগে আপনি যদি এই পদ্ধতিটি একাধিকবার কল করেন তবে কেবল শেষ মানটি প্রেরণ করা হবে।


6

এটি উপরের সমস্যার সরাসরি উত্তর নয়। সাগর এবং ডব্লু ২০১২ এর উত্তরগুলি দুর্দান্ত। তবে মিউটেবল লাইভডেটা জন্য ভিউমোডেলগুলিতে আমি থাম্বের একটি সহজ নিয়ম ব্যবহার করি:

private boolean isMainThread() {
    return Looper.myLooper() == Looper.getMainLooper();
}

private MutableLiveData<Boolean> mutVal = new MutableLiveData<>(false);
public LiveData<Boolean> getMutVal() { return this.mutVal;  }
public void setMutVal(boolean val) {
    if (isMainThread()) mutVal.setValue(val);
    else mutVal.postValue(val);
}

mutValআপনার পছন্দসই মানটি প্রতিস্থাপন করুন ।


ভাল লাগল, আমি এই পছন্দ করি কোটলিনে আমি একটি এক্সটেনশন তৈরি করেছি যা স্মার্ট আপডেটকে encapsulate করে তাই আমার অ্যাপ্লিকেশনটিতে অসংখ্য মান আপডেট একক, ধারাবাহিক কল।
19Craig

4

setValue()মূল থ্রেড থেকে পদ্ধতিটি কল করতে হবে। আপনার যদি ব্যাকগ্রাউন্ড থ্রেড থেকে কোনও মান সেট করতে হয় তবে আপনি ব্যবহার করতে পারেনpostValue()

আরও এখানে


0

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

সুতরাং এলডি দেখতে দেখতে:

LD {
   state (view_1, view_2, view_3 …),
   model_that_contains_data_of_all_views
}

এমন কয়েকটি দর্শন (ভিউ_1 এবং দর্শন 3) রয়েছে যা একটি ইভেন্ট হওয়ার সাথে সাথে আপডেট করতে হয়েছিল..আমার ঘটনা ঘটে যখন তাদের একই সময়ে জানানো উচিত। সুতরাং, আমি ফোন করেছি:

postData(LD(view_1, data))
postData(LD(view_2, data)

এটি আমরা জানি যে কারণে কাজ করবে না।

আমি যা বুঝতে পেরেছি তা হল মূলত একটি এলডি কেবলমাত্র একটি দৃষ্টিভঙ্গি উপস্থাপন করে। তারপরে কোনও সম্ভাবনা নেই যে আপনি পর পর দুবার পোস্টডেটা () কল করতে পারেন। এমনকি যদি আপনি কল করেন তবে পোস্ট ডেটা আপনার পক্ষে যেভাবে পরিচালনা করে তা হ'ল আপনিও প্রত্যাশা করবেন (দর্শনে আপনার জন্য সর্বশেষ ডেটা দেখানো হচ্ছে)। সবকিছু ঠিক জায়গায় পড়ে যায়।

একটি এলডি -> একটি দেখুন। পারফেক্ট

এক এলডি -> একাধিক দর্শন এখানে একটি প্রথম ব্যবহার হতে পারে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.