آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

نحوه متوقف کردن و ادامه دادن Thread

Hossein Kurd  9 سال پیش  5 سال پیش
+6 0

برای متوقف کردن Thread هنگام خروج از اکتیویتی و اجرای مجدد آن هنگام بازگشت به اکتیویتی یا اجرای مجدد اکتیویتی چه راه حلی وجود داره؟

+2 0
من دارم کل انجن رو سرچ میکنم _ هنوز جواب درستی پیدا نکردم ! من یک کانتر دارم که شمارش معکوس انجام میده < قبل از اتمام کار ترد و تمام شدن شمارش معکوس جواب مسئله پیدا میشه < توی این مدت دوباره شمارش معکوس از اول اجرا میشه < اما همچنان ترد قبلی داره کار میکنه < و مقدار TextView پشت سر هم تغییر میکنه < که اصلا جالب نیست ! (9 سال پیش)
 برای این سوال 10 پاسخ وجود دارد.
پاسخ به سوال 
hamed  9 سال پیش
+5 0

من این کار را می کنم. درست و غلطش را نمی دونم. یک متغیر تعریف می کنم و هر وقت خواستم درون ترد پروسه ای اجرا نشه اون را 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();
0 0
این برای زمانی خوب هست که کارشما باید تا اخر اتمام پیدا کنه (9 سال پیش)
0 0
کریس جان سوال شما را دقیقا نفهمیدم. ایا این سوال اینجا با این لینک مرتبطه؟ (9 سال پیش)
+1 0
نه اون مشکل قدیمی بود < که با الگوریتم حلش کردم < مشکلی که الان دارم < مربوط میشه به یک شمارش گر معکوس < که با شروع اکتیویتی شروع به کم شدن میکنه < حالا اگر ماهر لحظه بخواهیم ثانیه شمار رو از اول شروع کنیم باید یک بار دیگه ترد رو فراخوانی کنیم که این کار باعث میشه ترد پشت سر هم مقدار TextView رو تغییر بده (9 سال پیش)
+1 0
یه شمارش گر معکوس تو یکی از آموزش ها بود. یادم نیست چجوری بود ولی شاید ایده خوبی داشته باشه. یه نگاه بهش بندازید. ببخشید یکم دیرفهمم(هنوز نفهمیدم چی به چیه!) اما اگه اشتباه نکنم شما یه اکتیویتی دارید که یک شمارشگر معکوس با بالا آمدن آن شروع به کار می کنه. (خوب حالا یه سوال اینه که ساختار شمارشگر چجوریه؟ مثلا می تونه یک حلقه باشه که یک دستور وقفه داخل اون قرار می گیره و یا راه های دیگر) خوب حالا دقیقا اینکه شما مثلا می خواهید شمارش گر را ریست یا متوقف بکنید چه ربطی به اجرای مجدد ترد پیدا می کنه؟ شما می تونید برای ریست مقدار شمارش گر را از نو مقدار دهی کنید. و برای توقف هم درون حلقه یک شرط قرار بدهید که از حلقه بیاید بیرون و یا از while یا do-while استفاده کنید. (9 سال پیش)
پاسخ به سوال 
Criss  9 سال پیش
+1 0

من یک شمارش معکوس دارم <

میخوام هر بار که متد زیر اجرا میشه < شمارش از ابتدا اغاز بشه < و شمارشی که از قبل شروع شده دیگه ادامه پیدا نکنه  !

  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--;

}

}
}

 

0 0
چطور میتونم تا تعریف یک متغیر از دستور While ، بریک کنم ؟ و دوباره از اول شروع کنم ؟ (9 سال پیش)
+1 0
خوب حالا شد. البته من دو تا پیشنهاد الان با ذهنم می رسه که یه جورایی فعلا پاک کردن صورت مساله است. اول اینکه می تونید شیوه نوشتن تایمر را عوض کنید و اصلا اون را به صورت ترد نگذارید که داستان جدایی می شه. و دوم که اصولی تر به نظر می رسه اینه: شما در درجه اول txtCounter و thread_conter را به صورت غیرمحلی و خارج از متد تعریف کنید. به این ترتیب با هر بار تغییر محتوای thread_conter.setSecound(70);l می توانید شمارشگر را از نو راه اندازی کنید. (9 سال پیش)
0 0
کمی سرچ کردم ، فکر کنم روش اول رو انتخاب کنم < فعلا دارم تست میکنم سورسش رو < فکر کنم این روش ، از روش استاد هم ساده تر باشه ! (9 سال پیش)
0 0
البته حواستون باشه که در این روش چون پردازش شمارش معکوس به صورت موازی با بخش های دیگر برنامتون پیش نمی ره یه خورده الگوریتم پیچیده تری را در کدهای برنامتون می طلبه. (البته بستگی به برنامتون هم داره) (9 سال پیش)
پاسخ به سوال 
Criss  9 سال پیش
0 0

خب چیزی که تجربه شد < اینه که ترد رو نمیشه 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--;
}
}
}

 

0 0
ولی هنوز وقتی متد دوباره اجرا میشه < نمیتونیم مقدارش رو از اول برابر 60 قرار بدیم ! (9 سال پیش)
پاسخ به سوال 
Criss  9 سال پیش
+1 0

سلام دوستان

بلاخره موفق شدم ترم رو متوقف کنم

اما کد نویسی اون به کثیف ترین شکل ممکن انجام شده ! و البته ترد ها هر چنتا که اجرا شده باشند همه با هم متوقف می شوند <

ولی باز هم نیاز هست < بعد از توقف ترد ها < دوباره خود بخود یک ترد از 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--;
}
}
}

لطفا همکاری کنید < اگر کسی متوجه میشه این کد چی هست نظر بده < اگر هم بد خط هست < کمی توضیح بدم <

+1 0
یادش بخیر سال قبل همین موقع ها بود خیلی سر این موضوع اذیت شدم در اخر از Timer استفاده کردم و مشکلم حل شد پرا از Timer استفاده نمیکنید؟ (9 سال پیش)
0 0
این زندگی چدر زود میگذره 3 روز شده که وقت نکردم به پروژه سر بزنم ! میشه نمونه سورس اماده اگر دارید به همین تاپیک اضاف کنید < ولی من سعی میکنم یه راهی برای خارج شدن از ترد پیدا کنم < اخرین سورسی که گذاشتم ترد رو متوقف میکنه ! (9 سال پیش)
0 0
سلام این کدی که شما گذاشتید ، در چه سطحی بودید اونوقت که این کد رو زدید ؟ بنظر من خیلی کد عالی ای زدید . (5 سال پیش)
پاسخ به سوال 
Criss  9 سال پیش
0 0

سلام دوستان <

حدود 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 استفاده شده <

 

مشکل حل شد < اما اصلا جالب نیست که از یک باتن روی ویو برای توقف کردن ترد استفاده شده <

بهتر بود که از یک متغیر استفاده میشد که من هنوز نمیدونم چطوری ممکنه !

 

+1 0
منم همین مشکلو دارم، چرا نمیشه از متد stop یا متد interrupt استفاده کرد؟ هیچ راه دیگه نیست؟ (9 سال پیش)
0 0
منم تقریبا همین مشکل رو دارم، مثلا برای من چند سوال چهار گزینه ای هستش که به هر کدوم 5 ثانیه وقت میده، وقتی کاربر گزینه ای رو انتخاب کرد باید بره سوال بعدی، ولی مشکل اینجاست چون thread متوقف نمیشه مثلا وقتی کاربر بعد از 3 ثانیه روجواب کلیک کرد، برای سوال بعد بجای 5 ثانیه، 2 ثانیه وقت داره. دوستان کمک کنید. (9 سال پیش)
0 0
منم با این مشکل دارم همین الان بازم کارم گیرش افتاد ! لامصب این ترد خیلی کاریه ! تا کارش تموم نکنه ول کن نیست !! (9 سال پیش)
0 0
ترد شما چه کاری رو انجام میده ؟ یک حلقه while ? یا یک حلقه for ؟ اون تکه از کد که مدام تکرار میشه رو بزارید راهنماییتون کنم (9 سال پیش)
0 0
دوستمون nooriDveloper که سوالشون داخل نظر قبلی نوشته بودند ! مشکل اصلی من اینه که چجوری به thread بگم بی خیال ! دیگه ادامه نده ! یه سوال دیگه هم قبلا همین پایین نوشته بودم ! ممنون . (9 سال پیش)
+1 0
سوال پایینیتون که جواب داده شده < اما ترد رو نمیشه بهش گفت که متوقف بشه < تنها راه متوقف کردن این هست که کاری رو که داره انجام میده رو متوقف کنید تا اینکه کاری وجود نداشته باشه و ترد هم فعالیتی انجام نده < ترد شما چه کاری رو انجام میده ؟ (9 سال پیش)
0 0
اون مال یه برنامه دیگه بود که کلا عملکرد برنامه رو عوض کردم چون ترد بعد از یه زمان تاخیر باید یه موسیقی پخش میکرد و در جای دیگه بعد از گذشتن زمان باید intent میکرد به یه اکتیویتی دیگه ... ! کلا کنسل و عوض شد . (9 سال پیش)
+1 0
الان هم در نظر بگیرید یه progresbar داریم که با زدن یه دکمه صفر تا صد پر میکنه ( مثلا هر یک دهم ثانیه ، یک درصد ) و با thread این تاخیر بوجود اوردیم حالا اگه قبل از رسیدن به صد دوباره دکمه رو بزنیم دوبار با فاصله این کار ایجاد میشه و اگه دوباره بزنیم ... حالا نمیشه با زدن دکمه thread قبلی کنسل بشه و دوباره شروع کنه ! البته مشکل با تغییر مقدار های حلقه یک تا صد و مقدار پروگرس حل کردم ولی خب ... ! با تشکر (9 سال پیش)
پاسخ به سوال 
doost_fu  9 سال پیش
0 0

دوستان بلاخره راه منطقی برا stop کردن thread  چیه ؟ در حالت عادی و همچنین موقع خروج از اکتیویتی
و یه سوال دیگه "
غیر از thread.sleep و استفاده از thread چطوری میشه در بین انجام دستورات یک تاخیر یا وقفه ایجاد کرد ؟
مثلا خط اول کد ما اجرا شد حالا بگیم 10 ثانیه صبر کن و بعد برو خط بعد و ادامه بده !

باتشکر

پاسخ به سوال 
saeidhic  9 سال پیش
+2 0

این رو هم امتحان کن:

         Handler handler = new Handler();
handler.postDelayed(new Runnable() {

@Override
public void run() {
//code haye shoma

}
},10000);
0 0
این کد شما postDelayed هست < به متوقف شدم ترد مربوط نیست ! (9 سال پیش)
0 0
اشتباه شد < این پست شما برای پست بالای هست < که کاملا صحیح هست (9 سال پیش)
پاسخ به سوال 
Criss  9 سال پیش
+1 0

doost_fu @  درواقع شما انتظار داری با هربار کلیک شدن روی باتن < پروگرسبار شما از صفر شروع کنه به پر شدن < حتی اگر 50% پر شده باشه و در هیمن حین کلیکی انجام بشه همون لحظه مقدار پروگرس صفر بشه و شروع به پر شدن کنه <

شما نمیتونید ترد رو متوقف کنید < ولی میتونید مقدار i که درون حلقه for هست رو 100 کنید < تا کار ترد تموم بشه <

 

الان سورس پروژه رو براتون آپلود میکنم <

این نمونه کار ترد با پروگرس بار هست

 

ترد رو نمیشه متوقف کرد < برای چیزی که توسط ترد درحال اجرا هست و میخواید متوقفش کنید باید الگوریتم بنویسید <

 

+1 0
خب من داخل سوالم نوشتم که فعلا همین کارو کردم با تشکر . (9 سال پیش)
0 0
سلام ، بالاخره بعد از اینهمه سال نتیجه تون چی شد ؟ آیا ترد قابل متوقف کردن نیست ؟ من الان این سوال برام مطرح شده و درگیرش هستم ، ینی 3 سال حداقل از شما عقبم |: (5 سال پیش)
پاسخ به سوال 
116236  5 سال پیش
0 0

روش روتین متوقف کردن ترد به این شکله:


        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();
0 0
interrupt دقیقا کارش چیه ؟ (5 سال پیش)
0 0
سلام ، کار نمیده ، من اجرا شدن Thread رو دادم دست یک Button که اسمش هست : btn_start و اجرا شدن thread.interrupt رو دادم دست یک Button به اسم : btn_stop اما متاسفانه جواب نمیده . ترد همینجور به کار خودش ادامه میده . (5 سال پیش)
0 0
اما خوشبختانه کرش هم نمیکنه . (5 سال پیش)
پاسخ به سوال 
116236  5 سال پیش
+1 0

روش روتین متوقف کردن ترد به این شکله:


        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();
0 0
در داکیومنتی نوشته بود که اگه interrupt برای Thread هایی استفاده بشه که در اونها sleep ، wait (و شاید موارد مشابه دیگه ای ) باشه ، دستور interrupt براتون جوا نمیده . در اینجا هم ما داریم از sleep استفاده میکنیم و همونطور که امتحان کردم نمیشه ازش جواب گرفت . (5 سال پیش)
+1 0
من این کد رو داخل یه نرم افزار استفاده کردم، مشکلی هم نداشته. برای شما چه مشکلی وجود داشت؟ (5 سال پیش)
0 0
درواقع stop نمیشه . زمانی که میخوایم متد thread رو intrrupt کنیم ، هیچ اتفاقی نمیفته (5 سال پیش)
0 0
دستور intrrupt رو توی کلید دیگه ای گذاشتم ، وقتی روش میزنی هیچ اتفاقی نمیفته ، اما یه چیزی لوگ میشه ، چیزی که داره به خط 47 اشاره میکنه و خط 47 این دستور هست : Thread.sleep(300); نمیدونم مشکل از کجا باشه (5 سال پیش)
+1 0
خب احتمالا داره از این خط خطا میگیره. ولی چون تووی بلک try نوشته شده نرم افزار کرش نمی کنه. اگه متن ارور رو بفرستید شاید بتونم کمک کنم (5 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .