প্রক্রিয়া এবং থ্রেড ওভারভিউ

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

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

একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশনে প্রক্রিয়া এবং থ্রেডগুলি কীভাবে কাজ করে এই নথিটি আলোচনা করে৷

প্রসেস

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

প্রতিটি ধরনের উপাদান উপাদানের জন্য ম্যানিফেস্ট এন্ট্রি- <activity> , <service> , <receiver> , এবং <provider> — একটি android:process অ্যাট্রিবিউট সমর্থন করে যা কম্পোনেন্টটি চলার একটি প্রক্রিয়া নির্দিষ্ট করতে পারে। আপনি এই বৈশিষ্ট্যটি সেট করতে পারেন যাতে প্রতিটি উপাদান তার নিজস্ব প্রক্রিয়ায় চলে বা যাতে কিছু উপাদান একটি প্রক্রিয়া ভাগ করে যখন অন্যরা তা করে না।

এছাড়াও আপনি android:process সেট করতে পারেন যাতে বিভিন্ন অ্যাপ্লিকেশানের উপাদানগুলি একই প্রক্রিয়ায় চলে, শর্ত থাকে যে অ্যাপ্লিকেশনগুলি একই লিনাক্স ব্যবহারকারী আইডি ভাগ করে এবং একই শংসাপত্রের সাথে স্বাক্ষরিত হয়।

<application> উপাদানটি একটি android:process বৈশিষ্ট্যকেও সমর্থন করে, যা আপনি একটি ডিফল্ট মান সেট করতে ব্যবহার করতে পারেন যা সমস্ত উপাদানের জন্য প্রযোজ্য।

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

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

প্রক্রিয়া জীবনচক্রের বিশদ বিবরণ এবং অ্যাপ্লিকেশন স্টেটের সাথে এর সম্পর্ক প্রক্রিয়া এবং অ্যাপ লাইফসাইকেলে আলোচনা করা হয়েছে।

থ্রেড

যখন একটি অ্যাপ্লিকেশন চালু করা হয়, সিস্টেমটি অ্যাপ্লিকেশনটির জন্য কার্যকর করার একটি থ্রেড তৈরি করে, যাকে প্রধান থ্রেড বলা হয়। এই থ্রেডটি অত্যন্ত গুরুত্বপূর্ণ, কারণ এটি ইভেন্টগুলি অঙ্কন সহ উপযুক্ত ইউজার ইন্টারফেস উইজেটগুলিতে ইভেন্টগুলি প্রেরণের দায়িত্বে রয়েছে। এটি প্রায় সবসময়ই সেই থ্রেড যেখানে আপনার অ্যাপ্লিকেশনটি Android UI টুলকিটের android.widget এবং android.view প্যাকেজগুলির উপাদানগুলির সাথে ইন্টারঅ্যাক্ট করে৷ এই কারণে, প্রধান থ্রেডকে কখনও কখনও UI থ্রেড বলা হয়। যাইহোক, বিশেষ পরিস্থিতিতে, একটি অ্যাপের মূল থ্রেড তার UI থ্রেড নাও হতে পারে। আরও তথ্যের জন্য, থ্রেড টীকা দেখুন।

সিস্টেমটি একটি উপাদানের প্রতিটি উদাহরণের জন্য একটি পৃথক থ্রেড তৈরি করে না । একই প্রক্রিয়ায় চলা সমস্ত উপাদানগুলি UI থ্রেডে তাত্ক্ষণিক করা হয় এবং প্রতিটি উপাদানে সিস্টেম কলগুলি সেই থ্রেড থেকে প্রেরণ করা হয়। ফলস্বরূপ, পদ্ধতিগুলি যেগুলি সিস্টেম কলব্যাকগুলিতে সাড়া দেয় — যেমন onKeyDown() ব্যবহারকারীর অ্যাকশন রিপোর্ট করার জন্য, অথবা একটি লাইফসাইকেল কলব্যাক পদ্ধতি—সর্বদা প্রক্রিয়ার UI থ্রেডে চলে৷

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

আপনি যদি আপনার অ্যাপ্লিকেশনটি সঠিকভাবে বাস্তবায়ন না করেন, এই একক-থ্রেড মডেলটি খারাপ কর্মক্ষমতা দিতে পারে যখন আপনার অ্যাপ ব্যবহারকারীর ইন্টারঅ্যাকশনের প্রতিক্রিয়ায় নিবিড় কাজ করে। UI থ্রেডে দীর্ঘ ক্রিয়াকলাপ সম্পাদন করা, যেমন নেটওয়ার্ক অ্যাক্সেস বা ডাটাবেস কোয়েরি, পুরো UI ব্লক করে। থ্রেড ব্লক করা হলে, অঙ্কন ইভেন্ট সহ কোনো ইভেন্ট পাঠানো যাবে না।

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

মনে রাখবেন যে Android UI টুলকিট থ্রেড-নিরাপদ নয় । সুতরাং, কর্মী থ্রেড থেকে আপনার UI ম্যানিপুলেট করবেন না। UI থ্রেড থেকে আপনার ব্যবহারকারী ইন্টারফেসে সমস্ত ম্যানিপুলেশন করুন। অ্যান্ড্রয়েডের একক-থ্রেড মডেলের দুটি নিয়ম রয়েছে:

  1. UI থ্রেড ব্লক করবেন না।
  2. UI থ্রেডের বাইরে থেকে Android UI টুলকিট অ্যাক্সেস করবেন না।

শ্রমিক থ্রেড

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

আপনাকে এই নিয়মগুলি অনুসরণ করতে সাহায্য করার জন্য, Android অন্যান্য থ্রেড থেকে UI থ্রেড অ্যাক্সেস করার বিভিন্ন উপায় অফার করে৷ এখানে সাহায্য করতে পারে এমন পদ্ধতিগুলির একটি তালিকা রয়েছে:

নিম্নলিখিত উদাহরণ ব্যবহার করে View.post(Runnable) :

কোটলিন

fun onClick(v: View) {
    Thread(Runnable {
        // A potentially time consuming task.
        val bitmap = processBitMap("image.png")
        imageView.post {
            imageView.setImageBitmap(bitmap)
        }
    }).start()
}

জাভা

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // A potentially time consuming task.
            final Bitmap bitmap =
                    processBitMap("image.png");
            imageView.post(new Runnable() {
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

এই বাস্তবায়ন থ্রেড-নিরাপদ, কারণ ব্যাকগ্রাউন্ড অপারেশন একটি পৃথক থ্রেড থেকে করা হয় যখন ImageView সবসময় UI থ্রেড থেকে ম্যানিপুলেট করা হয়।

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

থ্রেড-নিরাপদ পদ্ধতি

কিছু পরিস্থিতিতে, আপনি যে পদ্ধতিগুলি প্রয়োগ করেন সেগুলি একাধিক থ্রেড থেকে বলা হয়, এবং তাই থ্রেড-নিরাপদ হতে লিখতে হবে।

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

উদাহরণস্বরূপ, যেখানে একটি পরিষেবার onBind() পদ্ধতি পরিষেবার প্রক্রিয়ার UI থ্রেড থেকে কল করা হয়, সেখানে অবজেক্টে প্রয়োগ করা পদ্ধতিগুলি যা onBind() রিটার্ন করে, যেমন একটি সাবক্লাস যা দূরবর্তী পদ্ধতি কল (RPC) পদ্ধতি প্রয়োগ করে, থ্রেড থেকে কল করা হয় পুলের মধ্যে যেহেতু একটি পরিষেবাতে একাধিক ক্লায়েন্ট থাকতে পারে, একই সময়ে একাধিক পুল থ্রেড একই IBinder পদ্ধতিতে যুক্ত হতে পারে, তাই থ্রেড-নিরাপদ হতে IBinder পদ্ধতিগুলি অবশ্যই প্রয়োগ করতে হবে।

একইভাবে, একটি বিষয়বস্তু প্রদানকারী ডেটা অনুরোধগুলি গ্রহণ করতে পারে যা অন্যান্য প্রক্রিয়ায় উদ্ভূত হয়। ContentResolver এবং ContentProvider ক্লাসগুলি কীভাবে ইন্টারপ্রসেস কমিউনিকেশন (IPC) পরিচালিত হয় তার বিশদ বিবরণ লুকিয়ে রাখে, কিন্তু ContentProvider পদ্ধতিগুলি যেগুলি সেই অনুরোধগুলিতে সাড়া দেয়- পদ্ধতিগুলি query() , insert() , delete() , update() , এবং getType() —কন্টেন্ট প্রদানকারীর প্রক্রিয়ায় থ্রেডের পুল থেকে ডাকা হয়, প্রক্রিয়াটির জন্য UI থ্রেড নয়। যেহেতু এই পদ্ধতিগুলি একই সময়ে যে কোনও সংখ্যক থ্রেড থেকে কল করা যেতে পারে, সেগুলিকেও থ্রেড-নিরাপদ হতে প্রয়োগ করতে হবে।

আন্তঃপ্রক্রিয়া যোগাযোগ

অ্যান্ড্রয়েড RPCs ব্যবহার করে IPC-এর জন্য একটি পদ্ধতি অফার করে, যেখানে একটি পদ্ধতি একটি কার্যকলাপ বা অন্যান্য অ্যাপ্লিকেশন উপাদান দ্বারা কল করা হয় কিন্তু অন্য প্রক্রিয়ায় দূরবর্তীভাবে কার্যকর করা হয়, যেকোনো ফলাফল কলারের কাছে ফিরে আসে। এটি একটি মেথড কল এবং এর ডেটাকে অপারেটিং সিস্টেম বুঝতে পারে এমন একটি স্তরে বিচ্যুত করে, স্থানীয় প্রক্রিয়া এবং ঠিকানা স্থান থেকে দূরবর্তী প্রক্রিয়া এবং ঠিকানা স্থানে প্রেরণ করে এবং তারপর সেখানে কলটিকে পুনরায় একত্রিত করে এবং পুনরায় সক্রিয় করে।

রিটার্ন মান তারপর বিপরীত দিকে প্রেরণ করা হয়. এই আইপিসি লেনদেনগুলি সম্পাদন করার জন্য অ্যান্ড্রয়েড সমস্ত কোড সরবরাহ করে, তাই আপনি RPC প্রোগ্রামিং ইন্টারফেস সংজ্ঞায়িত এবং বাস্তবায়নের উপর ফোকাস করতে পারেন।

IPC সঞ্চালনের জন্য, আপনার অ্যাপ্লিকেশনটিকে অবশ্যই bindService() ব্যবহার করে একটি পরিষেবার সাথে আবদ্ধ হতে হবে। আরও তথ্যের জন্য, পরিষেবার ওভারভিউ দেখুন।