অ্যান্ড্রয়েড: আমার কখন হ্যান্ডলার ব্যবহার করা উচিত () এবং কখন আমার কোনও থ্রেড ব্যবহার করা উচিত?


129

যখন অ্যাসিঙ্ক্রোনালি চালানোর জন্য যখন আমার কিছু প্রয়োজন , যেমন একটি দীর্ঘ চলমান কাজ বা নেটওয়ার্ক যুক্ত যুক্তিযুক্ত যুক্তি, বা যে কোনও কারণের জন্য, একটি নতুন থ্রেড শুরু করা এবং এটি চালানো ভাল কাজ করে। হ্যান্ডলার তৈরি করা এবং এটি চালানোও কাজ করে। পার্থক্য কি? আমি যখন প্রতিটি ব্যবহার করা উচিত? একটি Handlerএবং না ব্যবহারের সুবিধা / কারণগুলি কী কী Thread?

পুনশ্চ. - এই প্রশ্নের খাতিরে, আসুন উপেক্ষা করা যাক AsyncTask। - Handler().postDelayedব্যবহারের বিষয়টি আমার কাছে স্পষ্ট, এই প্রশ্নের খাতিরে ধরে নেওয়া যাক অবিলম্বে আমার কাজটি শুরু করা দরকার।


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

1
@ কবুতু 178 ভাল, হ্যান্ডলারের অন্যান্য সুবিধা রয়েছে যা উল্লেখযোগ্য নয় যে আপনি এড়িয়ে গেছেন। যেমন, পৃথক থ্রেড থেকে ইউআই থ্রেডের সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হয়ে ..
tony9099

উত্তর:


168

আপনি যা করছেন তা যদি "ভারী" হয় তবে আপনার এটি থ্রেডে করা উচিত। যদি আপনি এটিকে স্পষ্টভাবে তার নিজস্ব থ্রেডে শুরু না করেন, তবে এটি মূল (ইউআই) থ্রেডে চলবে যা আপনার ব্যবহারকারীদের দ্বারা ইন্টারফেসের প্রতিক্রিয়া হিসাবে ধীরগতিযুক্ত বা ধীর হতে পারে।

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

একটি সাধারণ থ্রেড / হ্যান্ডলার ইন্টারঅ্যাকশনটি এর মতো দেখতে পারে:

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            updateUI();
        }else{
            showErrorDialog();
        }
    }
};

Thread t = new Thread() {
    @Override
    public void run(){
        doSomeWork();
        if(succeed){
            //we can't update the UI from here so we'll signal our handler and it will do it for us.
            h.sendEmptyMessage(0);
        }else{
            h.sendEmptyMessage(1);
        }
    }   
};

যদিও সাধারণভাবে গৃহীত হয় তা হ'ল দীর্ঘ সময় ধরে চলমান বা খুব নিবিড় (যেমন কোনও নেটওয়ার্ক, ফাইল আইও, ভারী পাটিগণিত ইত্যাদি) কাজ করার সময় আপনার কোনও থ্রেড ব্যবহার করা উচিত।


দ্রুত উত্তর এবং সময় যে পরিমাণ বিনিয়োগ করেছে (এবং আপনার জবাবের গতি !!) এর জন্য ধন্যবাদ! সুতরাং, আমি এটি পেয়েছি কিনা তা আমাকে দেখতে দিন: হ্যান্ডলারটি কর্মী থ্রেড এবং ইউআই থ্রেডের মধ্যে অ-ব্লকিং যোগাযোগের সুবিধার জন্য ডিজাইন করা হয়েছে?
জেআরুন

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

@ ফোম্যগুই সুন্দরভাবে ব্যাখ্যা করেছেন!
tony9099

হাই, এটি কি নিশ্চিত যে এটি updateUI()পরে চলবে onCreateView(নতুন মতামত লোড হওয়ার পরে)?
Zyoo

1
এটা কেন message.what()? এটা ঠিক হবে না if(msg == 0){? অনেক ধন্যবাদ! :)
রুচির বড়োনিয়া

64

হ্যান্ডলার এবং থ্রেড আসলে 2 ভিন্ন জিনিস।

দীর্ঘ চলমান কাজগুলি সম্পাদন করতে একটি থ্রেড তৈরি করতে হবে।

একটি হ্যান্ডলার 2 থ্রেডের মধ্যে যোগাযোগের জন্য খুব সুবিধাজনক অবজেক্ট (উদাহরণস্বরূপ: একটি পটভূমি থ্রেডটি ইউআই আপডেট করতে হবে You আপনি আপনার ব্যাকগ্রাউন্ড থ্রেড থেকে ইউআই থ্রেডে কিছু রান্নেবল পোস্ট করতে হ্যান্ডলারটি ব্যবহার করতে পারেন)।

সুতরাং হ্যান্ডলার বা থ্রেডের মধ্যে আপনার পছন্দ নেই। ভারী কাজ করতে একটি থ্রেড ব্যবহার করুন! (যদি আপনার পটভূমি থ্রেডটি অন্য থ্রেডে কিছু কাজ করার জন্য ট্রিগার করে - আপনি বেশিরভাগ সময় ইউআই থ্রেড ব্যবহার করতে পারেন)


দ্রুত উত্তর এবং সময় যে পরিমাণ বিনিয়োগ করেছে (এবং আপনার জবাবের গতি !!) এর জন্য ধন্যবাদ!
জেআরুন

28

Handlerএবং Threadদুটি ভিন্ন জিনিস, তবে তারা একে অপরের বিরোধিতা করে না। আপনার একই সাথে একটি Handlerএবং একটি থাকতে পারে Threadএবং প্রকৃতপক্ষে প্রতিটি Handlerঅবশ্যই একটিতে চলছে Thread

আরও বিশদের জন্য, আপনি এই নিবন্ধটি চেক করতে চাইতে পারেন ।

এখানে চিত্র বর্ণনা লিখুন


19

একজন Handlerএকই রানে Thread, একটি Threadএকটি ভিন্ন থ্রেডে চলে।

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

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


6
আমি যদি একই থ্রেডে কিছু চালাতে চাই তবে কেন হ্যান্ডলারটি ব্যবহার করব? mHandler.post (...) পদ্ধতির উদ্দেশ্য কী?
ইলিয়াস

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

14

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

ব্যবহার:

থ্রেড: ইউআই থ্রেডের চেয়ে আলাদা (ব্যাকগ্রাউন্ড) থ্রেডে কাজ করা। (ইউআই থ্রেড অবরোধ মুক্ত করতে সহায়তা করে)

হ্যান্ডলারটি ইউআই এবং পটভূমির থ্রেডের মধ্যে যোগাযোগের জন্য ব্যবহৃত হয়।

এই নিবন্ধটি দেখুন


4

যদি আপনাকে নতুন থ্রেড থেকে ইউজার ইন্টারফেস আপডেট করতে হয় তবে আপনাকে ইউজার ইন্টারফেস থ্রেডের সাথে সিঙ্ক্রোনাইজ করতে হবে।

আপনি এর জন্য android.os.Handler ক্লাস বা AsyncTasks বর্গ ব্যবহার করতে পারেন।

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

আপনি থ্রেডটি সেন্ডম্যাসেজ (বার্তা _) পদ্ধতির মাধ্যমে বা সেন্ডএম্পটিমেসেজ () পদ্ধতির মাধ্যমে বার্তা পোস্ট করতে পারেন।

থ্রেড ইত্যাদি সম্পর্কে এখানে আরও তথ্য (বিভিন্ন থ্রেডিং এবং সিঙ্ক মেকানিজমের জন্য টিউরিওরিজ এবং কখন কী ব্যবহার করবেন) অন্তর্ভুক্ত রয়েছে


আমার প্রশ্নের উত্তর দিতে সময় দেওয়ার জন্য ধন্যবাদ। আমি লার্স ভোগেলের ব্লগটি পছন্দ করি, এটি অত্যন্ত অন্তর্দৃষ্টিপূর্ণ এবং অনুসরণযোগ্য easy ধন্যবাদ!
JRun

2

কোনও হ্যান্ডলার ব্যবহার করার সুবিধা এবং কারণগুলি কী এবং কোনও থ্রেড নয়?

একটি হ্যান্ডলার আপনাকে Runnableকোনও থ্রেডের সাথে সম্পর্কিত বার্তা এবং অবজেক্টগুলি প্রেরণ এবং প্রক্রিয়া করার অনুমতি দেয় MessageQueue। প্রতিটি Handlerউদাহরণ একক থ্রেড এবং সেই থ্রেডের বার্তার সারিটির সাথে সম্পর্কিত।

আপনি যখন একটি নতুন তৈরি করেন Handler, এটি যে থ্রেডটি তৈরি করছে তার থ্রেড / বার্তা সারিতে আবদ্ধ - সেদিক থেকে এটি বার্তাগুলি এবং রানবেলগুলি সেই বার্তার কাতারে পৌঁছে দেবে এবং বার্তা সারি থেকে বেরিয়ে আসার সাথে সাথে তাদের সম্পাদন করবে ।

হ্যান্ডলারের জন্য দুটি প্রধান ব্যবহার রয়েছে:

  1. ভবিষ্যতে কিছু বিষয় হিসাবে বার্তাগুলি এবং রান্নেবলগুলি নির্বাহ করা হবে schedule
  2. করার সারিবদ্ধ একটি কর্ম আপনার নিজের চেয়ে ভিন্ন থ্রেডে সম্পাদন করা যায়।

আপনি যদি জাভা থ্রেড ব্যবহার করেন তবে আপনাকে নিজের থেকে কিছু কিছু পরিচালনা করতে হবে - মূল থ্রেডের সাথে সিঙ্ক্রোনাইজ করা, কোনও থ্রেড বাতিল করা ইত্যাদি

এই একক থ্রেডটি থ্রেড পুল তৈরি করে না আপনি যদি না ব্যবহার করেন ThreadPoolExecutorবা ExecutorServiceএপিআই না করেন।

(ব্ল্যাকবেল্ট উত্তরের উপর আপনার মন্তব্যগুলি থেকে এই প্রশ্নটি নেওয়া)

এক্সিকিউটর ব্যবহার করবেন না কেন? এবং এমনকি যদি আমি হ্যান্ডলারটি এটি করতে ব্যবহার করতে চাইতাম তবে কীভাবে?

তথ্যসূত্র: থ্রেড পারফরম্যান্স নিবন্ধ

কিছু নির্দিষ্ট ধরণের কাজ রয়েছে যা অত্যন্ত সমান্তরাল, বিতরণকৃত কার্যগুলিতে হ্রাস করা যেতে পারে। কাজের প্যাকেটের নিখুঁত ভলিউম সহ এটি তৈরি হয় AsyncTaskএবং HandlerThreadউপযুক্ত ক্লাস হয় না। এর একক AsyncTaskথ্রেডযুক্ত প্রকৃতি সমস্ত থ্রেডপুল করা কাজকে একটি রৈখিক সিস্টেমে রূপান্তরিত করে। অন্যদিকে HandlerThreadক্লাসটি ব্যবহার করে প্রোগ্রামারকে ম্যানুয়ালি থ্রেডের একটি গ্রুপের মধ্যে লোড ভারসাম্য পরিচালনা করতে হবে।

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

 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

আপনি আরও বিশদের জন্য তৈরি-থ্রেডপুলে এই বিকাশকারী গাইড নিবন্ধটি উল্লেখ করতে পারেন ।

Handlerএকাধিক চলমান উদাহরণগুলি চালনার জন্য এই পোস্টটি একবার দেখুন । এই ক্ষেত্রে, সমস্ত Runnableকাজ একক থ্রেডে চলবে।

অ্যান্ড্রয়েড: একটি থ্রেড টোস্ট


1

HandlerThreadএকটি সারিবদ্ধ প্রক্রিয়া তৈরির সাথে একত্রে ব্যবহার করা যেতে পারে । আপনি কিছুতে handlerপোস্ট করতে ব্যবহার করতে পারেনThread Looper


আমার প্রশ্নের উত্তর দিতে সময় দেওয়ার জন্য ধন্যবাদ। এক্সিকিউটর ব্যবহার করবেন না কেন? এবং এমনকি যদি আমি হ্যান্ডলারটি এটি করতে ব্যবহার করতে চাইতাম তবে কীভাবে?
জেআরুন

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