অ্যান্ড্রয়েড এমভিভিএম ভিউমোডেলে কনটেক্সট কীভাবে পাবেন


96

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


যদি কেউ ব্যবহার করার চেষ্টা করছে AndroidViewModelকিন্তু পেয়ে Cannot create instance exceptionতারপর তুমি আমার এই উত্তর পাঠাতে পারেন stackoverflow.com/a/62626408/1055241
gprathour

আপনার ভিউমোডেলে কনটেক্সট ব্যবহার করা উচিত নয়, সেই উপায় থেকে প্রসঙ্গটি পেতে তার পরিবর্তে একটি ইউজকেস তৈরি করা উচিত
রুবেন কাস্টার

উত্তর:


78

আপনি Applicationপ্রদত্ত একটি প্রসঙ্গ ব্যবহার করতে পারেন AndroidViewModel, আপনার প্রসারিত হওয়া উচিত AndroidViewModelযা কেবল ViewModelএকটি Applicationরেফারেন্স অন্তর্ভুক্ত করে ।


মোহন মত কাজ!
এসপিএম

63

অ্যান্ড্রয়েড আর্কিটেকচার উপাদানগুলির জন্য মডেল দেখুন,

আপনার ক্রিয়াকলাপের প্রসঙ্গটি ক্রিয়াকলাপের ভিউমোডেলের কাছে এটিকে একটি স্মৃতি ফাঁস হিসাবে পাস করা ভাল অনুশীলন নয়।

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

class ActivityViewModel(application: Application) : AndroidViewModel(application) {

    private val context = getApplication<Application>().applicationContext

    //... ViewModel methods 

}

4
অ্যাপ্লিকেশন প্যারামিটার এবং একটি সাধারণ ভিউমোডেল সরাসরি ব্যবহার করবেন না কেন? আমি "get অ্যাপ্লিকেশন <অ্যাপ্লিকেশন> ()" এর কোনও বিন্দু দেখতে পাচ্ছি না। এটি কেবল বয়লারপ্লেট যুক্ত করে।
অবিশ্বাস্য জানুয়ারী

কেন এটি একটি স্মৃতি ফাঁস হবে?
বেন বাটারওয়ার্থ

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

52

টেস্টিং সহজ করার জন্য ভিউমোডেলগুলিতে অ্যান্ড্রয়েড নির্দিষ্ট কোড থাকা উচিত নয়, কারণ এটি বিমূর্ততা যা পরীক্ষাকে সহজ করে তোলে।

ভিউমোডেলগুলিতে প্রসঙ্গের উদাহরণ বা কনটেক্সটে থাকা ভিউ বা অন্যান্য অবজেক্টের মতো কিছু না থাকার কারণ হ'ল এটির ক্রিয়াকলাপ এবং খণ্ডগুলির চেয়ে পৃথক একটি জীবনচক্র রয়েছে।

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

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

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


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

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

4
যদি আমি কোনও মান ফর্ম ভিউ মডেলের উপর ভিত্তি করে পাঠ্যদর্শনটিতে টেক্সটটি টগল করতে চাই তবে স্ট্রিংটির স্থানীয়করণ করা দরকার, সুতরাং আমার ভিউমডেলে সংস্থানগুলি পাওয়া দরকার, প্রসঙ্গ ছাড়াই আমি কীভাবে সংস্থানগুলি অ্যাক্সেস করব?
শ্রুতি রায়

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

4
@ পেসারিয়র আপনি ভিউমোডেলের মূল উদ্দেশ্যটি ভুল বুঝে গেছেন। এটি উদ্বেগ ইস্যু একটি বিচ্ছেদ। ভিউমোডেলটিতে কোনও মতামতের রেফারেন্স রাখা উচিত নয়, যেহেতু দায় স্তর দ্বারা প্রদর্শিত হচ্ছে এমন ডেটা বজায় রাখা তার দায়িত্ব responsibility ইউআই উপাদানগুলি, ওরফে দর্শনগুলি ভিউ স্তর দ্বারা রক্ষণাবেক্ষণ করা হয় এবং অ্যান্ড্রয়েড সিস্টেম প্রয়োজনীয় হলে ভিউগুলি পুনরায় তৈরি করবে। পুরানো ভিউয়ের রেফারেন্স রাখা এই আচরণের সাথে দ্বন্দ্ব সৃষ্টি করবে এবং মেমরি ফাঁসের কারণ হবে।
জ্যাকি

16

সংক্ষিপ্ত উত্তর - এটি করবেন না

কেন?

এটি দেখার মডেলগুলির পুরো উদ্দেশ্যকে পরাস্ত করে

মডেল দর্শনে আপনি যা করতে পারেন তার প্রায় প্রতিটি কাজ লাইভডেটা ইনস্ট্যান্স এবং অন্যান্য বিভিন্ন প্রস্তাবিত পদ্ধতির মাধ্যমে ক্রিয়াকলাপ / খণ্ডে করা যেতে পারে।


26
তাহলে অ্যান্ড্রয়েডভিউমোডেল ক্লাসটি কেন বিদ্যমান?
অ্যালেক্স বার্ডনিকভ

4
@ অ্যালেক্সবার্ডনিকভ এমভিভিএমের উদ্দেশ্য ভিউমোডেল থেকে ভিভি (ক্রিয়াকলাপ / অংশবিশেষ) কে এমভিপি এর চেয়েও বেশি আলাদা করা। যাতে এটি পরীক্ষা করা আরও সহজ হবে।
3x_voice

4
@ ফ্রি_স্টাইল স্পষ্টকরণের জন্য ধন্যবাদ, তবে প্রশ্নটি এখনও দাঁড়িয়েছে: যদি আমাদের ভিউমোডেলে প্রসঙ্গটি রাখা না হয় তবে অ্যান্ড্রয়েডভিউমোডেল শ্রেণি কেন বিদ্যমান? এর পুরো উদ্দেশ্যটি অ্যাপ্লিকেশন প্রসঙ্গ সরবরাহ করা, তাই না?
অ্যালেক্স বার্ডনিকভ

7
@ অ্যালেক্সবার্ডনিকভ ভিউ মডেলের অভ্যন্তরে ক্রিয়াকলাপ প্রসঙ্গ ব্যবহার করা স্মৃতি ফাঁসির কারণ হতে পারে। সুতরাং অ্যান্ড্রয়েডভিউমোডেল ক্লাস ব্যবহার করে আপনাকে অ্যাপ্লিকেশন প্রসঙ্গ সরবরাহ করবে যা কোনভাবেই মেমরি ফাঁসের কারণ হবে না (আশা করি)। সুতরাং অ্যান্ড্রয়েডভিউমোডেল ব্যবহার করা এতে ক্রিয়াকলাপের প্রসঙ্গটি পাস করার চেয়ে ভাল। তবে তবুও এটি করা পরীক্ষাটি কঠিন করে তুলবে। এটি আমার নিন।
3x_voice

4
আমি সংগ্রহস্থল থেকে রেজ / কাঁচা ফোল্ডার থেকে ফাইল অ্যাক্সেস করতে পারি না?
ফুগোগোগো

15

ভিউমোডলে সরাসরি কনটেক্সট করার পরিবর্তে আমি কী শেষ করেছি, আমি রিসোর্সপ্রাইভাইডারের মতো সরবরাহকারী শ্রেণি তৈরি করেছি যা আমাকে আমার প্রয়োজনীয় সংস্থানগুলি দেবে এবং আমার ভিউমোডেলটিতে সেই সরবরাহকারী ক্লাসগুলি injুকিয়ে দিয়েছিল


4
আমি অ্যাপমোডুলে ডাগারের সাথে রিসোর্সপ্রোভাইডার ব্যবহার করছি। রিসোর্সসপ্রোভাইডার বা অ্যান্ড্রয়েডভিউমোডেল প্রসঙ্গে ফিরে আসার পক্ষে কি সেই ভাল পদ্ধতির জন্য রিসোর্সের প্রসঙ্গটি আরও ভাল?
উসমান রানা

@ ভিনসেন্ট: ভিউমোডেলের ভিতরে ড্রয়যোগ্য পেতে কীভাবে রিসোর্সপ্রোভাইডার ব্যবহার করবেন?
বুলমা

@ ভেজেটা আপনি রিসোর্সপ্রাইডার getDrawableRes(@DrawableRes int id)শ্রেণীর ভিতরে যেমন একটি পদ্ধতি যুক্ত করবেন
ভিনসেন্ট উইলিয়ামস

4
এটি ক্লিন আর্কিটেকচার পদ্ধতির বিপরীতে যায় যা বলে যে ফ্রেমওয়ার্ক নির্ভরতা ডোমেন লজিকের (ভিউমোডেলস) সীমানা অতিক্রম করবে না।
ইগোরগানাপলস্কি 21

4
@ আইগরগানাপলস্কি ভিএমগুলি ঠিক ডোমেন লজিক নয়। ডোমেন লজিক অন্যান্য শ্রেণি যেমন ইন্টারেক্টর এবং কয়েকটি নাম সংগ্রহের জন্য সংগ্রহস্থল। ভিএমগুলি "আঠালো" বিভাগে আসে কারণ তারা আপনার ডোমেনের সাথে ইন্টারঅ্যাক্ট করে তবে সরাসরি তা নয়। যদি আপনার ভিএমগুলি আপনার ডোমেনের অংশ হয় তবে আপনি কীভাবে প্যাটার্নটি ব্যবহার করছেন সেগুলি আপনি কীভাবে ব্যবহার করছেন সেগুলি নিয়ে আপনার পুনর্বিবেচনা করা উচিত।
mradzinski

9

টিএল; ডিআর: আপনার ভিউমোডেলসে ডাগারের মাধ্যমে অ্যাপ্লিকেশনটির প্রসঙ্গটি ইনজেক্ট করুন এবং এটি সংস্থানগুলি লোড করতে ব্যবহার করুন। আপনার যদি চিত্রগুলি লোড করতে হয়, ডেটাবাইন্ডিং পদ্ধতিগুলি থেকে তর্কগুলি দিয়ে ভিউ উদাহরণটি পাস করুন এবং সেই দৃশ্য প্রসঙ্গে ব্যবহার করুন।

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

বলা হচ্ছে, আপনার নির্দিষ্ট সমস্যার সাথে আমার পদ্ধতির ডিআইয়ের মাধ্যমে আমার স্ট্রিং.এক্সএমএল থেকে স্ট্রিংয়ের মতো জিনিস পেতে আমার ভিউমোডেলগুলিতে ব্যবহারের জন্য অ্যাপ্লিকেশনটির প্রসঙ্গটি উপলব্ধ রয়েছে is

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

আশা করি এটা সাহায্য করবে!


4
টিএল; ডিআর শীর্ষে থাকা উচিত
জ্যাক কুর্টস

4
আপনার উত্তর করার জন্য আপনাকে ধন্যবাদ। তবে, আপনি যদি নিজের ভিউ মডেলটি অ্যান্ড্রয়েডভিউ মডেল থেকে প্রসারিত করতে এবং শ্রেণি নিজেই সরবরাহ করেন এমন বিল্টিন প্রসঙ্গটি ব্যবহার করতে পারেন তবে আপনি কেন প্রসঙ্গটি ইনজেক্ট করতে ডাগার ব্যবহার করবেন? বিশেষত ডগার এবং এমভিভিএম একসাথে কাজ করতে বয়লারপ্লেট কোডের হাস্যকর পরিমাণ বিবেচনা করে অন্য সমাধানটি আরও পরিষ্কার ইমো বলে মনে হচ্ছে। এ ব্যাপারে আপনার চিন্তা - ভাবনা কি?
জোসিপ দোমাজেট

8

যেমনটি অন্যরা উল্লেখ করেছেন, AndroidViewModelঅ্যাপটি পেতে আপনি যা পেতে পারেন Contextকিন্তু আমি যে মন্তব্যগুলিতে জড়ো করি তা থেকে আপনি নিজের @drawableমধ্যে থেকে গুলি ViewModelচালনার চেষ্টা করছেন যা উদ্দেশ্য এমভিভিএমকে পরাস্ত করে।

সাধারণত, একটি থাকতে হবে Contextআপনার ViewModelপ্রায় সর্বজনীন প্রস্তাব দেওয়া আপনি ভান্ডারের চিন্তা বিবেচনা করা উচিত কিভাবে আপনি আপনার মধ্যে যুক্তিবিজ্ঞান ভাগ Views এবং ViewModels

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

এটি ডেটাবাইন্ডিংয়ের মাধ্যমে বেশ সহজভাবে করা যেতে পারে :

<ImageView
...
app:src="@{viewModel.isOn ? @drawable/switch_on : @drawable/switch_off}"
/>

আপনার যদি আরও রাজ্য এবং আঁকতে সক্ষম হয় তবে বিন্যাস ফাইলে অযৌক্তিক যুক্তি এড়াতে আপনি একটি কাস্টম বাইন্ডিংএডাপ্টার লিখতে পারেন যা অনুবাদ করে বলতে পারেন, একটি Enumমান R.drawable.*(যেমন কার্ড স্যুট)

অথবা হয়ত আপনি প্রয়োজন Contextকিছু জন্য আপনি যে উপাদানটি মধ্যে ব্যবহারের জন্য আপনার ViewModel- তারপর, বাহিরে উপাদান তৈরি ViewModelকরুন এবং এটা পাস আপনি দ্বি, অথবা singletons ব্যবহার করতে পারেন, বা তৈরি করুন। ContextInitialising আগে -dependent উপাদান অধিকার ViewModelমধ্যে Fragment/ Activity

কেন বিরক্ত হবে: Contextএকটি অ্যান্ড্রয়েড-নির্দিষ্ট জিনিস, এবং ViewModelএর মধ্যে থাকা তাদের উপর নির্ভর করা একটি খারাপ অভ্যাস: তারা ইউনিট পরীক্ষার পথে দাঁড়ায়। অন্যদিকে, আপনার নিজস্ব উপাদান / পরিষেবা ইন্টারফেস পুরোপুরি আপনার নিয়ন্ত্রণে রয়েছে যাতে আপনি পরীক্ষার জন্য তাদের সহজেই উপহাস করতে পারেন।


5

অ্যাপ্লিকেশন প্রসঙ্গে একটি রেফারেন্স রয়েছে, তবে এতে অ্যান্ড্রয়েড নির্দিষ্ট কোড রয়েছে

সুসংবাদ, আপনি Mockito.mock(Context.class)পরীক্ষাগুলিতে যা যা চান প্রসঙ্গটি ব্যবহার করতে পারেন এবং ফিরে আসতে পারেন!

আপনি কেবল ViewModelযেমনটি ব্যবহার করেন ঠিক তেমন একটি ব্যবহার করুন এবং আপনার ভিউমোডেলপ্রভাইডার্সের মাধ্যমে এপ্লিকেশন কনটেক্সটটি দিন।


3

আপনি getApplication().getApplicationContext()ভিউমোডেল থেকে অ্যাপ্লিকেশন প্রসঙ্গটি অ্যাক্সেস করতে পারেন । এটি আপনার প্রয়োজনীয় সংস্থানসমূহ, পছন্দগুলি ইত্যাদিতে অ্যাক্সেস করার প্রয়োজন ..


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

14
ViewModelশ্রেণী নেই getApplicationপদ্ধতি।
বেরোয়াল

4
না, তবে AndroidViewModelকরেন
ওহ 4

4
তবে আপনার অ্যাপ্লিকেশন উদাহরণটি তার নির্মাণকারীটিতে পাস করতে হবে, এটি থেকে অ্যাপ্লিকেশন উদাহরণটি অ্যাক্সেস করার মতোই
জন সার্ডিনহা

4
অ্যাপ্লিকেশন প্রসঙ্গে থাকা এটি কোনও বড় সমস্যা করে না। আপনার কোনও ক্রিয়াকলাপ / খণ্ড প্রসঙ্গ থাকতে চান না কারণ আপনি যদি বিরক্ত হয়ে থাকেন তবে যদি খণ্ড / ক্রিয়াকলাপটি ধ্বংস হয়ে যায় এবং দৃশ্যের মডেলটিতে এখনও উপস্থিত নেই তবে প্রাসঙ্গিক প্রসঙ্গে। তবে আপনি কখনই অ্যাপ্লিকেশন প্রসঙ্গটি ধ্বংস করতে যাবেন না তবে ভিএম এর এখনও এর একটি উল্লেখ রয়েছে। ঠিক? আপনি কী এমন কোনও দৃশ্যের কল্পনা করতে পারেন যেখানে আপনার অ্যাপটি প্রস্থান করেছে কিন্তু ভিউমডেলটি নেই? :)
ব্যবহারকারী 1713450

3

আপনার ভিউমোডেলে অ্যান্ড্রয়েড সম্পর্কিত জিনিসগুলি ব্যবহার করা উচিত নয় কারণ ভিউমোডেল ব্যবহারের উদ্দেশ্যটি জাভা কোড এবং অ্যান্ড্রয়েড কোড পৃথক করা যাতে আপনি নিজের ব্যবসায়ের যুক্তিটি পৃথকভাবে পরীক্ষা করতে পারেন এবং আপনার অ্যান্ড্রয়েড উপাদানগুলির একটি পৃথক স্তর এবং আপনার ব্যবসার যুক্তি থাকতে পারে এবং ডেটা, আপনার ভিউমোডেলে আপনার প্রসঙ্গ থাকা উচিত নয় কারণ এটি ক্রাশ হতে পারে


4
এটি একটি নিখুঁত পর্যবেক্ষণ, তবে কিছু ব্যাকএন্ড লাইব্রেরিতে মিডিয়াস্টোরের মতো অ্যাপ্লিকেশন প্রসঙ্গগুলি এখনও প্রয়োজন। নীচে 4gus71n এর উত্তর কীভাবে আপস করবেন তা ব্যাখ্যা করে।
ব্রায়ান ডাব্লু ওয়াগনার

4
হ্যাঁ আপনি অ্যাপ্লিকেশন কনটেক্সট ব্যবহার করতে পারেন তবে ক্রিয়াকলাপের প্রসঙ্গ নয়, যেমন অ্যাপ্লিকেশন প্রবন্ধটি পুরো অ্যাপ্লিকেশন লাইক চক্র জুড়ে থাকে তবে অ্যাসিঙ্ক্রোনাস প্রক্রিয়াতে ক্রিয়াকলাপ প্রসঙ্গ হিসাবে পাস করার ক্রিয়াকলাপের প্রসঙ্গটি মেমরি ফাঁস হতে পারে না my আমার পোস্টে উল্লিখিত প্রসঙ্গটি হ'ল ক্রিয়াকলাপ প্রসঙ্গ.কিন্তু আপনার তবুও কোনও অ্যাসিক্রোনাস প্রক্রিয়া প্রসঙ্গে প্রযোজন না করার যত্ন নেওয়া উচিত যদিও তা অ্যাপ্লিকেশন প্রসঙ্গ।
রোহিত শর্মা

2

আমি কষ্ট পেয়ে চাপ ছিল SharedPreferencesযখন ব্যবহার ViewModelবর্গ তাই আমি উপরে উত্তর থেকে পরামর্শ নেন এবং নিম্নলিখিত ব্যবহার করেনি AndroidViewModel। সবকিছু এখন দুর্দান্ত দেখাচ্ছে

জন্য AndroidViewModel

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;

import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.preference.PreferenceManager;

public class HomeViewModel extends AndroidViewModel {

    private MutableLiveData<String> some_string;

    public HomeViewModel(Application application) {
        super(application);
        some_string = new MutableLiveData<>();
        Context context = getApplication().getApplicationContext();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        some_string.setValue("<your value here>"));
    }

}

এবং মধ্যে Fragment

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;


public class HomeFragment extends Fragment {


    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        final View root = inflater.inflate(R.layout.fragment_home, container, false);
        HomeViewModel homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
        homeViewModel.getAddress().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String address) {


            }
        });
        return root;
    }
}

0

আমি এটি এইভাবে তৈরি করেছি:

@Module
public class ContextModule {

    @Singleton
    @Provides
    @Named("AppContext")
    public Context provideContext(Application application) {
        return application.getApplicationContext();
    }
}

এবং তারপরে আমি স্রেফ অ্যাপস কম্পোনেন্টটি কনটেক্সটমডিউল.ক্লাসে যুক্ত করেছি:

@Component(
       modules = {
                ...
               ContextModule.class
       }
)
public interface AppComponent extends AndroidInjector<BaseApplication> {
.....
}

এবং তারপরে আমি আমার ভিউমোডেলে প্রসঙ্গটি ইনজেকশন দিয়েছি:

@Inject
@Named("AppContext")
Context context;


0

ভিউমোডেলটিতে একটি প্রসঙ্গ ইনজেকশনের সমস্যাটি হ'ল পর্দার ঘূর্ণন, নাইট মোড বা সিস্টেম ভাষার উপর নির্ভর করে যে কোনও সময় প্রসঙ্গ পরিবর্তন হতে পারে এবং যে কোনও প্রত্যাবর্তিত সংস্থান তদনুসারে পরিবর্তিত হতে পারে। একটি সাধারণ রিসোর্স আইডি ফিরিয়ে দেওয়া অতিরিক্ত প্যারামিটারগুলির জন্য গেটস্ট্রিং বিকল্প হিসাবে সমস্যার কারণ হয়। একটি উচ্চ-স্তরের ফলাফল প্রত্যাবর্তন এবং ক্রিয়াকলাপে রেন্ডারিং যুক্তি সরিয়ে নেওয়া পরীক্ষা করা আরও কঠিন করে তোলে।

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

ViewModel.kt:

// connectedStatus holds a function that calls Context methods
// `this` can be elided
val connectedStatus = MutableLiveData<Context.() -> String> {
  // initial value
  this.getString(R.string.connectionStatusWaiting)
}
connectedStatus.postValue {
  this.getString(R.string.connectionStatusConnected, brand)
}
Activity.kt  // is a Context

override fun onCreate(_: Bundle?) {
  connectionViewModel.connectedStatus.observe(this) { it ->
   // runs the posted value with the given Context receiver
   txtConnectionStatus.text = this.run(it)
  }
}

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


এবং ডেটাবাইন্ডিং সমর্থন সক্ষম করতে, আপনি ঠিক যেমন একটি সাধারণ বাঁধাকপি অ্যাডাপ্টার যোগ করুন:@BindingAdapter("android:text") fun setText(view: TextView, value: Context.() -> String) { view.text = view.context.run(value) }
Hufman
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.