PDA

View Full Version : Multi-Threading in Android



مهران رسا
یک شنبه 21 اسفند 1390, 01:41 صبح
سلام. یک مقدار رو بحث چند نخی در جاوا و اندروید مطالعه داشتم. یه مثال براتون قرار میدم که در اون نحوه همگام سازی و بروز رسانی GUI هم شرح داده شده. برنامه به درستی کار میکنه فقط تنها مشکل کار اینجاست که مطمئن نیستم تعریفاتی که انجام دادم به شکل درستی بکار رفته یا نه. از دوستان اگر کسی علاقه مند هست به این مبحث ممنون میشم یه نگاهی به کد زیر بندازه و اگه راهکار بهتری برای پیاده سازی داری بگه.

توضیح : در این برنامه از یک ProgressBar استفاده شده که از طریق ایجاد یک حلقه در Thread جداگانه، مقدارش بروز میشه. علاوه بر نخی که وظیفه اش بروز رسانی پوزیشن progressbar هست. یک نخ دیگه برای کنترل وظعیت نخ اول ایجاد کرده ایم که پراپرتی isAlive نخ اول رو مورد بررسی قرار میده و نتایج رو در Thread اصلی برنامه بر روی یک TextView به نمایش در میاره. همچنین برای همگام سازی و بروز رسانی GUI از handler ها و متد post استفاده کرده ایم.

package m8.apps;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class Main extends Activity {

int i = 0;
ProgressBar pr;
TextView tv;
TextView tv2;
Button btn;
Thread Tr;
Thread checkerThread;
boolean bln;

private Handler handler = new Handler();
private Handler handler2 = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
pr = (ProgressBar) findViewById(R.id.Pr1);
tv = (TextView) findViewById(R.id.Tv1);
tv2 = (TextView) findViewById(R.id.Tv2);
btn = (Button) findViewById(R.id.Btn1);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Main Thread
btn.setEnabled(false);
Tr = new Thread(null, doProgressStart, "Background");
Tr.start();
// Checker Thread
bln = true;
checkerThread = new Thread(null, doCheck, "ChkThread");
checkerThread.start();
}
});
}

// Main Thread Declarations
private Runnable doProgressStart = new Runnable() {
@Override
public void run() {
final int Mx = 1000;
pr.setMax(Mx);
for (i = 0; i < Mx; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(doUpdateGUI);
}
}
};
private Runnable doUpdateGUI = new Runnable() {
public void run() {
pr.setProgress(i);
tv.setText("Progress : " + i + "%");
}
};

// --------------------------------------------
// Checker Thread Declarations
private Runnable doCheck = new Runnable() {
@Override
public void run() {
while (bln) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler2.post(doUpGUI2);
}
}
};
private Runnable doUpGUI2 = new Runnable() {
@Override
public void run() {
if (Tr.isAlive()) {
tv2.setText("Thread Status : Alive");
} else {
tv2.setText("Thread Status : Dead");
bln = false;
btn.setEnabled(true);
}
}
};

}

مهران رسا
یک شنبه 21 اسفند 1390, 12:28 عصر
خب تا جایی که متوجه شدم متغیر Bln که به عنوان یه flag برای خاتمه دادن به Thread دوم مورد بررسی قرار میگرفت باید به صورت Volatile تعریف بشه. اطلاعات بیشتر : http://en.wikipedia.org/wiki/Volatile_variable