কয়েক বছর আগে, গুগল ডেটাস্টোর ঘোষণা করেছিল, যা চেষ্টা করা এবং সত্য শেয়ার করা পছন্দগুলির প্রতিস্থাপন।
আপনি যদি আপনার অ্যাপ্লিকেশানগুলিতে SharedPreferences ব্যবহার করেন বা ব্যবহার করেন, আপনি হয়ত সুইচ করার কথা ভাবছেন। কিন্তু সবকিছুর মতো, এখানে প্রধান প্রশ্ন হল:উন্নয়নে খরচ কী হতে চলেছে?
ডেটাস্টোর ব্যবহার করার সুবিধা রয়েছে, তবে শুধুমাত্র প্রোটো ডেটাস্টোর টাইপ নিরাপত্তা প্রদান করার সময় আপনি বস্তু সংরক্ষণ করতে পারবেন.
আপনি যদি প্রোটো ডেটাস্টোরের ডকুমেন্টেশন দেখেন, আপনি দেখতে পাবেন যে এটি কিছুটা পুরানো এবং এটির সাথে কাজ করার সময় কিছু গুরুত্বপূর্ণ পদক্ষেপ অনুপস্থিত। তাই, এই প্রবন্ধে, আমরা কীভাবে আপনার অ্যাপ্লিকেশনে প্রোটো ডেটাস্টোরকে একীভূত করব এবং দেখাব যে এটি ব্যবহার করা এত বড় ঝামেলা নয়৷
ডেটাস্টোর কি?
জেটপ্যাক ডেটাস্টোরের দুটি রূপ রয়েছে:
- পছন্দের ডেটাস্টোর
- প্রোটো ডেটাস্টোর
আমরা প্রথমটি নিয়ে আলোচনা করব না, কারণ এটি শেয়ারডপ্রেফারেন্সের সাথে মিল রয়েছে এবং এটি ব্যাপকভাবে কভার করা হয়েছে। তাহলে এখন আসুন জেনে নেই প্রোটো ডেটাস্টোরে প্রোটো বলতে কী বোঝায়।
প্রোটো হল প্রোটোকল বাফারের প্রতিনিধিত্ব করার জন্য Google বেছে নেওয়া নাম। এগুলি হল (গুগলের) মেকানিজম যা আপনাকে স্ট্রাকচার্ড ডেটা সিরিয়ালাইজ করতে সাহায্য করে। এগুলি ভাষা-নির্দিষ্ট কোডিং নয় এবং সাধারণভাবে, আপনি যে ধরনের ডেটা নিয়ে কাজ করতে চান তা আপনি নির্ধারণ করেন এবং তারপর কোড তৈরি হয় যা আপনাকে আপনার ডেটা পড়তে এবং লিখতে সহায়তা করে৷
✋ আমরা এই নিবন্ধে প্রোটো 3 সংস্করণ ব্যবহার করব৷
৷সেই সংজ্ঞাটি কেমন দেখাচ্ছে?
message MyItem {
string itemName = 1;
int32 itemId = 2;
}
প্রথমত, আপনি বার্তা কীওয়ার্ড দিয়ে একটি বস্তুকে সংজ্ঞায়িত করুন। এটির ভিতরে, আপনি সেই বস্তুর সাথে যুক্ত ক্ষেত্রগুলি তালিকাভুক্ত করুন। প্রতিটি ক্ষেত্রের শেষে নম্বরগুলি ক্ষেত্রটি নিজেই সনাক্ত করতে ব্যবহৃত হয় এবং সেট করার পরে এবং অবজেক্টটি ব্যবহার করা হলে পরিবর্তন করা যাবে না .
কিন্তু যদি আমরা আমাদের .proto ফাইলে একাধিক অবজেক্ট রাখতে চাই? অবজেক্টগুলি একে অপরের সাথে সম্পর্কিত বলে ধরে নিলে, আপনি আরও বার্তা বস্তু যোগ করে এটি করতে পারেন:
message MyItem {
string itemName = 1;
int32 itemId = 2;
}
message MyListOfItems {
repeated MyItem items = 1;
}
লক্ষ্য করুন যে উপরে আমরা আরেকটি বার্তা অবজেক্ট যোগ করেছি যা উপরে সংজ্ঞায়িত MyItem অবজেক্টের উপর নির্ভর করে। আপনি যদি বস্তুর একটি তালিকা সংজ্ঞায়িত করতে চান, তাহলে আপনাকে পুনরাবৃত্তি ব্যবহার করতে হবে কীওয়ার্ড।
কিভাবে প্রোটো ডেটাস্টোর সেট আপ করবেন
শুরু করার জন্য, আপনাকে আপনার অ্যাপ্লিকেশন স্তর বিল্ড.গ্রেডলে নিম্নলিখিত নির্ভরতা যোগ করতে হবে:
implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.18.0"
তারপরে, আপনাকে আপনার প্রকল্পের ভিতরে একটি প্রোটো ডিরেক্টরি তৈরি করতে হবে। এই ডিরেক্টরিটি আপনার প্রজেক্ট স্ট্রাকচারের জাভা ফোল্ডারের ভাইবোন হতে হবে।
প্রোটো ডিরেক্টরির ভিতরে, আপনি একটি .proto ফাইল তৈরি করবেন। এই ফাইলটি প্রোটো ডেটাস্টোরে আপনি যে ধরনের ডেটা সঞ্চয় করতে চান তা তৈরি করার জন্য দায়ী৷
৷
প্রোটো ডিরেক্টরির ভিতরে, .proto এক্সটেনশন দিয়ে একটি ফাইল তৈরি করুন। আমাদের .proto ফাইলটি টোডো তালিকার প্রতিনিধিত্বকারী বস্তু ধারণ করবে (আর কি?)। তাই আমরা আমাদের ফাইলকে কল করব todo.proto এবং এটি এই মত দেখাবে:
syntax = "proto3";
option java_package = "com.yourPackageName.todo";
option java_multiple_files = true;
message TodoItem {
string itemId = 1;
string itemDescription = 2;
}
message TodoItems {
repeated TodoItem items = 1;
}
লক্ষ্য করুন কিভাবে আমরা দুটি বার্তা বস্তুকে সংজ্ঞায়িত করেছি:
- TodoItem - যা একটি করণীয় আইটেমকে সংজ্ঞায়িত করে
- TodoItems - যা TodoItem অবজেক্টের একটি তালিকা নির্ধারণ করে
এরপরে, প্রকল্পটি তৈরি করুন যাতে TodoItem এবং TodoItems-এর জন্য ক্লাস তৈরি করা হয়।
আমাদের ডেটা অবজেক্টগুলিকে সংজ্ঞায়িত করার পরে, সেগুলিকে সিরিয়াল করার জন্য আমাদের একটি ক্লাস তৈরি করতে হবে। এই ক্লাসটি ডেটাস্টোরকে বলবে কিভাবে আমাদের অবজেক্ট পড়তে/লিখতে হয়।
// 1
object TodoItemSerializer: Serializer<TodoItems> {
// 2
override val defaultValue: TodoItems = TodoItems.getDefaultInstance()
// 3
override suspend fun readFrom(input: InputStream): TodoItems {
try {
return TodoItems.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
// 3
override suspend fun writeTo(
t: TodoItems,
output: OutputStream
) = t.writeTo(output)
}
এই ক্লাসে আমাদের কী আছে তা পর্যালোচনা করা যাক:
- যখন আমরা ক্লাস ঘোষণা করি, তখন আমাদের সিরিয়ালাইজার বাস্তবায়ন করতে হবে টাইপ (T) হিসাবে আমাদের অবজেক্টের সাথে ইন্টারফেস
- ফাইলটি তৈরি না হলে আমরা সিরিয়ালাইজারের জন্য একটি ডিফল্ট মান সংজ্ঞায়িত করি
- আমরা readFrom/writeTo পদ্ধতিগুলিকে ওভাররাইড করি এবং আমরা নিশ্চিত করি যে সেখানে ডেটা টাইপ হিসাবে আমাদের অবজেক্ট রয়েছে
আমাদের ডাটা টাইপ এবং আমাদের সিরিয়ালাইজার সহ আমাদের .proto ফাইল আছে, তাই পরবর্তী ধাপ হল DataStore ইনস্ট্যান্টিয়েট করা। আমরা ডেটাস্টোর দ্বারা তৈরি সম্পত্তি প্রতিনিধি ব্যবহার করে এটি করি, যার জন্য একটি ফাইলের নাম দেওয়া প্রয়োজন যেখানে আমাদের ডেটা সংরক্ষণ করা হবে এবং আমাদের সিরিয়ালাইজার ক্লাস (যা আমরা উপরে সংজ্ঞায়িত করেছি)।
private const val DATA_STORE_FILE_NAME = "todo.pb"
private val Context.todoItemDatastore: DataStore<TodoItems> by dataStore(
fileName = DATA_STORE_FILE_NAME,
serializer = TodoItemSerializer,
)
কোডের এই অংশটি আপনার পছন্দের একটি ক্লাসের শীর্ষে থাকা দরকার ক্লাসের সংজ্ঞার উপরে। সেটি হল:
private const val DATA_STORE_FILE_NAME = "todo.pb"
private val Context.todoItemDatastore: DataStore<TodoItems> by dataStore(
fileName = DATA_STORE_FILE_NAME,
serializer = TodoItemSerializer,
)
class YourClassName {
}
আমাদের বাকি অ্যাপ্লিকেশনটিতে এই বস্তুটি অ্যাক্সেস করতে, আমাদের একটি প্রসঙ্গ ব্যবহার করতে হবে। একটি উদাহরণ হল আপনার ভিউমডেল ক্লাসে অ্যাপ্লিকেশন প্রসঙ্গ ব্যবহার করা:
class MyViewModel(application: Application): AndroidViewModel(application) {
val todoDataStore = application.todoItemDataStore
//...
}
কোটলিন ফ্লো কীভাবে ব্যবহার করবেন
এখন যেহেতু আমরা আমাদের ডেটাস্টোরের জন্য প্রয়োজনীয় সমস্ত কিছু সেট আপ করার মধ্য দিয়ে চলেছি, আমরা আসলে এটির সাথে কীভাবে ইন্টারঅ্যাক্ট করতে যাচ্ছি তা নিয়ে আলোচনা করব। আমরা এটিতে/থেকে ডেটা পড়তে এবং লিখতে চাই। কিন্তু আমরা যেভাবে তা করতে পারি তা শেয়ারডপ্রেফারেন্স থেকে আপনি যা জানেন তার থেকে আলাদা৷
আমরা উপরে সংজ্ঞায়িত ডেটাস্টোরটিতে একটি ডেটা ক্ষেত্র রয়েছে যা আমাদের ডেটাস্টোরে সংজ্ঞায়িত বৈশিষ্ট্যগুলির জন্য একটি প্রবাহ প্রকাশ করে৷
🚰 আপনি যদি প্রবাহের সাথে পরিচিত না হন তবে এটি শুরু করার জন্য একটি ভাল জায়গা।
val todoItemFlow: Flow<TodoItems> = todoItemDataStore.data
.catch { exception ->
if (exception is IOException) {
emit(TodoItems.getDefaultInstance())
} else {
throw exception
}
}
উপরের কোডটি দেখায় যে আপনি কীভাবে একটি ফ্লোকে সংজ্ঞায়িত করতে পারেন যা প্রোটো ডেটাস্টোর থেকে ডেটা সংগ্রহ করে। ব্যতিক্রম ঘটলে একটি ক্যাচ ব্লক যোগ করা হয়েছে। আপনি এই যুক্তিটিকে ক্লাসে রাখতে পারেন যেখানে আপনি আপনার ডেটাস্টোরকে সংজ্ঞায়িত করেছেন এবং আপনার ভিউমডেলের মতো এটি ব্যবহার করতে পারেন:
val todoItemsFlow: LiveData<TodoItems> = todoItemsRepository.todoItemFlow.asLiveData()
লক্ষ্য করুন কিভাবে আমরা আমাদের ফ্লোকে লাইভডেটাতে রূপান্তর করেছি। আমরা দুটি কারণে এটি করেছি:
- এগুলি ব্যবহার করে এমন কার্যকলাপ/খণ্ড নির্বিশেষে প্রবাহ সক্রিয় থাকতে পারে
- লাইভডেটা অনেক ডেভেলপারদের কাছে পরিচিত কিছু, এবং আমি এই উদাহরণটিকে যতটা সম্ভব সহজ করতে চেয়েছিলাম
এটি করতে সক্ষম হওয়ার জন্য, আপনাকে আপনার build.gradle ফাইলে নিম্নলিখিত নির্ভরতা যোগ করতে হবে:
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
আপনার অ্যাক্টিভিটি/ফ্র্যাগমেন্ট ক্লাসে, আপনি এই লাইভ ডেটা দেখতে পারেন:
myViewModel.todoItemFlow.observe(LocalLifecycleOwner.current) { todoItems ->
// Logic to access data from DataStore
}
কেন এবং কখন ডেটাস্টোর ব্যবহার করবেন
আমরা সবকিছু পর্যালোচনা করার পরে, ঘরের হাতি সম্পর্কে কথা বলার সময় এসেছে। আপনি কি এগিয়ে যান এবং আপনার বিদ্যমান বা পরবর্তী প্রকল্পে ডেটাস্টোর (হয় পছন্দ বা প্রোটো) ব্যবহার করবেন?
আমার মতে, উত্তরটি হ্যাঁ হওয়া উচিত . Google SharedPreferences থেকে দূরে সরে যাওয়ার পাশাপাশি, DataStore আপনাকে আপনার অ্যাপ্লিকেশনের উপর ফোকাস করতে সাহায্য করার জন্য প্রচুর সুবিধা প্রদান করে এবং আপনার ডেটার স্থিরতা নয়।
UI থ্রেড থেকে ডেটাস্টোরের সাথে ইন্টারঅ্যাক্ট করা নিরাপদ (যেহেতু এটি স্বয়ংক্রিয়ভাবে কাজকে I/O-তে নিয়ে যায়), এবং এটি আপনাকে ফ্লো ব্যবহার করতে বাধ্য করে (যদি আপনি এখনও না থাকেন) এবং এর মধ্যে থাকা সমস্ত সুবিধা উপভোগ করুন। ShareedPreferences থেকে Preferences DataStore এ সহজে মাইগ্রেট করার বিকল্পও রয়েছে।
আপনি যদি প্রোটো ডেটাস্টোরের পরিবর্তে রুম ব্যবহার করার কথা ভাবছেন, তবে এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। আপনি যে পরিমাণ ডেটা সংরক্ষণ করতে যাচ্ছেন (বা অব্যাহত) তা যদি খুব কম হয় এবং আংশিক আপডেট করার প্রয়োজন না হয়, তবে প্রোটো ডেটাস্টোরই যাওয়ার উপায়। যদি আপনার কাছে একটি বড় ডেটা সেট থাকে বা জটিল হতে পারে তবে আপনার পরিবর্তে রুম ব্যবহার করা বেছে নেওয়া উচিত।
আপনি যদি একটি অ্যাপ্লিকেশনে এই সমস্ত কোড দেখতে কেমন তা দেখতে চান, আপনি এটি এখানে দেখতে পারেন:
আপনি যদি আমার লেখা অন্য নিবন্ধগুলি পড়তে চান তবে আপনি সেগুলি এখানে দেখতে পারেন:
পড়ার জন্য ধন্যবাদ!
তথ্যসূত্র:
- প্রোটোকল বাফার ডকুমেন্টেশন (প্রোটো 3)
- প্রোটো ডেটাস্টোর কোডল্যাবের সাথে কাজ করা
- ডেটাস্টোর ডকুমেন্টেশন
বিনামূল্যে কোড শিখুন. freeCodeCamp-এর ওপেন সোর্স পাঠ্যক্রম 40,000-এরও বেশি লোককে ডেভেলপার হিসেবে চাকরি পেতে সাহায্য করেছে। শুরু করুন