توقف thread فعلی تا زمانی که روش doInBackground از AsyncTask به طور کامل اجرا شود، با روش get ، در برنامه نویسی اندروید
همان طور که می دانید، از AsyncTask برای اجرای یک سری کد در پس زمینه (background) استفاده می کنیم، به گونه ای که آن کدها به صورت جدا از thread فعلی اجرا می شوند. اما ممکن است که ادامه کدهای thread فعلی، به گونه ای باشد که باید از بخشی از اطلاعات پردازش شده در مرحله doInBackground از AsyncTask استفاده کند. بنابراین ادامه اجرای thread ، باعث می شود که کدها بدون آن مقادیر اجرا شوند، زیرا روش doInBackground از AsyncTask ، هنوز به طور کامل اجرا نشده است.
بگذارید یک مثال بزنیم تا دقیقتر متوجه شوید :
public void ShowAlertDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this.context);
alertDialog.setTitle("Title");
alertDialog.setMessage("No Internet");
alertDialog.setIcon(R.drawable.ic_launcher);
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("Yes (repeat check internet)",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
new NetCheck().execute();
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("No (cancel)",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
private class NetCheck extends AsyncTask<String,String,Boolean>{
private ProgressDialog nDialog;
@Override
protected void onPreExecute(){
super.onPreExecute();
nDialog = new ProgressDialog(context);
nDialog.setTitle("Checking Network");
nDialog.setMessage("Loading..");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
/**
* Gets current device state and checks for working internet connection by trying Google.
**/
@Override
protected Boolean doInBackground(String... args){
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
isConnectedOrNot = true;
return true;
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isConnectedOrNot = false;
return false;
}
@Override
protected void onPostExecute(Boolean th){
if(th == true){
nDialog.dismiss();
Toast.makeText(context.getApplicationContext(), "Your device is connected to internet !", Toast.LENGTH_SHORT).show();
}else{
nDialog.dismiss();
ShowAlertDialog();
}
}
}
public boolean CheckInternet() {
new NetCheck().execute();
return isConnectedOrNot;
}
در کد فوق، یک AsyncTask با نام NetCheck داریم که برای چک کردن وضعیت اتصال گوشی اندروید به اینترنت به کار می رود. ما این AsyncTask را با روش زیر اجرا کرده ایم :
new NetCheck().execute();
return isConnectedOrNot;
}
در روش CheckInternet ، ما ابتدا NetCheck را اجرا کرده ایم، سپس مقدار isConnectedOrNot را برگردانده ایم که متغیری می باشد که بر اساس آن متوجه می شویم که گوشی اندروید به اینترنت متصل است یا نه. متغیر isConnectedOrNot در روش doInBackground از AsyncTask تعیین می شود. بنابراین با این کد، عملا متغیر isConnectedOrNot حاوی هیچ مقداری نخواهد بود (زیرا هنوز روش doInBackground اجرا نشده).
بابراین ما باید کدها را به گونه ای بنویسیم که ابتدا doInBackground کامل اجرا شود و سپس کد زیر اجرا گردد :
برای این منظور، هنگام اجرای NetCheck ، باید روش get را به کار ببریم. یعنی کد زیر را :
new NetCheck().execute();
return isConnectedOrNot;
}
به این کد تبدیل می کنیم :
try {
new NetCheck().execute().get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return isConnectedOrNot;
}
بنابراین تا اجرای کامل روش doInBackground ، آن خط از کدها اجرا نخواهد شد و قبل از اجرا شدن آن خط از کدها، مقدار درست متغیر isConnectedOrNot تعیین می شود.
شاید فردی بگوید که خوب ما کدهای تعین مقدار متغیر isConnectedOrNot را در روش onPostExecute از AsynkTask می نویسیم تا خیالمان راحت باشد که بعد از اجرای کامل روش doInBackground از AsynkTask ، مقدار متغیر isConnectedOrNot تعیین شود. ولی این حالت نیز هیچ تفاوتی نمی کند و باز هم هیچ مقداری در متغیر isConnectedOrNot نخواهد بود، زیرا قبل از اینکه روش onPostExecute اجرا شود، کد زیر از روش CheckInternet اجرا می گردد (هنوز مقدار isConnectedOrNot تعیین نشده، آن را بر می گردانیم) :
در مواردی مشاهده شده است که استفاده از نکته شرح داده شده در این مبحث، می تواند باعث ((نمایش صفحه به صورت سیاه رنگ کامل)) شود. بنابراین اگر از این روش استفاده کردید، حتما فرآیند مورد نظر را در آهسته ترین حالت خود بررسی کنید که برنامه مشکلی نداشته باشد. مثلا اگر فرآیند مورد نظر وابسته به اینترنت است، آن را با یک اینترنت با سرعت کم تست کنید.