با سلام، ممکنه برای خیلی ها این سوال پیش اومده باشه که از هرکدوم از Handler یا Thread یا AsycTask استفاده کرده باشیم و لی در حقیقت تفاوت میان آنها را به درستی نشناسیم. در این مقاله می خواهیم این تفاوت ها و محل مناسب استفاده از هر یک را برسی کنیم.
اول لازم هست تا با تعریف هرکدام بیشتر آشنا شویم.
Thread
A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
ترد یا رشته واحد های کلی پردازش وظایف هستند که هر برنامه می تواند تعدادی ترد داشته باشد. هر ترد اولویتی در سیستم دارد و تردهای ایجاد شده توسط یک ترد دیگر، اولویت هم سطح خواهند داشت. در اندروید هر برنامه یک ترد اصلی یا Main thread دارد و وقتی thread جدیدی ایجاد می کنیم پردازش ها جدا از اتفاقات ترد اصلی روی می دهد. اما برای هماهنگ کردن و یا به عنوان مثال بازگشت جواب باید اینکار را بصورت دستی توسط message یا callback مدیریت کنیم. ( مقاله کامل در اینجا) در صورتی که اگر تردی ایجاد کنیم دستورالعمل های آن باعث freeze شدن برنامه نمی شود زیرا در یک ترد دیگری جاریست اما در عوض به عناصر UI که در ترد اصلی هستند دسترسی نداریم و نمی توانیم بطور مستقیم UI را تغییر دهیم.
1 2 3 4 5 6 |
new Thread(new Runnable() { @Override public void run() { doSomething(); } }).start(); |
Handler
A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it — from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue
طبق تعریف خود گوگل با تعریف یک هندلر می توانیم پیغام یا Runnable ای را پردازش کنیم که دقیقاً در thread کلاس تولید کننده آن قرار می گیرد و نحوه اجرا شدن آن هم به صف همان thread بستگی دارد. پس یعنی Handler های تولید شده در یک thread به ترتیب در همان thread اجرا می شوند. دستورالعمل هایی که در Handler اجرا می شوند در thread اصلی بوده و اصطلاحاً باعث freeze شدن برنامه می شود. اما اگر در ترد اصلی تولید شوند به عناصر UI برنامه دسترسی داریم و مثلا می توانیم یک ViewText ای را بروز رسانی کنیم.
1 2 3 4 5 6 |
new Handler().post(new Runnable() { @Override public void run() { doSomething(); } }); |
بطور معمول وقتی از Handler استفاده می کنیم که بخواهیم اتفاق خاصی در زمان خاصی بیافتد. مثلا فرض کنید می خواهید با تایمر View ای را آپدیت کنید.
1 2 3 4 5 6 |
new Handler().postDelayed(new Runnable() { @Override public void run() { // update UI after 1000 millisecons } },۱۰۰۰); |
یک اینترفیسی است که تمامی کلاس هایی که قرار است توسط Thread اجرا شوند، باید آن را پیاده سازی کنند که یک متد run دارد. پس هرکلاس مشخص می کند که هنگام اجرا شدن توسط Thread چکاری را انجام دهد. ( آن کار در متد run پیاده سازی می شود.) که در تمامی مثال های قبلی قابل مشاهده است.
AsyncTask
برای ساخت آن باید کلاسی از آن مشتق کنیم و متد های آن را Override کنیم.
- doInBackground
- onPostExecute
متد doInBackground در یک ترد مجزا انجام می گیرد و جواب آن onPostExecute در ترد اصلی یا همان UI thread اتفاق می افتد که می توانیم توسط آن UI را آپدیت کنیم. البته متد های دیگری نیز دارد که تنها به این دو متد اشاره کردم. استفاده از AsyncTask بسیار در گرفتن اطلاعات از سمت web پرکاربرد است. ( در صورتی که نخواهیم از کتابخانه های نظیر Retrofit و Volley استفاده کنیم) و اصولاً در قدیم (حدود ۶ سال قبل) ترکیب HttpConnection و AsyncTask برای صدا زدن Api های سمت وب اجتناب ناپذیر بود!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private class MyAsycTask extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { //do something in Ui-thread before background work start } @Override protected Void doInBackground(Void... params) { //do something in background return null; } @Override protected void onPostExecute(Void aVoid) { //do something in Ui-thread } } |
نکته:
یک نوع استفاده دیگر از Handler وجود دارد که در ظاهر انگار Thread است اما:
1 2 3 4 5 6 |
runOnUiThread(new Runnable() { @Override public void run() { doSomething(); } }); |
توجه کنید که runOnUiThread یک نوع خاصی از Handler است که فقط در ترد اصلی اتفاق می افتد.
هرگونه سوال و یا نکته ای داشتید خوشحال می شم که کامنت کنید.