نحوه متوقف کردن و ادامه دادن Thread
برای متوقف کردن Thread هنگام خروج از اکتیویتی و اجرای مجدد آن هنگام بازگشت به اکتیویتی یا اجرای مجدد اکتیویتی چه راه حلی وجود داره؟
من این کار را می کنم. درست و غلطش را نمی دونم. یک متغیر تعریف می کنم و هر وقت خواستم درون ترد پروسه ای اجرا نشه اون را false می کنم. با این کار از درون خود ترد هم می ونم اون را کنترل کنم. به عنوان مثال:
Thread thread = new Thread(new Runnable() { boolean bool = true; @Override public void run() { while (bool) { try { Thread.sleep(500); G.HANDLER.post(new Runnable() { @Override public void run() { DownloadRequest request = downloadRequests.get(item.DownloadRequestIndex); int percent = request.getPercent(); prgressBarItemStandardDownloading.setProgress(percent); txtStandardDownloadingPersent.setText(" " + percent + " %"); if (percent == 100) { bool = false; } } }); } catch (InterruptedException e) { e.printStackTrace(); } } } }); thread.start();
من یک شمارش معکوس دارم <
میخوام هر بار که متد زیر اجرا میشه < شمارش از ابتدا اغاز بشه < و شمارشی که از قبل شروع شده دیگه ادامه پیدا نکنه !
public void Counter() {
TextView txtCounter = (TextView) findViewById(R.id.txtcounter);
ThreadCounter thread_conter = new ThreadCounter();
thread_conter.setSecound(70);
thread_conter.setTextView(txtCounter);
thread_conter.start();
}
ترد هم بصورت زیر هست
public class ThreadCounter extends Thread {
private int secound;
private int counter;
private TextView textView;
public void setSecound(int value) {
secound = value;
counter = secound;
}
public void setTextView(TextView value) {
textView = value;
}
@Override
public void run() {
super.run();
while (counter >= 0) {
Log.i("LOG", "" + counter);
if (textView != null) {
G.HANDLER.post(new Runnable() {
@Override
public void run() {
int MIN = (int) Math.floor(counter / 60);
int SEC = (int) Math.floor(counter % 60);
String P_SEC = "";
String P_MIN = "";
if (SEC < 10) {
P_SEC = "0";
}
if (MIN < 10) {
P_MIN = "0";
}
textView.setText(P_MIN + MIN + ":" + P_SEC + SEC);
}
});
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
counter--;
}
}
}
خب چیزی که تجربه شد < اینه که ترد رو نمیشه Stop یا Kill یا Destroy کرد
و ترد زمانی تموم میشه که خود به خود کارش تمومش بشه < مثلا اگر دستور For یا While وجود داشته باشه اون متغیر باید 0 بشه و حلقه به انتها برسه ، مگر اینکه شما اینقدر خلاق کد بزنید که بتونید کار حلقه رو در لحظه ایی که میخواهید متغیرش رو 0 کنید !
من مجبور شدم سورس رو بصورت زیر تغییر بدم < (همچنان چندین ترد اجرا میشه < اما اینبار روی خروجی خرابی به بار نمیاره! و با اینکه TextView رو هی پشت سر هم توسط چندین ترد مقدارش رو ست میکنه ، اما در ظاهر پیدا نیست!)
متد در اکتیوتی اصلی به این صورت تغییر کرد <
public void Counter() {
TextView txtCounter = (TextView) findViewById(R.id.txtcounter);
ThreadCounter thread_conter = new ThreadCounter();
thread_conter.setTextView(txtCounter);
thread_conter.start();
}
و کلاس ترد هم به صورت زیر
در واقع آخرین مقدار از روی خود TextView دریافت میشه که بصورت پیشفرض برابر 60 هست
public class ThreadCounter extends Thread {
private int counter;
private TextView textView;
public void setTextView(TextView value) {
textView = value;
String txtcounter = textView.getText().toString();
counter = Integer.parseInt(txtcounter);
}
@Override
public void run() {
super.run();
while (counter >= 0) {
Log.i("LOG", "" + counter);
if (textView != null) {
G.HANDLER.post(new Runnable() {
@Override
public void run() {
textView.setText("" + counter);
}
});
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
counter--;
}
}
}
سلام دوستان
بلاخره موفق شدم ترم رو متوقف کنم
اما کد نویسی اون به کثیف ترین شکل ممکن انجام شده ! و البته ترد ها هر چنتا که اجرا شده باشند همه با هم متوقف می شوند <
ولی باز هم نیاز هست < بعد از توقف ترد ها < دوباره خود بخود یک ترد از 60 شمارش کنه < که این قسمتش رو هنوز ننوشتم !
# توی این روش یک Buttonداریم < که هم متد به اون دسترسی داره و هم کلاس ترد <
#ترد توی هر لحظه چک میکنه که مقدار Text درون Button مقدارش 0 هست یا 1 < اگر 0 باشه اخرین شرط حلقه اجرا میشه و ترد متوقف میشه<
# اگر متد دوبار اجرا بشه برای بار دوم مقدار باتن از 1 به 0 تغییر میکنه که باعث میشه ترد از کار بوفته !
واسطه ی ما یک باتن هست !
> متد بصورت زیر تغییر کرده !
public void Counter() {
timer = !timer;
Log.i("timer", "" + timer);
TextView txtCounter = (TextView) findViewById(R.id.txtcounter);
Button btnfalse = (Button) findViewById(R.id.Button35);
if (timer) {
btnfalse.setText("1");
} else {
btnfalse.setText("0");
}
ThreadCounter thread_conter = new ThreadCounter();
thread_conter.setTextView(txtCounter);
thread_conter.setbtnView(btnfalse);
thread_conter.start();
}
و کلاس ترد هم به صورت زیر !
public class ThreadCounter extends Thread {
private int counter;
private int falseable;
private TextView textView;
private Button btnView;
public void setTextView(TextView value) {
textView = value;
}
public void setbtnView(Button value) {
btnView = value;
}
@Override
public void run() {
super.run();
//-----------------------------------------------------
//آخرین مقدار عددی شمارش گر (تکست ویو) از اینجا دریافت میشه و هر باز توسط ترد یکی کم میشه
String txtcounter = textView.getText().toString();
counter = Integer.parseInt(txtcounter)
//-----------------------------------------------------
//تا زمانی که وایل داره کار میکنه ترد از کار نمیوفته!
while (counter >= 0) {
//-----------------------------------------------------
//همیشه چک میشه که مقدار باتن 0 هست یا 1 که اگر 0 باشه در ادامه ترد رو از کار میاندازیم
String txtfalseable = btnView.getText().toString();
falseable = Integer.parseInt(txtfalseable);
//-----------------------------------------------------
Log.i("LOG", "" + counter);
if (textView != null) {
G.HANDLER.post(new Runnable() {
@Override
public void run() {
//-----------------------------------------------------
//مقدار تکست ویو بصورت شمارش معکوس نمایش داده میشود
textView.setText("" + counter);
//-----------------------------------------------------
// اینجا تمام تردها متوقف می شوند اگر مقدار باتن که در بالا دریافت شده 0 باشد !
if (falseable == 0) {
counter = 0;
textView.setText("60");
}
//-----------------------------------------------------
}
});
}
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
counter--;
}
}
}
لطفا همکاری کنید < اگر کسی متوجه میشه این کد چی هست نظر بده < اگر هم بد خط هست < کمی توضیح بدم <
سلام دوستان <
حدود 2 ماه لپ تاپ نداشتم / ایمیلم هم که دی اکتیو شد !
کلا از زندگانی عقب افتادم ولی بلاخره این مشکل حل شد
من میخواستم برای بازی هنگ من یک تایمر تعریف کنم ، که کاربر بعد از این مدت بازی رو به اجبار تموم کنه یا GameOver بشه
مشکل با ترد داشتم < که متوقف نمیشد
با تجربه ایی که من تا اینجا کسب کردم < ترد در صورتی که توی یک حلقه باشه تحت هیچ عنوان کارش تموم نمیشه مگر اینکه خود شما وسط کار حلقه یک متغیر رو تزریق یا دریافت کنید که index حلقه رو به اخرین مقدار تبدیل کنه و دیگه شرط حلقه اجرا نشه و ترد هم تموم بشه
ولی برای مشکلی که من داشتم < تونستم به یک روشی مشکل رو حل کنم <<
قبلا همه چیز رو بالا توضیح دادم <
اینجا فقط سورس هارو میزارم
public void Counter() {
TextView txtCounter = (TextView) findViewById(R.id.txtcounter);
ThreadCounter thread_conter = new ThreadCounter();
thread_conter.setTextView(txtCounter);
thread_conter.setbtnView(btnfalse);
thread_conter.start();
}
متد کانتر که باعث میشه شمارش معکوس شروع بشه یا متوقف بشه < برای تاثیر گذاشتن روی ترد لازم بود 2 تا عنصر رو به ترد بفرستیم !
کلاس ترد هیچ تغییری نمیکنه < همون سورس بالا میمونه < توی کلاس ترد اگر مقدار btnfalse برابر 0 باشه ترد از کار میوفته
و اگر یک باشه همچنان مقدار قبلی txtcounter دریافت میشه و یکی ازش کم میشه
حالا کافیه ما مقدار btnfalse رو مقدار دهی کنیم و بعد از اون متد بالا رو صدا بزنیم < تا ترد طبق درخواست ما متوقف بشه یا شروع به شمارش معکوس کنه
بنابر این با هر بار کلیک روی دکمه btnNew
مقدار btnfalse تبدیل به 0 میشه
btnfalse.setText("0");
Counter();
و با هربار کلیک شدن روی هر کدوم از حروف مقدار btnfalse تبدیل به 1 میشه
if (btnfalse.getText().toString().equals("0")) {
btnfalse.setText("1");
Counter();
}
برای اینکه چندین ترد بوجود نیاد < از دستور IF استفاده شده <
مشکل حل شد < اما اصلا جالب نیست که از یک باتن روی ویو برای توقف کردن ترد استفاده شده <
بهتر بود که از یک متغیر استفاده میشد که من هنوز نمیدونم چطوری ممکنه !
دوستان بلاخره راه منطقی برا stop کردن thread چیه ؟ در حالت عادی و همچنین موقع خروج از اکتیویتی
و یه سوال دیگه "
غیر از thread.sleep و استفاده از thread چطوری میشه در بین انجام دستورات یک تاخیر یا وقفه ایجاد کرد ؟
مثلا خط اول کد ما اجرا شد حالا بگیم 10 ثانیه صبر کن و بعد برو خط بعد و ادامه بده !
باتشکر
این رو هم امتحان کن:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//code haye shoma
}
},10000);
doost_fu @ درواقع شما انتظار داری با هربار کلیک شدن روی باتن < پروگرسبار شما از صفر شروع کنه به پر شدن < حتی اگر 50% پر شده باشه و در هیمن حین کلیکی انجام بشه همون لحظه مقدار پروگرس صفر بشه و شروع به پر شدن کنه <
شما نمیتونید ترد رو متوقف کنید < ولی میتونید مقدار i که درون حلقه for هست رو 100 کنید < تا کار ترد تموم بشه <
الان سورس پروژه رو براتون آپلود میکنم <
این نمونه کار ترد با پروگرس بار هست
ترد رو نمیشه متوقف کرد < برای چیزی که توسط ترد درحال اجرا هست و میخواید متوقفش کنید باید الگوریتم بنویسید <
روش روتین متوقف کردن ترد به این شکله:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while ( !thread.currentThread().isInterrupted()) {
try {
thread.sleep(1000); //این خط الزامی نیست
//To DO
}
catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
});
thread.start();
//هرجا خواستیم ترد متوقف شود، دستور زیر را اجرا می کنیم
thread.interrupt();
روش روتین متوقف کردن ترد به این شکله:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while ( !thread.currentThread().isInterrupted()) {
try {
thread.sleep(1000); //این خط الزامی نیست
//To DO
}
catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
});
thread.start();
//هرجا خواستیم ترد متوقف شود، دستور زیر را اجرا می کنیم
thread.interrupt();
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .