AsyncTask در برنامه نویسی اندروید

P O U R I A

مدیر مهندسی شیمی مدیر تالار گفتگوی آزاد
مدیر تالار
فهرست مطالب:

  1. توقف thread فعلی تا زمانی که روش doInBackground از AsyncTask به طور کامل اجرا شود، با روش get ، در برنامه نویسی اندروید
  2. متوقف کردن (cancel کردن) یک کلاس (Class) از نوع AsyncTask که در حال اجرا می باشد، در برنامه نویسی اندروید


منبع: kelidestan
 

P O U R I A

مدیر مهندسی شیمی مدیر تالار گفتگوی آزاد
مدیر تالار
توقف thread فعلی تا زمانی که روش doInBackground از AsyncTask به طور کامل اجرا شود، با روش get ، در برنامه نویسی اندروید

توقف thread فعلی تا زمانی که روش doInBackground از AsyncTask به طور کامل اجرا شود، با روش get ، در برنامه نویسی اندروید

همان طور که می دانید، از AsyncTask برای اجرای یک سری کد در پس زمینه (background) استفاده می کنیم، به گونه ای که آن کدها به صورت جدا از thread فعلی اجرا می شوند. اما ممکن است که ادامه کدهای thread فعلی، به گونه ای باشد که باید از بخشی از اطلاعات پردازش شده در مرحله doInBackground از AsyncTask استفاده کند. بنابراین ادامه اجرای thread ، باعث می شود که کدها بدون آن مقادیر اجرا شوند، زیرا روش doInBackground از AsyncTask ، هنوز به طور کامل اجرا نشده است.

بگذارید یک مثال بزنیم تا دقیقتر متوجه شوید :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace]    [B]public[/B] [COLOR=#000066][B]boolean[/B][/COLOR] isConnectedOrNot[COLOR=#339933];[/COLOR]
    
    [B]public[/B] [COLOR=#000066][B]void[/B][/COLOR] ShowAlertDialog[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
         AlertDialog.[COLOR=#006633]Builder[/COLOR] alertDialog [COLOR=#339933]=[/COLOR] [B]new[/B] AlertDialog.[COLOR=#006633]Builder[/COLOR][COLOR=#009900]([/COLOR][B]this[/B].[COLOR=#006633]context[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         alertDialog.[COLOR=#006633]setTitle[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"Title"[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         alertDialog.[COLOR=#006633]setMessage[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"No Internet"[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         alertDialog.[COLOR=#006633]setIcon[/COLOR][COLOR=#009900]([/COLOR]R.[COLOR=#006633]drawable[/COLOR].[COLOR=#006633]ic_launcher[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         [COLOR=#666666][I]// Setting Positive "Yes" Button[/I][/COLOR]
         alertDialog.[COLOR=#006633]setPositiveButton[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"Yes (repeat check internet)"[/COLOR],
         [B]new[/B] DialogInterface.[COLOR=#006633]OnClickListener[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
             [B]public[/B] [COLOR=#000066][B]void[/B][/COLOR] onClick[COLOR=#009900]([/COLOR]DialogInterface dialog, [COLOR=#000066][B]int[/B][/COLOR] which[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                 dialog.[COLOR=#006633]cancel[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                 [B]new[/B] NetCheck[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]execute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
             [COLOR=#009900]}[/COLOR]
         [COLOR=#009900]}[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         [COLOR=#666666][I]// Setting Negative "NO" Button[/I][/COLOR]
         alertDialog.[COLOR=#006633]setNegativeButton[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"No (cancel)"[/COLOR],
         [B]new[/B] DialogInterface.[COLOR=#006633]OnClickListener[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
             [B]public[/B] [COLOR=#000066][B]void[/B][/COLOR] onClick[COLOR=#009900]([/COLOR]DialogInterface dialog, [COLOR=#000066][B]int[/B][/COLOR] which[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                 dialog.[COLOR=#006633]cancel[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
             [COLOR=#009900]}[/COLOR]
         [COLOR=#009900]}[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
         [COLOR=#666666][I]// Showing Alert Message[/I][/COLOR]
         alertDialog.[COLOR=#006633]show[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
    [COLOR=#009900]}[/COLOR]
        
        
        [B]private[/B] [B]class[/B] NetCheck [B]extends[/B] AsyncTask[COLOR=#339933]<[/COLOR][COLOR=#003399]String[/COLOR],[COLOR=#003399]String[/COLOR],Boolean[COLOR=#339933]>[/COLOR][COLOR=#009900]{[/COLOR]
            [B]private[/B] ProgressDialog nDialog[COLOR=#339933];[/COLOR]

            @Override
            [B]protected[/B] [COLOR=#000066][B]void[/B][/COLOR] onPreExecute[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900]{[/COLOR]
                [B]super[/B].[COLOR=#006633]onPreExecute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                nDialog [COLOR=#339933]=[/COLOR] [B]new[/B] ProgressDialog[COLOR=#009900]([/COLOR]context[COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                nDialog.[COLOR=#006633]setTitle[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"Checking Network"[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                nDialog.[COLOR=#006633]setMessage[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"Loading.."[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                nDialog.[COLOR=#006633]setIndeterminate[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000066][B]false[/B][/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                nDialog.[COLOR=#006633]setCancelable[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000066][B]true[/B][/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]

                nDialog.[COLOR=#006633]show[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
            [COLOR=#009900]}[/COLOR]
            [COLOR=#008000][B][I]/**
             * Gets current device state and checks for working internet connection by trying Google.
            **/[/I][/B][/COLOR]
            @Override
            [B]protected[/B] [COLOR=#003399]Boolean[/COLOR] doInBackground[COLOR=#009900]([/COLOR][COLOR=#003399]String[/COLOR]... [COLOR=#006633]args[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900]{[/COLOR]

                ConnectivityManager cm [COLOR=#339933]=[/COLOR] [COLOR=#009900]([/COLOR]ConnectivityManager[COLOR=#009900])[/COLOR]context.[COLOR=#006633]getSystemService[/COLOR][COLOR=#009900]([/COLOR][COLOR=#003399]Context[/COLOR].[COLOR=#006633]CONNECTIVITY_SERVICE[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                NetworkInfo netInfo [COLOR=#339933]=[/COLOR] cm.[COLOR=#006633]getActiveNetworkInfo[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                [B]if[/B] [COLOR=#009900]([/COLOR]netInfo [COLOR=#339933]!=[/COLOR] [COLOR=#000066][B]null[/B][/COLOR] [COLOR=#339933]&&[/COLOR] netInfo.[COLOR=#006633]isConnected[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                    [B]try[/B] [COLOR=#009900]{[/COLOR]
                        [COLOR=#003399]URL[/COLOR] url [COLOR=#339933]=[/COLOR] [B]new[/B] [COLOR=#003399]URL[/COLOR][COLOR=#009900]([/COLOR][COLOR=#0000FF]"http://www.google.com"[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                        [COLOR=#003399]HttpURLConnection[/COLOR] urlc [COLOR=#339933]=[/COLOR] [COLOR=#009900]([/COLOR][COLOR=#003399]HttpURLConnection[/COLOR][COLOR=#009900])[/COLOR] url.[COLOR=#006633]openConnection[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                        urlc.[COLOR=#006633]setConnectTimeout[/COLOR][COLOR=#009900]([/COLOR][COLOR=#CC66CC]3000[/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                        urlc.[COLOR=#006633]connect[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                        [B]if[/B] [COLOR=#009900]([/COLOR]urlc.[COLOR=#006633]getResponseCode[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]==[/COLOR] [COLOR=#CC66CC]200[/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                                isConnectedOrNot [COLOR=#339933]=[/COLOR] [COLOR=#000066][B]true[/B][/COLOR][COLOR=#339933];[/COLOR]
                            [B]return[/B] [COLOR=#000066][B]true[/B][/COLOR][COLOR=#339933];[/COLOR]
                        [COLOR=#009900]}[/COLOR]
                    [COLOR=#009900]}[/COLOR] [B]catch[/B] [COLOR=#009900]([/COLOR][COLOR=#003399]MalformedURLException[/COLOR] e1[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                        [COLOR=#666666][I]// TODO Auto-generated catch block[/I][/COLOR]
                        e1.[COLOR=#006633]printStackTrace[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                    [COLOR=#009900]}[/COLOR] [B]catch[/B] [COLOR=#009900]([/COLOR][COLOR=#003399]IOException[/COLOR] e[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
                        [COLOR=#666666][I]// TODO Auto-generated catch block[/I][/COLOR]
                        e.[COLOR=#006633]printStackTrace[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                    [COLOR=#009900]}[/COLOR]
                [COLOR=#009900]}[/COLOR]
                isConnectedOrNot [COLOR=#339933]=[/COLOR] [COLOR=#000066][B]false[/B][/COLOR][COLOR=#339933];[/COLOR]
                [B]return[/B] [COLOR=#000066][B]false[/B][/COLOR][COLOR=#339933];[/COLOR]

            [COLOR=#009900]}[/COLOR]
            @Override
            [B]protected[/B] [COLOR=#000066][B]void[/B][/COLOR] onPostExecute[COLOR=#009900]([/COLOR][COLOR=#003399]Boolean[/COLOR] th[COLOR=#009900])[/COLOR][COLOR=#009900]{[/COLOR]

                [B]if[/B][COLOR=#009900]([/COLOR]th [COLOR=#339933]==[/COLOR] [COLOR=#000066][B]true[/B][/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900]{[/COLOR]
                    nDialog.[COLOR=#006633]dismiss[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                    Toast.[COLOR=#006633]makeText[/COLOR][COLOR=#009900]([/COLOR]context.[COLOR=#006633]getApplicationContext[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR], [COLOR=#0000FF]"Your device is connected to internet !"[/COLOR], Toast.[COLOR=#006633]LENGTH_SHORT[/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]show[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                [COLOR=#009900]}[/COLOR][B]else[/B][COLOR=#009900]{[/COLOR]
                    nDialog.[COLOR=#006633]dismiss[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                    ShowAlertDialog[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
                [COLOR=#009900]}[/COLOR]
            [COLOR=#009900]}[/COLOR]
        [COLOR=#009900]}[/COLOR]
         
         [B]public[/B] [COLOR=#000066][B]boolean[/B][/COLOR] CheckInternet[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
             [B]new[/B] NetCheck[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]execute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR] 
             [B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR]
         [COLOR=#009900]}[/COLOR][/FONT]
[/FONT][/COLOR]
در کد فوق، یک AsyncTask با نام NetCheck داریم که برای چک کردن وضعیت اتصال گوشی اندروید به اینترنت به کار می رود. ما این AsyncTask را با روش زیر اجرا کرده ایم :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]public[/B] [COLOR=#000066][B]boolean[/B][/COLOR] CheckInternet[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
    [B]new[/B] NetCheck[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]execute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR] 
    [B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR][/FONT]
[/FONT][/COLOR]
در روش CheckInternet ، ما ابتدا NetCheck را اجرا کرده ایم، سپس مقدار isConnectedOrNot را برگردانده ایم که متغیری می باشد که بر اساس آن متوجه می شویم که گوشی اندروید به اینترنت متصل است یا نه. متغیر isConnectedOrNot در روش doInBackground از AsyncTask تعیین می شود. بنابراین با این کد، عملا متغیر isConnectedOrNot حاوی هیچ مقداری نخواهد بود (زیرا هنوز روش doInBackground اجرا نشده).

بابراین ما باید کدها را به گونه ای بنویسیم که ابتدا doInBackground کامل اجرا شود و سپس کد زیر اجرا گردد :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR][/FONT]
[/FONT][/COLOR]
برای این منظور، هنگام اجرای NetCheck ، باید روش get را به کار ببریم. یعنی کد زیر را :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]public[/B] [COLOR=#000066][B]boolean[/B][/COLOR] CheckInternet[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
    [B]new[/B] NetCheck[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]execute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR] 
    [B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR][/FONT]
[/FONT][/COLOR]
به این کد تبدیل می کنیم :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]public[/B] [COLOR=#000066][B]boolean[/B][/COLOR] CheckInternet[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
    [B]try[/B] [COLOR=#009900]{[/COLOR]
        [B]new[/B] NetCheck[COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]execute[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR].[COLOR=#006633]get[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR] 
    [COLOR=#009900]}[/COLOR] [B]catch[/B] [COLOR=#009900]([/COLOR][COLOR=#003399]InterruptedException[/COLOR] e[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
        [COLOR=#666666][I]// TODO Auto-generated catch block[/I][/COLOR]
        e.[COLOR=#006633]printStackTrace[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
    [COLOR=#009900]}[/COLOR] [B]catch[/B] [COLOR=#009900]([/COLOR]ExecutionException e[COLOR=#009900])[/COLOR] [COLOR=#009900]{[/COLOR]
        [COLOR=#666666][I]// TODO Auto-generated catch block[/I][/COLOR]
        e.[COLOR=#006633]printStackTrace[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
    [COLOR=#009900]}[/COLOR]
    [B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR][/FONT]
[/FONT][/COLOR]
بنابراین تا اجرای کامل روش doInBackground ، آن خط از کدها اجرا نخواهد شد و قبل از اجرا شدن آن خط از کدها، مقدار درست متغیر isConnectedOrNot تعیین می شود.

[h=4]نکته :[/h]شاید فردی بگوید که خوب ما کدهای تعین مقدار متغیر isConnectedOrNot را در روش onPostExecute از AsynkTask می نویسیم تا خیالمان راحت باشد که بعد از اجرای کامل روش doInBackground از AsynkTask ، مقدار متغیر isConnectedOrNot تعیین شود. ولی این حالت نیز هیچ تفاوتی نمی کند و باز هم هیچ مقداری در متغیر isConnectedOrNot نخواهد بود، زیرا قبل از اینکه روش onPostExecute اجرا شود، کد زیر از روش CheckInternet اجرا می گردد (هنوز مقدار isConnectedOrNot تعیین نشده، آن را بر می گردانیم) :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]return[/B] isConnectedOrNot[COLOR=#339933];[/COLOR][/FONT]
[/FONT][/COLOR]
[h=4]نکته :[/h]در مواردی مشاهده شده است که استفاده از نکته شرح داده شده در این مبحث، می تواند باعث ((نمایش صفحه به صورت سیاه رنگ کامل)) شود. بنابراین اگر از این روش استفاده کردید، حتما فرآیند مورد نظر را در آهسته ترین حالت خود بررسی کنید که برنامه مشکلی نداشته باشد. مثلا اگر فرآیند مورد نظر وابسته به اینترنت است، آن را با یک اینترنت با سرعت کم تست کنید.
 

P O U R I A

مدیر مهندسی شیمی مدیر تالار گفتگوی آزاد
مدیر تالار
متوقف کردن (cancel کردن) یک کلاس (Class) از نوع AsyncTask که در حال اجرا می باشد، در برنامه نویسی اندروید

متوقف کردن (cancel کردن) یک کلاس (Class) از نوع AsyncTask که در حال اجرا می باشد، در برنامه نویسی اندروید

برای متوقف کردن (cancel کردن) یک کلاس (Class) از نوع AsyncTask که در حال اجرا می باشد، کد زیر را می نویسیم (نام کلاس را برابر MyAsyncTask در نظر گرفته ایم) :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace]MyAsyncTask.[COLOR=#006633]cancel[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000066][B]true[/B][/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR][/FONT]
[/FONT][/COLOR]
چنانچه بخواهیم که قبل از متوقف کردن (cancel کردن) کلاس، ببینیم که آیا در حال اجرا می باشد یا خیر و تنها زمانی کد متوقف کردن اجرا شود که کلاس در حال اجرا باشد، کدها را به صورت زیر می نویسیم :
کد:
[COLOR=#000000][FONT=Tahoma][FONT=monospace][B]if[/B][COLOR=#009900]([/COLOR]MyAsyncTask [COLOR=#339933]!=[/COLOR] [COLOR=#000066][B]null[/B][/COLOR] [COLOR=#339933]&&[/COLOR] MyAsyncTask.[COLOR=#006633]getStatus[/COLOR][COLOR=#009900]([/COLOR][COLOR=#009900])[/COLOR] [COLOR=#339933]==[/COLOR] Status.[COLOR=#006633]RUNNING[/COLOR][COLOR=#009900])[/COLOR][COLOR=#009900]{[/COLOR] 
    MyAsyncTask.[COLOR=#006633]cancel[/COLOR][COLOR=#009900]([/COLOR][COLOR=#000066][B]true[/B][/COLOR][COLOR=#009900])[/COLOR][COLOR=#339933];[/COLOR]
[COLOR=#009900]}[/COLOR][/FONT]
[/FONT][/COLOR]
 
بالا