এই কোডল্যাবটি অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোর্সের অংশ। আপনি যদি ক্রমানুসারে কোডল্যাবগুলির মাধ্যমে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন৷ সমস্ত কোর্স কোডল্যাব অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোডল্যাব ল্যান্ডিং পৃষ্ঠায় তালিকাভুক্ত করা হয়েছে।
ভূমিকা
 আপনার তৈরি করা প্রায় যেকোনো অ্যান্ড্রয়েড অ্যাপকে কোনো না কোনো সময়ে ইন্টারনেটের সাথে সংযোগ করতে হবে। এই কোডল্যাবে এবং যেগুলি অনুসরণ করে, আপনি একটি অ্যাপ তৈরি করেন যা ডেটা পুনরুদ্ধার এবং প্রদর্শন করতে একটি ওয়েব পরিষেবার সাথে সংযোগ করে৷ এছাড়াও আপনি ViewModel , LiveData , এবং RecyclerView সম্পর্কে অতীতের কোডল্যাবগুলিতে যা শিখেছেন তার উপর ভিত্তি করে তৈরি করুন৷
এই কোডল্যাবে, আপনি নেটওয়ার্ক স্তর তৈরি করতে কমিউনিটি ডেভেলপড লাইব্রেরি ব্যবহার করেন। এটি ডেটা এবং ছবিগুলি আনার প্রক্রিয়াটিকে ব্যাপকভাবে সহজ করে, এবং অ্যাপটিকে কিছু Android সেরা অনুশীলনগুলি মেনে চলতে সাহায্য করে, যেমন একটি ব্যাকগ্রাউন্ড থ্রেডে ছবি লোড করা এবং লোড করা ছবি ক্যাশ করা। কোডের মধ্যে অ্যাসিঙ্ক্রোনাস বা নন-ব্লকিং বিভাগগুলির জন্য, যেমন ওয়েব পরিষেবা স্তরের সাথে কথা বলা, আপনি কোটলিনের কোরোটিনগুলি ব্যবহার করার জন্য অ্যাপটি পরিবর্তন করবেন। আপনি অ্যাপের ইউজার ইন্টারফেস আপডেট করবেন যদি ইন্টারনেট ধীর বা অনুপলব্ধ হয় ব্যবহারকারীকে জানাতে যে কি ঘটছে।
আপনি ইতিমধ্যে কি জানা উচিত
- কীভাবে টুকরো তৈরি এবং ব্যবহার করবেন।
 -  টুকরোগুলির মধ্যে কীভাবে নেভিগেট করবেন এবং টুকরোগুলির মধ্যে ডেটা পাস করতে 
safeArgsব্যবহার করবেন। -  
ViewModel,ViewModelProvider.Factory,LiveData, এবংLiveDataরূপান্তর সহ আর্কিটেকচারের উপাদানগুলি কীভাবে ব্যবহার করবেন৷ - দীর্ঘমেয়াদী কাজের জন্য কোরোটিনগুলি কীভাবে ব্যবহার করবেন।
 
আপনি কি শিখবেন
- একটি REST ওয়েব পরিষেবা কি.
 - ইন্টারনেটে একটি REST ওয়েব পরিষেবার সাথে সংযোগ করতে এবং একটি প্রতিক্রিয়া পেতে Retrofit লাইব্রেরি ব্যবহার করে৷
 - একটি ডেটা অবজেক্টে JSON প্রতিক্রিয়া পার্স করতে মোশি লাইব্রেরি ব্যবহার করে।
 
আপনি কি করবেন
- একটি ওয়েব পরিষেবা API অনুরোধ করতে এবং প্রতিক্রিয়া পরিচালনা করতে একটি স্টার্টার অ্যাপ পরিবর্তন করুন।
 - রেট্রোফিট লাইব্রেরি ব্যবহার করে আপনার অ্যাপের জন্য একটি নেটওয়ার্ক স্তর প্রয়োগ করুন।
 - মোশি লাইব্রেরির সাথে আপনার অ্যাপের লাইভ ডেটাতে ওয়েব পরিষেবা থেকে JSON প্রতিক্রিয়া পার্স করুন।
 - কোডটি সরলীকরণ করতে কোরোটিনের জন্য রেট্রোফিটের সমর্থন ব্যবহার করুন।
 
এই কোডল্যাবে (এবং নিম্নলিখিত কোডল্যাবগুলি), আপনি MarsRealEstate নামে একটি স্টার্টার অ্যাপের সাথে কাজ করেন, যা মঙ্গল গ্রহে বিক্রয়ের জন্য বৈশিষ্ট্য দেখায়। এই অ্যাপটি সম্পত্তির ডেটা পুনরুদ্ধার এবং প্রদর্শন করার জন্য একটি ওয়েব পরিষেবার সাথে সংযোগ করে, যার মধ্যে মূল্য এবং সম্পত্তিটি বিক্রয় বা ভাড়ার জন্য উপলব্ধ কিনা। প্রতিটি সম্পত্তির প্রতিনিধিত্বকারী চিত্রগুলি হল মঙ্গল গ্রহের বাস্তব জীবনের ছবি যা NASA-এর মার্স রোভার থেকে ধারণ করা হয়েছে৷

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

.
MarsRealEstate অ্যাপের আর্কিটেকচারে দুটি প্রধান মডিউল রয়েছে:
-  একটি ওভারভিউ ফ্র্যাগমেন্ট, যেটিতে থাম্বনেইল প্রোপার্টি ইমেজগুলির একটি গ্রিড রয়েছে, একটি 
RecyclerViewদিয়ে তৈরি। - প্রতিটি সম্পত্তি সম্পর্কে তথ্য ধারণকারী একটি বিশদ দৃশ্য খণ্ড।
 

 অ্যাপটিতে প্রতিটি খণ্ডের জন্য একটি ViewModel রয়েছে। এই কোডল্যাবের জন্য, আপনি নেটওয়ার্ক পরিষেবার জন্য একটি স্তর তৈরি করেন এবং ViewModel সেই নেটওয়ার্ক স্তরের সাথে সরাসরি যোগাযোগ করে। ViewModel যখন Room ডাটাবেসের সাথে যোগাযোগ করেছিল তখন আপনি পূর্ববর্তী কোডল্যাবগুলিতে যা করেছিলেন তার অনুরূপ।
 ওভারভিউ ViewModel মঙ্গল গ্রহের রিয়েল এস্টেট তথ্য পেতে নেটওয়ার্ক কল করার জন্য দায়ী। বিশদ ViewModel মার্স রিয়েল এস্টেটের একক অংশের বিশদ বিবরণ রয়েছে যা বিশদ খণ্ডে প্রদর্শিত হয়। প্রতিটি ViewModel এর জন্য, ডেটা পরিবর্তিত হলে আপনি অ্যাপ UI আপডেট করতে লাইফসাইকেল-সচেতন ডেটা বাইন্ডিং সহ LiveData ব্যবহার করেন।
আপনি দুটি খণ্ডের মধ্যে নেভিগেট করতে এবং একটি আর্গুমেন্ট হিসাবে নির্বাচিত সম্পত্তি পাস করতে উভয় ন্যাভিগেশন উপাদান ব্যবহার করুন।
এই কাজটিতে, আপনি MarsRealEstate-এর জন্য স্টার্টার অ্যাপ ডাউনলোড করে চালান এবং প্রকল্পের কাঠামোর সাথে নিজেকে পরিচিত করুন।
ধাপ 1: টুকরো এবং নেভিগেশন অন্বেষণ করুন
- MarsRealEstate স্টার্টার অ্যাপটি ডাউনলোড করুন এবং এটি অ্যান্ড্রয়েড স্টুডিওতে খুলুন।
 -  
app/java/MainActivity.ktপরীক্ষা করুন। অ্যাপটি উভয় স্ক্রিনের জন্য টুকরা ব্যবহার করে, তাই ক্রিয়াকলাপের জন্য একমাত্র কাজ হল কার্যকলাপের বিন্যাস লোড করা। -  
app/res/layout/activity_main.xmlপরীক্ষা করুন। ক্রিয়াকলাপের বিন্যাস হল দুটি খণ্ডের হোস্ট, যা নেভিগেশন ফাইলে সংজ্ঞায়িত করা হয়েছে। এই লেআউটটি একটিNavHostFragmentএবং এর সংশ্লিষ্ট নেভিগেশন কন্ট্রোলারকেnav_graphরিসোর্সের সাথে তাত্ক্ষণিক করে। -  
app/res/navigation/nav_graph.xmlখুলুন। এখানে আপনি দুটি খণ্ডের মধ্যে নেভিগেশন সম্পর্ক দেখতে পারেন। নেভিগেশন গ্রাফStartDestinationoverviewFragmentদিকে নির্দেশ করে, তাই অ্যাপটি চালু হলে ওভারভিউ ফ্র্যাগমেন্টটি ইনস্ট্যান্ট করা হয়। 
ধাপ 2: Kotlin সোর্স ফাইল এবং ডেটা বাইন্ডিং এক্সপ্লোর করুন
-  প্রকল্প ফলকে, অ্যাপ > java প্রসারিত করুন। লক্ষ্য করুন যে MarsRealEstate অ্যাপটিতে তিনটি প্যাকেজ ফোল্ডার রয়েছে: 
detail,networkএবংoverview। এগুলি আপনার অ্যাপের তিনটি প্রধান উপাদানের সাথে মিলে যায়: ওভারভিউ এবং বিশদ খণ্ড, এবং নেটওয়ার্ক স্তরের কোড৷
 -  
app/java/overview/OverviewFragment.ktখুলুন।OverviewFragmentঅলসভাবেOverviewViewModelআরম্ভ করে, যার মানেOverviewViewModelপ্রথমবার ব্যবহার করার সময় তৈরি হয়। -  
onCreateView()পদ্ধতি পরীক্ষা করুন। এই পদ্ধতিটি ডেটা বাইন্ডিং ব্যবহার করেfragment_overviewলেআউটকে স্ফীত করে, বাইন্ডিং লাইফসাইকেল মালিককে নিজের সাথে সেট করে (this), এবং এটিতেbindingঅবজেক্টেviewModelভেরিয়েবল সেট করে। যেহেতু আমরা লাইফসাইকেল মালিক সেট করেছি, ডেটা বাইন্ডিং-এ ব্যবহৃত যেকোনLiveDataযেকোন পরিবর্তনের জন্য স্বয়ংক্রিয়ভাবে পর্যবেক্ষণ করা হবে এবং সেই অনুযায়ী UI আপডেট করা হবে। -  
app/java/overview/OverviewViewModelখুলুন। কারণ প্রতিক্রিয়াটি একটিLiveDataএবং আমরা বাইন্ডিং ভেরিয়েবলের জন্য লাইফসাইকেল সেট করেছি, এতে যে কোনো পরিবর্তন অ্যাপ UI আপডেট করবে। -  
initব্লক পরীক্ষা করুন। যখনViewModelতৈরি করা হয়, এটিgetMarsRealEstateProperties()পদ্ধতিকে কল করে। -  
getMarsRealEstateProperties()পদ্ধতি পরীক্ষা করুন। এই স্টার্টার অ্যাপে, এই পদ্ধতিতে একটি স্থানধারক প্রতিক্রিয়া রয়েছে। এই কোডল্যাবের লক্ষ্য হল আপনি ইন্টারনেট থেকে প্রাপ্ত বাস্তব ডেটা ব্যবহার করেViewModelমধ্যে প্রতিক্রিয়াLiveDataআপডেট করা। -  
app/res/layout/fragment_overview.xmlখুলুন। এই কোডল্যাবে আপনি যে ওভারভিউ ফ্র্যাগমেন্টের সাথে কাজ করেন তার লেআউট এবং এতে ভিউ মডেলের জন্য ডেটা বাইন্ডিং অন্তর্ভুক্ত রয়েছে। এটিOverviewViewModelআমদানি করে এবং তারপরViewModelথেকে প্রতিক্রিয়াটিকে একটিTextViewএ আবদ্ধ করে। পরবর্তী কোডল্যাবগুলিতে, আপনি একটিRecyclerViewএ চিত্রগুলির একটি গ্রিড দিয়ে পাঠ্য দৃশ্য প্রতিস্থাপন করেন। - অ্যাপটি কম্পাইল করে রান করুন। এই অ্যাপের বর্তমান সংস্করণে আপনি যা দেখতে পাচ্ছেন তা হল স্টার্টার প্রতিক্রিয়া—"মঙ্গল API প্রতিক্রিয়া এখানে সেট করুন!"
 

মার্স রিয়েল এস্টেট ডেটা একটি ওয়েব সার্ভারে, একটি REST ওয়েব পরিষেবা হিসাবে সংরক্ষণ করা হয়৷ ওয়েব পরিষেবাগুলি REST আর্কিটেকচার ব্যবহার করে স্ট্যান্ডার্ড ওয়েব উপাদান এবং প্রোটোকল ব্যবহার করে নির্মিত হয়।
আপনি URI-এর মাধ্যমে একটি প্রমিত উপায়ে একটি ওয়েব পরিষেবার কাছে একটি অনুরোধ করেন। পরিচিত ওয়েব ইউআরএল আসলে এক ধরনের ইউআরআই, এবং উভয়ই এই কোর্স জুড়ে বিনিময়যোগ্যভাবে ব্যবহার করা হয়। উদাহরণস্বরূপ, এই পাঠের জন্য অ্যাপে, আপনি নিম্নলিখিত সার্ভার থেকে সমস্ত ডেটা পুনরুদ্ধার করবেন:
https://android-kotlin-fun-mars-server.appspot.com
আপনি যদি আপনার ব্রাউজারে নিম্নলিখিত URL টাইপ করেন, আপনি মঙ্গল গ্রহে সমস্ত উপলব্ধ রিয়েল এস্টেট সম্পত্তির একটি তালিকা পাবেন!
https://android-kotlin-fun-mars-server.appspot.com/realestate
একটি ওয়েব পরিষেবা থেকে প্রতিক্রিয়া সাধারণত JSON- এ ফর্ম্যাট করা হয়, স্ট্রাকচার্ড ডেটা উপস্থাপনের জন্য একটি বিনিময় বিন্যাস৷ আপনি পরবর্তী টাস্কে JSON সম্পর্কে আরও জানবেন, কিন্তু সংক্ষিপ্ত ব্যাখ্যা হল যে একটি JSON অবজেক্ট হল কী-মানের জোড়ার একটি সংগ্রহ, যাকে কখনও কখনও অভিধান , একটি হ্যাশ মানচিত্র বা একটি সহযোগী অ্যারে বলা হয়। JSON অবজেক্টের একটি সংগ্রহ হল একটি JSON অ্যারে, এবং এটি এমন অ্যারে যা আপনি একটি ওয়েব পরিষেবা থেকে প্রতিক্রিয়া হিসাবে ফিরে পাবেন।
অ্যাপটিতে এই ডেটা পেতে, আপনার অ্যাপটিকে একটি নেটওয়ার্ক সংযোগ স্থাপন করতে হবে এবং সেই সার্ভারের সাথে যোগাযোগ করতে হবে, এবং তারপরে অ্যাপটি ব্যবহার করতে পারে এমন ফর্ম্যাটে প্রতিক্রিয়া ডেটা গ্রহণ এবং পার্স করতে হবে। এই কোডল্যাবে, আপনি এই সংযোগটি তৈরি করতে Retrofit নামক একটি REST ক্লায়েন্ট লাইব্রেরি ব্যবহার করেন।
ধাপ 1: Gradle এ Retrofit নির্ভরতা যোগ করুন
- build.gradle খুলুন (মডিউল: অ্যাপ) ।
 -  
dependenciesবিভাগে, রেট্রোফিট লাইব্রেরির জন্য এই লাইনগুলি যোগ করুন: 
implementation "com.squareup.retrofit2:retrofit:$version_retrofit"
implementation "com.squareup.retrofit2:converter-scalars:$version_retrofit"
 লক্ষ্য করুন যে সংস্করণ নম্বরগুলি প্রকল্প গ্রেডল ফাইলে আলাদাভাবে সংজ্ঞায়িত করা হয়েছে। প্রথম নির্ভরতা রেট্রোফিট 2 লাইব্রেরির জন্য এবং দ্বিতীয় নির্ভরতা হল রেট্রোফিট স্কেলার কনভার্টারের জন্য। এই রূপান্তরকারী রেট্রোফিটকে একটি String হিসাবে JSON ফলাফল ফেরত দিতে সক্ষম করে। দুটি লাইব্রেরি একসঙ্গে কাজ করে।
- নতুন নির্ভরতার সাথে প্রকল্পটি পুনর্নির্মাণ করতে এখন সিঙ্ক এ ক্লিক করুন।
 
ধাপ 2: MarsApiService বাস্তবায়ন করুন
রেট্রোফিট ওয়েব পরিষেবার বিষয়বস্তুর উপর ভিত্তি করে অ্যাপের জন্য একটি নেটওয়ার্ক API তৈরি করে। এটি ওয়েব পরিষেবা থেকে ডেটা নিয়ে আসে এবং এটিকে একটি পৃথক রূপান্তরকারী লাইব্রেরির মাধ্যমে রুট করে যা জানে কীভাবে ডেটা ডিকোড করতে হয় এবং দরকারী বস্তুর আকারে ফেরত দিতে হয়। রেট্রোফিটের মধ্যে XML এবং JSON-এর মতো জনপ্রিয় ওয়েব ডেটা ফর্ম্যাটের জন্য অন্তর্নির্মিত সমর্থন অন্তর্ভুক্ত রয়েছে। রেট্রোফিট শেষ পর্যন্ত আপনার জন্য বেশিরভাগ নেটওয়ার্ক স্তর তৈরি করে, যার মধ্যে গুরুত্বপূর্ণ বিবরণ যেমন ব্যাকগ্রাউন্ড থ্রেডগুলিতে অনুরোধ চালানোর মতো।
 MarsApiService ক্লাস অ্যাপের জন্য নেটওয়ার্ক স্তর ধারণ করে; অর্থাৎ, এটি সেই API যা আপনার ViewModel ওয়েব পরিষেবার সাথে যোগাযোগ করতে ব্যবহার করবে। এটি সেই ক্লাস যেখানে আপনি Retrofit পরিষেবা API বাস্তবায়ন করবেন।
-  
app/java/network/MarsApiService.ktখুলুন। এই মুহূর্তে ফাইলটিতে শুধুমাত্র একটি জিনিস রয়েছে: ওয়েব পরিষেবার জন্য বেস URL-এর জন্য একটি ধ্রুবক৷ 
private const val BASE_URL = 
   "https://android-kotlin-fun-mars-server.appspot.com"-  সেই ধ্রুবকের ঠিক নীচে, একটি রেট্রোফিট অবজেক্ট তৈরি করতে একটি রেট্রোফিট নির্মাতা ব্যবহার করুন। অনুরোধ করা হলে 
retrofit2.Retrofitএবংretrofit2.converter.scalars.ScalarsConverterFactoryআমদানি করুন। 
private val retrofit = Retrofit.Builder()
   .addConverterFactory(ScalarsConverterFactory.create())
   .baseUrl(BASE_URL)
   .build()
 একটি ওয়েব পরিষেবা API তৈরি করতে রেট্রোফিটের কমপক্ষে দুটি জিনিস উপলব্ধ থাকতে হবে: ওয়েব পরিষেবার জন্য বেস ইউআরআই এবং একটি রূপান্তরকারী কারখানা৷ কনভার্টারটি রেট্রোফিটকে বলে যে এটি ওয়েব পরিষেবা থেকে ফিরে পাওয়া ডেটা নিয়ে কী করবে৷ এই ক্ষেত্রে, আপনি রেট্রোফিটকে ওয়েব পরিষেবা থেকে একটি JSON প্রতিক্রিয়া আনতে চান এবং এটি একটি String হিসাবে ফেরত দিতে চান। Retrofit এর একটি ScalarsConverter রয়েছে যা স্ট্রিং এবং অন্যান্য আদিম প্রকারগুলিকে সমর্থন করে, তাই আপনি ScalarsConverterFactory এর উদাহরণ সহ নির্মাতাকে addConverterFactory() কল করুন। অবশেষে, আপনি Retrofit অবজেক্ট তৈরি করতে build() কল করুন।
-  রেট্রোফিট বিল্ডারের কলের ঠিক নীচে, একটি ইন্টারফেস সংজ্ঞায়িত করুন যা সংজ্ঞায়িত করে যে রেট্রোফিট কীভাবে HTTP অনুরোধগুলি ব্যবহার করে ওয়েব সার্ভারের সাথে কথা বলে৷ 
retrofit2.http.GETএবংretrofit2.Callআমদানি করুন। অনুরোধ করা হলে কল করুন। 
interface MarsApiService {
    @GET("realestate")
    fun getProperties():
            Call<String>
} এই মুহূর্তে লক্ষ্য হল ওয়েব পরিষেবা থেকে JSON প্রতিক্রিয়া স্ট্রিং পাওয়া, এবং এটি করার জন্য আপনার শুধুমাত্র একটি পদ্ধতির প্রয়োজন: getProperties() । রেট্রোফিটকে এই পদ্ধতিটি কী করা উচিত তা জানাতে, একটি @GET টীকা ব্যবহার করুন এবং সেই ওয়েব পরিষেবা পদ্ধতির জন্য পাথ বা এন্ডপয়েন্ট নির্দিষ্ট করুন৷ এই ক্ষেত্রে শেষ পয়েন্টটিকে realestate বলা হয়। যখন getProperties() পদ্ধতিটি চালু করা হয়, তখন Retrofit এন্ডপয়েন্ট realestate বেস ইউআরএলে যুক্ত করে (যা আপনি রেট্রোফিট বিল্ডারে সংজ্ঞায়িত করেছেন), এবং একটি Call অবজেক্ট তৈরি করে। সেই Call অবজেক্টটি অনুরোধ শুরু করতে ব্যবহৃত হয়।
-  
MarsApiServiceইন্টারফেসের নীচে, Retrofit পরিষেবা শুরু করতেMarsApiনামক একটি পাবলিক অবজেক্ট সংজ্ঞায়িত করুন। 
object MarsApi {
    val retrofitService : MarsApiService by lazy { 
       retrofit.create(MarsApiService::class.java) }
} Retrofit create() পদ্ধতি MarsApiService ইন্টারফেসের সাথে Retrofit পরিষেবা নিজেই তৈরি করে। যেহেতু এই কলটি ব্যয়বহুল, এবং অ্যাপটির শুধুমাত্র একটি Retrofit পরিষেবার উদাহরণ প্রয়োজন, আপনি MarsApi নামক একটি পাবলিক অবজেক্ট ব্যবহার করে অ্যাপের বাকি অংশের কাছে পরিষেবাটি প্রকাশ করুন এবং সেখানে অলসভাবে রেট্রোফিট পরিষেবা চালু করুন৷ এখন যেহেতু সমস্ত সেটআপ সম্পন্ন হয়েছে, প্রতিবার আপনার অ্যাপটি MarsApi.retrofitService কল করবে, এটি একটি Singleton Retrofit অবজেক্ট পাবে যা MarsApiService প্রয়োগ করে৷ 
ধাপ 3: OverviewViewModel-এ ওয়েব পরিষেবাতে কল করুন
-  
app/java/overview/OverviewViewModel.ktখুলুন।getMarsRealEstateProperties()পদ্ধতিতে নিচে স্ক্রোল করুন। 
private fun getMarsRealEstateProperties() {
   _response.value = "Set the Mars API Response here!"
}এটি সেই পদ্ধতি যেখানে আপনি Retrofit পরিষেবাতে কল করবেন এবং ফিরে আসা JSON স্ট্রিংটি পরিচালনা করবেন৷ এই মুহূর্তে প্রতিক্রিয়ার জন্য শুধুমাত্র একটি স্থানধারক স্ট্রিং আছে।
- "এখানে মার্স এপিআই রেসপন্স সেট করুন!" এর প্রতিক্রিয়া সেট করে এমন স্থানধারক লাইনটি মুছুন!
 -  
getMarsRealEstateProperties()এর ভিতরে, নীচে দেখানো কোড যোগ করুন। অনুরোধ করা হলেretrofit2.Callbackএবংcom.example.android.marsrealestate.network.MarsApiআমদানি করুন।
MarsApi.retrofitService.getProperties()পদ্ধতি একটিCallঅবজেক্ট রিটার্ন করে। তারপরে আপনি একটি পটভূমি থ্রেডে নেটওয়ার্ক অনুরোধ শুরু করতে সেই বস্তুতেenqueue()কল করতে পারেন। 
MarsApi.retrofitService.getProperties().enqueue( 
   object: Callback<String> {
})-  
objectশব্দটিতে ক্লিক করুন, যা লাল রঙে আন্ডারলাইন করা হয়েছে। কোড > প্রয়োগ পদ্ধতি নির্বাচন করুন। তালিকা থেকেonResponse()এবংonFailure()উভয়ই নির্বাচন করুন।
অ্যান্ড্রয়েড স্টুডিও প্রতিটি পদ্ধতিতে TODO সহ কোড যোগ করে: 
override fun onFailure(call: Call<String>, t: Throwable) {
       TODO("not implemented") 
}
override fun onResponse(call: Call<String>, 
   response: Response<String>) {
       TODO("not implemented") 
}-  
onFailure()এ, TODO মুছুন এবং একটি ব্যর্থতার বার্তায়_responseসেট করুন, যেমনটি নীচে দেখানো হয়েছে।_responseহল একটিLiveDataস্ট্রিং যা টেক্সট ভিউতে কী দেখানো হয়েছে তা নির্ধারণ করে। প্রতিটি রাজ্যকে_responseLiveDataআপডেট করতে হবে।
ওয়েব পরিষেবার প্রতিক্রিয়া ব্যর্থ হলেonFailure()কলব্যাক বলা হয়। এই প্রতিক্রিয়ার জন্য,_responseস্ট্যাটাসটিকে"Failure: "তেThrowableআর্গুমেন্টের বার্তার সাথে সংযুক্ত করুন। 
override fun onFailure(call: Call<String>, t: Throwable) {
   _response.value = "Failure: " + t.message
}-  
onResponse()এ, TODO মুছে দিন এবং প্রতিক্রিয়া বডিতে_responseসেট করুন।onResponse()কলব্যাক বলা হয় যখন অনুরোধ সফল হয় এবং ওয়েব পরিষেবা একটি প্রতিক্রিয়া প্রদান করে। 
override fun onResponse(call: Call<String>, 
   response: Response<String>) {
      _response.value = response.body()
}ধাপ 4: ইন্টারনেট অনুমতি সংজ্ঞায়িত করুন
-  MarsRealEstate অ্যাপ কম্পাইল করুন এবং চালান। নোট করুন যে অ্যাপটি একটি ত্রুটির সাথে সাথে সাথে বন্ধ হয়ে যায়। 

 - অ্যান্ড্রয়েড স্টুডিওতে লগক্যাট ট্যাবে ক্লিক করুন এবং লগটিতে ত্রুটিটি নোট করুন, যা এইরকম একটি লাইন দিয়ে শুরু হয়:
 
Process: com.example.android.marsrealestate, PID: 10646 java.lang.SecurityException: Permission denied (missing INTERNET permission?)
ত্রুটি বার্তা আপনাকে বলে যে আপনার অ্যাপটি হয়ত INTERNET অনুমতি হারিয়েছে৷ ইন্টারনেটের সাথে সংযোগ নিরাপত্তা উদ্বেগের পরিচয় দেয়, যে কারণে অ্যাপগুলিতে ডিফল্টরূপে ইন্টারনেট সংযোগ থাকে না। আপনাকে স্পষ্টভাবে অ্যান্ড্রয়েডকে বলতে হবে যে অ্যাপটির ইন্টারনেট অ্যাক্সেস প্রয়োজন।
-  
app/manifests/AndroidManifest.xmlখুলুন।<application>ট্যাগের ঠিক আগে এই লাইনটি যোগ করুন: 
<uses-permission android:name="android.permission.INTERNET" />-  কম্পাইল করুন এবং আবার অ্যাপ চালান। আপনার ইন্টারনেট সংযোগের সাথে সবকিছু সঠিকভাবে কাজ করলে, আপনি মঙ্গল গ্রহের সম্পত্তি ডেটা সম্বলিত JSON পাঠ্য দেখতে পাবেন। 

 - অ্যাপটি বন্ধ করতে আপনার ডিভাইস বা এমুলেটরের পিছনের বোতামটি আলতো চাপুন।
 - আপনার ডিভাইস বা এমুলেটরকে এয়ারপ্লেন মোডে রাখুন, এবং তারপরে সাম্প্রতিক মেনু থেকে অ্যাপটি আবার খুলুন, অথবা অ্যান্ড্রয়েড স্টুডিও থেকে অ্যাপটি পুনরায় চালু করুন।
 

- বিমান মোড আবার বন্ধ করুন।
 
এখন আপনি মার্স ওয়েব পরিষেবা থেকে একটি JSON প্রতিক্রিয়া পাচ্ছেন, যা একটি দুর্দান্ত শুরু৷ কিন্তু আপনার যা প্রয়োজন তা হল কোটলিন অবজেক্ট, বড় JSON স্ট্রিং নয়। Moshi নামে একটি লাইব্রেরি আছে, যা একটি Android JSON পার্সার যা একটি JSON স্ট্রিংকে Kotlin অবজেক্টে রূপান্তর করে। রেট্রোফিটের একটি রূপান্তরকারী রয়েছে যা মোশির সাথে কাজ করে, তাই এটি এখানে আপনার উদ্দেশ্যে একটি দুর্দান্ত লাইব্রেরি।
এই কাজটিতে, আপনি ওয়েব পরিষেবা থেকে JSON প্রতিক্রিয়াকে দরকারী Mars Property Kotlin অবজেক্টে পার্স করতে Retrofit সহ Moshi লাইব্রেরি ব্যবহার করেন। আপনি অ্যাপটি পরিবর্তন করুন যাতে কাঁচা JSON প্রদর্শনের পরিবর্তে, অ্যাপটি মঙ্গল গ্রহের সম্পত্তির সংখ্যা প্রদর্শন করে।
ধাপ 1: মোশি লাইব্রেরি নির্ভরতা যোগ করুন
- build.gradle খুলুন (মডিউল: অ্যাপ) ।
 -  নির্ভরতা বিভাগে, মোশি নির্ভরতা অন্তর্ভুক্ত করতে নীচে দেখানো কোড যোগ করুন। রেট্রোফিটের মতো, 
$version_moshiপ্রকল্প-স্তরের গ্রেডল ফাইলে আলাদাভাবে সংজ্ঞায়িত করা হয়েছে। এই নির্ভরতাগুলি মূল মোশি JSON লাইব্রেরির জন্য এবং মোশির কোটলিন সমর্থনের জন্য সমর্থন যোগ করে। 
implementation "com.squareup.moshi:moshi:$version_moshi"
implementation "com.squareup.moshi:moshi-kotlin:$version_moshi"-  
dependenciesব্লকে রেট্রোফিট স্কেলার কনভার্টারের জন্য লাইনটি সনাক্ত করুন: 
implementation "com.squareup.retrofit2:converter-scalars:$version_retrofit"-  
converter-moshiব্যবহার করতে সেই লাইনটি পরিবর্তন করুন: 
implementation "com.squareup.retrofit2:converter-moshi:$version_retrofit"- নতুন নির্ভরতার সাথে প্রকল্পটি পুনর্নির্মাণ করতে এখন সিঙ্ক এ ক্লিক করুন।
 
ধাপ 2: MarsProperty ডেটা ক্লাস বাস্তবায়ন করুন
আপনি ওয়েব পরিষেবা থেকে প্রাপ্ত JSON প্রতিক্রিয়ার একটি নমুনা এন্ট্রি দেখতে এইরকম কিছু দেখায়:
[{"price":450000,
"id":"424906",
"type":"rent",
"img_src":"http://mars.jpl.nasa.gov/msl-raw-images/msss/01000/mcam/1000ML0044631300305227E03_DXXX.jpg"},
...]উপরে দেখানো JSON প্রতিক্রিয়া একটি অ্যারে, যা বর্গাকার বন্ধনী দ্বারা নির্দেশিত হয়। অ্যারেতে JSON অবজেক্ট রয়েছে, যেগুলো কোঁকড়া ধনুর্বন্ধনী দ্বারা বেষ্টিত। প্রতিটি বস্তুর নাম-মানের জোড়ার একটি সেট থাকে, কোলন দ্বারা পৃথক করা হয়। নামগুলো উদ্ধৃতি দিয়ে ঘেরা। মানগুলি সংখ্যা বা স্ট্রিং হতে পারে এবং স্ট্রিংগুলিও উদ্ধৃতি দ্বারা বেষ্টিত। উদাহরণস্বরূপ, এই সম্পত্তির price হল $450,000 এবং img_src হল একটি URL, যা সার্ভারে চিত্র ফাইলের অবস্থান৷
উপরের উদাহরণে, লক্ষ্য করুন যে প্রতিটি মঙ্গল সম্পত্তি এন্ট্রিতে এই JSON কী এবং মান জোড়া রয়েছে:
-  
price: একটি সংখ্যা হিসাবে মঙ্গল সম্পত্তির মূল্য। -  
id: সম্পত্তির আইডি, একটি স্ট্রিং হিসাবে। -  
type: হয়"rent"বা"buy"। -  
img_src: একটি স্ট্রিং হিসাবে চিত্রের URL। 
মোশি এই JSON ডেটা পার্স করে এবং এটিকে Kotlin অবজেক্টে রূপান্তর করে। এটি করার জন্য, পার্স করা ফলাফলগুলি সঞ্চয় করার জন্য এটির একটি Kotlin ডেটা ক্লাস থাকা প্রয়োজন, তাই পরবর্তী পদক্ষেপটি সেই ক্লাস তৈরি করা।
-  
app/java/network/MarsProperty.ktখুলুন। -  বিদ্যমান 
MarsPropertyক্লাস সংজ্ঞা নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন: 
data class MarsProperty(
   val id: String, val img_src: String,
   val type: String,
   val price: Double
)লক্ষ্য করুন যে MarsProperty ক্লাসের প্রতিটি ভেরিয়েবল JSON অবজেক্টের একটি মূল নামের সাথে মিলে যায়। JSON-এর প্রকারের সাথে মেলানোর জন্য, আপনি price ব্যতীত সমস্ত মানের জন্য String অবজেক্ট ব্যবহার করেন, যা একটি Double । যেকোন JSON সংখ্যার প্রতিনিধিত্ব করতে একটি Double ব্যবহার করা যেতে পারে।
যখন মোশি JSON পার্স করে, তখন এটি নামের সাথে কী মেলে এবং উপযুক্ত মান দিয়ে ডেটা অবজেক্ট পূরণ করে।
-  নিচে দেখানো লাইন দিয়ে 
img_srcকী-এর লাইন প্রতিস্থাপন করুন। অনুরোধ করা হলেcom.squareup.moshi.Jsonআমদানি করুন। 
@Json(name = "img_src") val imgSrcUrl: String,কখনও কখনও একটি JSON প্রতিক্রিয়ার মূল নামগুলি বিভ্রান্তিকর Kotlin বৈশিষ্ট্য তৈরি করতে পারে, বা আপনার কোডিং শৈলীর সাথে মেলে না-উদাহরণস্বরূপ, JSON ফাইলে img_src কী একটি আন্ডারস্কোর ব্যবহার করে, যেখানে Kotlin বৈশিষ্ট্যগুলি সাধারণত বড় এবং ছোট হাতের অক্ষর ব্যবহার করে ("উট কেস")।
 আপনার ডেটা ক্লাসে পরিবর্তনশীল নামগুলি ব্যবহার করতে যা JSON প্রতিক্রিয়ার মূল নামগুলির থেকে আলাদা, @Json টীকাটি ব্যবহার করুন৷ এই উদাহরণে, ডেটা ক্লাসের ভেরিয়েবলের নাম হল imgSrcUrl । ভেরিয়েবলটি @Json(name = "img_src") ব্যবহার করে JSON অ্যাট্রিবিউট img_src এ ম্যাপ করা হয়েছে। 
ধাপ 3: MarsApiService এবং OverviewViewModel আপডেট করুন
 MarsProperty ডেটা ক্লাসের জায়গায়, আপনি এখন Moshi ডেটা অন্তর্ভুক্ত করতে নেটওয়ার্ক API এবং ViewModel আপডেট করতে পারেন।
-  
network/MarsApiService.ktখুলুন। আপনিScalarsConverterFactoryজন্য অনুপস্থিত-শ্রেণির ত্রুটি দেখতে পারেন। এটি রেট্রোফিট নির্ভরতা পরিবর্তনের কারণে যা আপনি ধাপ 1 এ করেছেন। আপনি শীঘ্রই সেই ত্রুটিগুলি ঠিক করবেন। -  ফাইলের শীর্ষে, রেট্রোফিট নির্মাতার ঠিক আগে, মোশি উদাহরণ তৈরি করতে নিম্নলিখিত কোডটি যোগ করুন। অনুরোধ করা হলে 
com.squareup.moshi.Moshiএবংcom.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactoryআমদানি করুন৷ 
private val moshi = Moshi.Builder()
   .add(KotlinJsonAdapterFactory())
   .build()আপনি রেট্রোফিটের সাথে যা করেছেন তার অনুরূপ, এখানে আপনি মোশি বিল্ডার ব্যবহার করে একটি moshi অবজেক্ট তৈরি করেন। কোটলিনের সাথে মোশির টীকাগুলি সঠিকভাবে কাজ করার জন্য, KotlinJsonAdapterFactory যোগ করুন এবং তারপর build() কল করুন।
-  
ScalarConverterFactoryএর পরিবর্তেMoshiConverterFactoryব্যবহার করতে রেট্রোফিট বিল্ডার পরিবর্তন করুন এবং আপনার তৈরি করাmoshiউদাহরণটি পাস করুন। অনুরোধ করা হলেretrofit2.converter.moshi.MoshiConverterFactoryআমদানি করুন। 
private val retrofit = Retrofit.Builder()
   .addConverterFactory(MoshiConverterFactory.create(moshi))
   .baseUrl(BASE_URL)
   .build()-  পাশাপাশি 
ScalarConverterFactoryজন্য আমদানি মুছুন। 
মুছে ফেলার জন্য কোড:
import retrofit2.converter.scalars.ScalarsConverterFactory-  
MarsApiServiceইন্টারফেস আপডেট করুন যাতে RetrofitMarsPropertyঅবজেক্টের একটি তালিকা ফেরত দেয়,Call<String>ফেরত না দিয়ে। 
interface MarsApiService {
   @GET("realestate")
   fun getProperties():
      Call<List<MarsProperty>>
}-  
OverviewViewModel.ktখুলুন।getMarsRealEstateProperties()পদ্ধতিতেgetProperties().enqueue()কলে নিচে স্ক্রোল করুন। -  আর্গুমেন্টটিকে 
enqueue()এCallback<String>থেকেCallback<List<MarsProperty>>এ পরিবর্তন করুন। অনুরোধ করা হলেcom.example.android.marsrealestate.network.MarsPropertyআমদানি করুন। 
MarsApi.retrofitService.getProperties().enqueue( 
   object: Callback<List<MarsProperty>> {-  
onFailure()এ, আর্গুমেন্টকেCall<String>থেকেCall<List<MarsProperty>>এ পরিবর্তন করুন : 
override fun onFailure(call: Call<List<MarsProperty>>, t: Throwable) {-  
onResponse()এ উভয় আর্গুমেন্টে একই পরিবর্তন করুন: 
override fun onResponse(call: Call<List<MarsProperty>>, 
   response: Response<List<MarsProperty>>) {onResponse()এর বডিতে, বিদ্যমান অ্যাসাইনমেন্টটিকে_response.valueএ নীচে দেখানো অ্যাসাইনমেন্ট দিয়ে প্রতিস্থাপন করুন। যেহেতুresponse.body()এখনMarsPropertyঅবজেক্টের একটি তালিকা, সেই তালিকার সাইজ হল পার্স করা প্রপার্টির সংখ্যা। এই প্রতিক্রিয়া বার্তাটি সেই সংখ্যক বৈশিষ্ট্য প্রিন্ট করে:
_response.value = 
   "Success: ${response.body()?.size} Mars properties retrieved"- নিশ্চিত করুন বিমান মোড বন্ধ আছে. অ্যাপটি কম্পাইল করে রান করুন। এইবার বার্তাটি ওয়েব পরিষেবা থেকে প্রত্যাবর্তিত সম্পত্তির সংখ্যা প্রদর্শন করা উচিত: 

 
এখন Retrofit API পরিষেবা চলছে, কিন্তু এটি দুটি কলব্যাক পদ্ধতি সহ একটি কলব্যাক ব্যবহার করে যা আপনাকে বাস্তবায়ন করতে হয়েছিল। একটি পদ্ধতি সাফল্য পরিচালনা করে এবং অন্যটি ব্যর্থতা পরিচালনা করে, এবং ব্যর্থতার ফলাফল ব্যতিক্রমগুলি রিপোর্ট করে। আপনি যদি কলব্যাক ব্যবহার না করে ব্যতিক্রম হ্যান্ডলিং সহ কোরোটিন ব্যবহার করতে পারেন তবে আপনার কোডটি আরও দক্ষ এবং পড়া সহজ হবে। সুবিধামত, রেট্রোফিটের একটি লাইব্রেরি রয়েছে যা কোরোটিনগুলিকে একীভূত করে৷
 এই টাস্কে, আপনি আপনার নেটওয়ার্ক পরিষেবা এবং ViewModel coroutines ব্যবহার করতে রূপান্তর করেন। 
ধাপ 1: করোটিন নির্ভরতা যোগ করুন
- build.gradle খুলুন (মডিউল: অ্যাপ) ।
 - নির্ভরতা বিভাগে, কোর কোটলিন করোটিন লাইব্রেরি এবং রেট্রোফিট করোটিন লাইব্রেরির জন্য সমর্থন যোগ করুন:
 
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version_kotlin_coroutines" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version_kotlin_coroutines" implementation "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:$version_retrofit_coroutines_adapter"
- নতুন নির্ভরতার সাথে প্রকল্পটি পুনর্নির্মাণ করতে এখন সিঙ্ক এ ক্লিক করুন।
 
ধাপ 2: MarsApiService এবং OverviewViewModel আপডেট করুন
-  
MarsApiService.ktএ,CoroutineCallAdapterFactoryব্যবহার করতে Retrofit নির্মাতা আপডেট করুন। সম্পূর্ণ নির্মাতা এখন এই মত দেখায়: 
private val retrofit = Retrofit.Builder()
        .addConverterFactory(MoshiConverterFactory.create(moshi))
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
        .baseUrl(BASE_URL)
        .build()কল অ্যাডাপ্টারগুলি রেট্রোফিটের জন্য API তৈরি করার ক্ষমতা যুক্ত করে যা ডিফল্ট Call ক্লাস ছাড়া অন্য কিছু ফেরত দেয়। এই ক্ষেত্রে, CoroutineCallAdapterFactory আমাদের Call অবজেক্টটি প্রতিস্থাপন করতে দেয় যা getProperties() পরিবর্তে একটি Deferred অবজেক্ট দিয়ে রিটার্ন করে।
-  
getProperties()পদ্ধতিতে,Call<List<MarsProperty>>Deferred<List<MarsProperty>>এ পরিবর্তন করুন।kotlinx.coroutines.Deferredআমদানি করুন। অনুরোধ করা হলে স্থগিত করুন। সম্পূর্ণgetProperties()পদ্ধতি এই মত দেখায়: 
@GET("realestate")
fun getProperties():
   Deferred<List<MarsProperty>>Deferred ইন্টারফেস একটি coroutine কাজ সংজ্ঞায়িত করে যা একটি ফলাফলের মান প্রদান করে ( Deferred inherits from Job )। Deferred ইন্টারফেসে await() নামক একটি পদ্ধতি রয়েছে, যার ফলে মান প্রস্তুত না হওয়া পর্যন্ত আপনার কোডটিকে ব্লক না করে অপেক্ষা করতে হবে এবং তারপরে সেই মানটি ফেরত দেওয়া হবে।
-  
OverviewViewModel.ktখুলুন।initব্লকের ঠিক আগে, একটি coroutine কাজ যোগ করুন: 
private var viewModelJob = Job()- মূল প্রেরক ব্যবহার করে সেই নতুন কাজের জন্য একটি করুটিন সুযোগ তৈরি করুন:
 
private val coroutineScope = CoroutineScope(
   viewModelJob + Dispatchers.Main )Dispatchers.Main প্রেরক তার কাজের জন্য UI থ্রেড ব্যবহার করে। যেহেতু রেট্রোফিট তার সমস্ত কাজ একটি ব্যাকগ্রাউন্ড থ্রেডে করে, তাই সুযোগের জন্য অন্য কোন থ্রেড ব্যবহার করার কোন কারণ নেই। আপনি যখন ফলাফল পান তখন এটি আপনাকে সহজেই MutableLiveData এর মান আপডেট করতে দেয়।
-  
getMarsRealEstateProperties()ভিতরে থাকা সমস্ত কোড মুছুন। আপনিenqueue()এবংonFailure()এবংonResponse()কলব্যাকের পরিবর্তে এখানে coroutines ব্যবহার করবেন। -  
getMarsRealEstateProperties()ভিতরে, করুটিন চালু করুন: 
coroutineScope.launch { 
}
 নেটওয়ার্ক টাস্কের জন্য রেট্রোফিট যে Deferred অবজেক্টটি ফেরত দেয় তা ব্যবহার করতে, আপনাকে একটি করটিনের ভিতরে থাকতে হবে, তাই এখানে আপনি এইমাত্র তৈরি করা কোরুটিনটি চালু করবেন। আপনি এখনও মূল থ্রেডে কোড নির্বাহ করছেন, কিন্তু এখন আপনি coroutines কে একযোগে পরিচালনা করতে দিচ্ছেন।
-  লঞ্চ ব্লকের ভিতরে, 
retrofitServiceঅবজেক্টেgetProperties()কল করুন: 
var getPropertiesDeferred = MarsApi.retrofitService.getProperties()MarsApi পরিষেবা থেকে getProperties() কল করা একটি ব্যাকগ্রাউন্ড থ্রেডে নেটওয়ার্ক কল তৈরি করে এবং শুরু করে, সেই কাজের জন্য Deferred অবজেক্ট ফিরিয়ে দেয়।
-  এছাড়াও লঞ্চ ব্লকের ভিতরে, ব্যতিক্রমগুলি পরিচালনা করতে একটি 
try/catchব্লক যোগ করুন: 
try {
} catch (e: Exception) {
  
}-  
try {}ব্লকের ভিতরে,Deferredঅবজেক্টেawait()কল করুন: 
var listResult = getPropertiesDeferred.await()Deferred অবজেক্টে await() কল করা নেটওয়ার্ক কল থেকে ফলাফল প্রদান করে যখন মান প্রস্তুত থাকে। await() পদ্ধতিটি নন-ব্লকিং, তাই Mars API পরিষেবা বর্তমান থ্রেড ব্লক না করেই নেটওয়ার্ক থেকে ডেটা পুনরুদ্ধার করে—যা গুরুত্বপূর্ণ কারণ আমরা UI থ্রেডের সুযোগে আছি। একবার কাজটি হয়ে গেলে, আপনার কোডটি যেখান থেকে ছেড়েছিল সেখান থেকে কার্যকর করা অব্যাহত থাকে। এটি try {} ভিতরে রয়েছে যাতে আপনি ব্যতিক্রমগুলি ধরতে পারেন৷
-  এছাড়াও 
try {}ব্লকের ভিতরে,await()পদ্ধতির পরে, সফল প্রতিক্রিয়ার জন্য প্রতিক্রিয়া বার্তা আপডেট করুন: 
_response.value = 
   "Success: ${listResult.size} Mars properties retrieved"catch {}ব্লকের ভিতরে, ব্যর্থতার প্রতিক্রিয়া পরিচালনা করুন:
_response.value = "Failure: ${e.message}"
 সম্পূর্ণ getMarsRealEstateProperties() পদ্ধতি এখন এই মত দেখায়: 
private fun getMarsRealEstateProperties() {
   coroutineScope.launch {
       var getPropertiesDeferred = 
          MarsApi.retrofitService.getProperties()
       try {          
           _response.value = 
              "Success: ${listResult.size} Mars properties retrieved"
       } catch (e: Exception) {
           _response.value = "Failure: ${e.message}"
       }
   }
}- ক্লাসের নীচে, এই কোডের সাথে একটি 
onCleared()কলব্যাক যোগ করুন: 
override fun onCleared() {
   super.onCleared()
   viewModelJob.cancel()
}ViewModel ধ্বংস হয়ে গেলে ডেটা লোড করা বন্ধ করা উচিত, কারণ OverviewFragment যা এই ViewModel ব্যবহার করে তা চলে যাবে। ViewModel ধ্বংস হয়ে গেলে লোড হওয়া বন্ধ করতে, আপনি কাজটি বাতিল করতে onCleared() ওভাররাইড করেন।
- অ্যাপটি কম্পাইল করে রান করুন। আপনি আগের টাস্কের মতো এবারও একই ফলাফল পাবেন (সম্পত্তির সংখ্যার একটি প্রতিবেদন), তবে আরও সহজবোধ্য কোড এবং ত্রুটি পরিচালনার সাথে।
 
অ্যান্ড্রয়েড স্টুডিও প্রকল্প: MarsRealEstateNetwork
REST ওয়েব পরিষেবা
- একটি ওয়েব পরিষেবা হল ইন্টারনেটে এমন একটি পরিষেবা যা আপনার অ্যাপকে অনুরোধ করতে এবং ডেটা ফেরত পেতে সক্ষম করে৷
 - সাধারণ ওয়েব পরিষেবাগুলি একটি REST আর্কিটেকচার ব্যবহার করে। REST আর্কিটেকচার অফার করে এমন ওয়েব পরিষেবাগুলি RESTful পরিষেবা হিসাবে পরিচিত। RESTful ওয়েব পরিষেবাগুলি স্ট্যান্ডার্ড ওয়েব উপাদান এবং প্রোটোকল ব্যবহার করে তৈরি করা হয়।
 - আপনি URI-এর মাধ্যমে একটি প্রমিত উপায়ে একটি REST ওয়েব পরিষেবার কাছে একটি অনুরোধ করেন৷
 - একটি ওয়েব পরিষেবা ব্যবহার করতে, একটি অ্যাপকে অবশ্যই একটি নেটওয়ার্ক সংযোগ স্থাপন করতে হবে এবং পরিষেবাটির সাথে যোগাযোগ করতে হবে৷ তারপর অ্যাপটিকে অবশ্যই প্রতিক্রিয়া ডেটা গ্রহণ করতে হবে এবং অ্যাপটি ব্যবহার করতে পারে এমন ফর্ম্যাটে পার্স করতে হবে।
 - রেট্রোফিট লাইব্রেরি হল একটি ক্লায়েন্ট লাইব্রেরি যা আপনার অ্যাপকে একটি REST ওয়েব পরিষেবায় অনুরোধ করতে সক্ষম করে।
 -  রেট্রোফিটকে জানাতে কনভার্টার ব্যবহার করুন যে ডেটা এটি ওয়েব পরিষেবাতে পাঠায় এবং ওয়েব পরিষেবা থেকে ফিরে আসে। উদাহরণস্বরূপ, 
ScalarsConverterরূপান্তরকারী ওয়েব পরিষেবা ডেটাকেStringবা অন্যান্য আদিম হিসাবে বিবেচনা করে। -  আপনার অ্যাপটিকে ইন্টারনেটে সংযোগ করতে সক্ষম করতে, Android ম্যানিফেস্টে 
"android.permission.INTERNET"অনুমতি যোগ করুন। 
JSON পার্সিং
- একটি ওয়েব পরিষেবা থেকে প্রতিক্রিয়া প্রায়শই JSON- এ ফর্ম্যাট করা হয়, স্ট্রাকচার্ড ডেটা উপস্থাপনের জন্য একটি সাধারণ বিনিময় বিন্যাস৷
 - একটি JSON অবজেক্ট হল কী-মান জোড়ার একটি সংগ্রহ। এই সংগ্রহটিকে কখনও কখনও অভিধান , একটি হ্যাশ মানচিত্র , বা একটি সহযোগী অ্যারে বলা হয়।
 - JSON বস্তুর একটি সংগ্রহ একটি JSON অ্যারে। আপনি একটি ওয়েব পরিষেবা থেকে প্রতিক্রিয়া হিসাবে একটি JSON অ্যারে পাবেন।
 - একটি মূল-মান জোড়ার কীগুলি উদ্ধৃতি দ্বারা বেষ্টিত। মানগুলি সংখ্যা বা স্ট্রিং হতে পারে। স্ট্রিংগুলিও উদ্ধৃতি দ্বারা বেষ্টিত।
 - মোশি লাইব্রেরি হল Android JSON পার্সার যা একটি JSON স্ট্রিংকে Kotlin অবজেক্টে রূপান্তর করে। রেট্রোফিটের একটি কনভার্টার আছে যা মোশির সাথে কাজ করে।
 - মোশি একই নামের একটি ডেটা অবজেক্টের বৈশিষ্ট্যগুলির সাথে JSON প্রতিক্রিয়ার কীগুলিকে মেলে৷
 -  একটি কী-এর জন্য আলাদা প্রপার্টির নাম ব্যবহার করতে, 
@Jsonটীকা এবং JSON কী নামের সাথে সেই প্রপার্টিটি টীকা করুন। 
রেট্রোফিট এবং coroutines
-  কল অ্যাডাপ্টারগুলি রেট্রোফিটকে এমন API তৈরি করতে দেয় যা ডিফল্ট 
Callক্লাস ছাড়া অন্য কিছু ফেরত দেয়।Callপরিবর্তে একটি coroutineDeferredদিয়েCoroutineCallAdapterFactoryক্লাস ব্যবহার করুন। -  
Deferredঅবজেক্টেawait()পদ্ধতিটি ব্যবহার করুন যাতে মান প্রস্তুত না হওয়া পর্যন্ত আপনার coroutine কোডটিকে ব্লক না করে অপেক্ষা করতে হয় এবং তারপরে মানটি ফেরত দেওয়া হয়। 
উদাসীনতা কোর্স:
অ্যান্ড্রয়েড বিকাশকারী ডকুমেন্টেশন:
কোটলিন ডকুমেন্টেশন:
অন্যান্য:
এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:
- প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
 - শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
 - হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.
 
প্রশিক্ষকরা এই পরামর্শগুলি যতটা কম বা যতটা চান ততটা ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।
আপনি যদি নিজে থেকে এই কোডল্যাবের মাধ্যমে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলিকে নির্দ্বিধায় ব্যবহার করুন৷
এই প্রশ্নগুলোর উত্তর দাও
প্রশ্ন 1
একটি ওয়েব পরিষেবা API তৈরি করার জন্য রেট্রোফিটের দুটি মূল জিনিস কী কী?
 ▢ ওয়েব পরিষেবার জন্য ভিত্তি URI, এবং একটি GET ক্যোয়ারী।
▢ ওয়েব পরিষেবার জন্য ভিত্তি URI, এবং একটি রূপান্তরকারী কারখানা।
▢ ওয়েব পরিষেবাতে একটি নেটওয়ার্ক সংযোগ, এবং একটি অনুমোদন টোকেন৷
▢ একটি রূপান্তরকারী কারখানা, এবং প্রতিক্রিয়ার জন্য একটি পার্সার।
প্রশ্ন 2
মশি গ্রন্থাগারের উদ্দেশ্য কী?
▢ একটি ওয়েব পরিষেবা থেকে ডেটা ফেরত পেতে।
▢ একটি ওয়েব পরিষেবা অনুরোধ করতে রেট্রোফিটের সাথে যোগাযোগ করতে।
▢ কোটলিন ডেটা অবজেক্টে একটি ওয়েব পরিষেবা থেকে একটি JSON প্রতিক্রিয়া পার্স করতে।
▢ JSON প্রতিক্রিয়ার কীগুলির সাথে মেলে কোটলিন বস্তুর নাম পরিবর্তন করতে।
প্রশ্ন 3
Retrofit কল অ্যাডাপ্টার কি জন্য ব্যবহার করা হয়?
▢ তারা রেট্রোফিটকে কোরোটিন ব্যবহার করতে সক্ষম করে।
▢ তারা কোটলিন ডেটা অবজেক্টে ওয়েব পরিষেবার প্রতিক্রিয়া মানিয়ে নেয়।
▢ তারা একটি রেট্রোফিট কলকে একটি ওয়েব পরিষেবা কলে পরিবর্তন করে৷
 ▢ তারা রেট্রোফিটে ডিফল্ট Call ক্লাস ছাড়া অন্য কিছু ফেরত দেওয়ার ক্ষমতা যোগ করে। 
 পরবর্তী পাঠ শুরু করুন: 
এই কোর্সে অন্যান্য কোডল্যাবগুলির লিঙ্কগুলির জন্য, Android Kotlin Fundamentals codelabs ল্যান্ডিং পৃষ্ঠাটি দেখুন।