بروز خطا
[message]
اشتراک در سوال
رای ها
[dataList]
یک سوال فنی در مورد Thread و اجرا بر روی UI Thread
کد زیر رو در نظر بگیرید : در اصل باید اول حلقه for اجرا بشه و بعد از اتمام، عمل setText انجام بشه. ولی با کمال تعجب وسطای حلقه یه هو عمل setText انجام میشه. کسی میدونه دلیلش چیه؟
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0 ; i<300000; i++){
Log.i("LOG" , " Job 1 : " + i);
}
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
txtShow.setText("Done");
}
});
}
});
thread.start();
+1
0
یه سرچ زدم. چیزی که دستگیرم شد : UI Thread برا خودش یه صف داره که همیشه از اون صف کارهارو بر میداره و اجرا می کنه. زمانیکه شما از چیزهایی شبیه runOnUiThread و یا Handler.post استفاده می کنی، در واقع یک کار رو (مرتبط با تغییر UI ) به اون صف پاس میدی. منابع معتبر میگن این عمل async هست یعنی ناهماهنگ. پس بهترین روش استفاده از listener هاست. یعنی یک Listener بزاری هر وقت کار background Thread تموم شد ، اون موقع post کنی به UI Thread. (9 سال پیش)
0
0
دلیل اینو نمیدونم ولی اگه از هندلر(Handler) استفاده کنی دیگه این اتفاق نمیفته (9 سال پیش)
0
0
تست کردم . برا Handler هم همین اتفاق میغته. (9 سال پیش)
+1
0
شما از کجا متوجه شدین setText وسط حلقه اجرا شد ؟!!! حلقه داره Log چاپ میکنه ، ولی شما دارین با تغییرات UI مقایسه ش میکنید . نمیشه به راحتی تشخیص داد . شما باید مقایسه تون از یه جنس باشه . روش تست درست رو براتون میذارم . (9 سال پیش)
برای این سوال 1 پاسخ وجود دارد.
پاسخ به سوال
Reza
9 سال پیش
+3
0
کد درست و به ترتیب اجرا میشه ، ولی اتفاقی که میفته اینه که LogCat در نمایش عقب میفته . یعنی حلقه واقعا به انتها رسیده که setText انجام میشه . ولی چون Log ها نمیتونه سریع چاپ بشه تو صف قرار میگیره ، در صورتی که حلقه تموم شده . راه تستش اینه که بگین هر موقع i به انتها رسید بگین یه تست و یه Log مخصوص اجرا بشه . میبینید که در انتهای حلقه ، تست مخصوص و setText انجام میشه ولی Log مخصوص با تاخیر اجرا میشه :
به جای کدهای بالا ، این کد رو تست کنید ، متجه میشید :
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 300000; i++) {
if (i == 299999) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Loop End", 1000).show();
Log.i("LOG", "#### END ####");
}
});
}
Log.i("LOG", "Job 1 : " + i);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
txtShow.setText("Done");
}
});
}
});
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .