זהו פוסט המשך בנושא Threads. בפוסט הקודם,Threads עם Message Handler הובא הסבר רקע, והוזכרו שלוש שיטות למימוש Threads:
Handler עם MessageQueue ו- Data Messages- שיטה זו תוארה בפוסט הנ"ל.
Handler עם MessageQueueu ו- Runnable- זהו נושא הפוסט הנוכחי.
AsyncTask - נושא הפוסט הבא.
מנגנון ה- Runnable
רקע - חזרה על שיטת ה-Data Messages .
בשיטה ה-Message Queue , התקשורת בין ה-Thread שיצרנו לבין ה-Thread הראשי נעשית בעזרת העברת נתונים בין ה-Threads. ה- Handler שולף את הנתונים ומריץ את התוכנית של עצמו. אם ה-Thread רוצה למשל להעביר אינפורמציה ל-UI, הוא ישלח את האינפורמציה כהודעה, וה-Handler יגש ל-UI.
בשיטת ה-runnable ה-Thread שניצור ישלח runnables שהם מודולים להרצה אותם יפעיל ה-Handler במסגרת ה-Thread הראשי.שליחת ה-runnables ל-MessageQueue נעשית עם פקודות post.
לגבי פקודות ה-post (השייכות ל-)Handler Calss:
קיימות מספר וריאציות של post למשל:
- (post(runnable r
בדוגמא נשתמש במתודה זו.
- (postAtTime(runnable r,long upTimeMillis
הביצוע יתקיים בזמן עפ"י הפרמטר השני.
- (postDelayed(runnable r,long upTimeMillis
הביצוע יתעכב בהתאם לפרמטר השני.
ויש עוד וריאציות של post, ראו Handler Class באתר המפתחים הרשמי.
נעבור לדוגמא:
הדוגמא כמעט זהה לזו מהפוסט הקודם, עם שינויים קלים בלבד - רק מה שהתחייב משינוי השיטה.
לפניכם התוכנית כולה, ולאחריה אגע בהבדלים לעומת התוכנית השניה.
- החלקים המסומנים באדום - תוספות שקשורות למימוש ה-runnable.
- החלקים המסומנים בצהוב - קריאות ל-constructor של הThread. עכשיו הן ללא פרמטר. קודם ה-constructor קיבל את ה-handler.
- מספר שורות הוסרו:
- המימוש של מתודת הhandleMessage בתוך ה-handler
- בניית ושליחת ההודעה ב-Thread.
מעבר לכך הכל נשאר כמו שהיה.
public class MyThreadHandlerRunnableExample extends Activity {
EditText editTextThreadOutput;
EditText editTextThreadOutput2;
EditText editTextPriority;
Button buttonThreadOnOff;
int prioIndx = 1;
ExampleThread exampleThread1;
ExampleThread exampleThread2;
final int THREAD2_PRIORITY = 10;
final int THREAD1_PRIORITY = 1;
/** Called when the activity is first created. */
@Override public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
buttonSetup();
editTextSetup();
threadSetup();
}
public class ExampleThread extends Thread {
Handler mHandler = new Handler();
private final Runnable displayCounter = new Runnable() {
public void run() { displayCounterOnUi(counter, threadId); }
};
boolean mState = true;
int counter;
int threadId;
void mPrioritySet(int priority){
setPriority(priority);
}
ExampleThread() {
}
public void run() {
counter = 0;
while (mState) {
try {
Thread.sleep(10);
}
catch (InterruptedException e) {
}
counter++;
mHandler.post(displayCounter);
}
}
public void threadStateSet(boolean state) {
mState = state;
}
public boolean threadStateGet(){
return(mState);
}
public void threadIDSet(int val) {
threadId = val;
}
public void threadCounterClear() {
counter = 0;
}
}
public void displayCounterOnUi(int counter, int threadId){
if(0 == threadId){
editTextThreadOutput.setText(Integer.toString(counter));
}
else{
editTextThreadOutput2.setText(Integer.toString(counter));
}
}
private void buttonSetup(){
Button buttonSetPriority = (Button)findViewById(R.id.button_set_priority);
buttonSetPriority.setText("Thread Priority Set");
buttonSetPriority.setOnClickListener(
new Button.OnClickListener() {public void onClick(View v) {
if (0 == (prioIndx++)%10){
prioIndx = 1;
}
exampleThread1.mPrioritySet(prioIndx);
editTextPriority.setText("Thrd Priority = " +prioIndx+ " Thrd 2 Prio= " + THREAD2_PRIORITY);
exampleThread1.threadCounterClear();
exampleThread2.threadCounterClear();
} });
buttonThreadOnOff = (Button)findViewById(R.id.button_thread_onoff);
buttonThreadOnOff.setText("Thread is On");
buttonThreadOnOff.setOnClickListener(
new Button.OnClickListener() {public void onClick(View v) {
if(exampleThread1.threadStateGet()){
exampleThread1.threadStateSet(false);
buttonThreadOnOff.setText("Thread is Off");
}
else
{
exampleThread1.threadStateSet(true);
buttonThreadOnOff.setText("Thread is On");
exampleThread1 = new ExampleThread();
exampleThread1.start();
}
exampleThread1.mPrioritySet(prioIndx);
} });
}
private void editTextSetup(){
EditText editText1;
editTextThreadOutput = (EditText) findViewById(R.id.edit_text2);
editTextThreadOutput2 = (EditText) findViewById(R.id.edit_text22);
editText1 = (EditText) findViewById(R.id.edit_text1);
editTextPriority = (EditText) findViewById(R.id.edit_text3);
}
private void threadSetup(){
exampleThread1 = new ExampleThread();
exampleThread1.start();
exampleThread1.mPrioritySet(THREAD1_PRIORITY);
editTextPriority.setText("Thrd 1 Prio= " +THREAD1_PRIORITY+ " Thrd 2 Prio= " + THREAD2_PRIORITY);
exampleThread1.threadIDSet(0);
exampleThread2 = new ExampleThread();
exampleThread2.start();
exampleThread2.mPrioritySet(THREAD2_PRIORITY);
exampleThread2.threadIDSet(111111);
}
}
EditText editTextThreadOutput;
EditText editTextThreadOutput2;
EditText editTextPriority;
Button buttonThreadOnOff;
int prioIndx = 1;
ExampleThread exampleThread1;
ExampleThread exampleThread2;
final int THREAD2_PRIORITY = 10;
final int THREAD1_PRIORITY = 1;
/** Called when the activity is first created. */
@Override public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.main);
buttonSetup();
editTextSetup();
threadSetup();
}
public class ExampleThread extends Thread {
Handler mHandler = new Handler();
private final Runnable displayCounter = new Runnable() {
public void run() { displayCounterOnUi(counter, threadId); }
};
boolean mState = true;
int counter;
int threadId;
void mPrioritySet(int priority){
setPriority(priority);
}
ExampleThread() {
}
public void run() {
counter = 0;
while (mState) {
try {
Thread.sleep(10);
}
catch (InterruptedException e) {
}
counter++;
mHandler.post(displayCounter);
}
}
public void threadStateSet(boolean state) {
mState = state;
}
public boolean threadStateGet(){
return(mState);
}
public void threadIDSet(int val) {
threadId = val;
}
public void threadCounterClear() {
counter = 0;
}
}
public void displayCounterOnUi(int counter, int threadId){
if(0 == threadId){
editTextThreadOutput.setText(Integer.toString(counter));
}
else{
editTextThreadOutput2.setText(Integer.toString(counter));
}
}
private void buttonSetup(){
Button buttonSetPriority = (Button)findViewById(R.id.button_set_priority);
buttonSetPriority.setText("Thread Priority Set");
buttonSetPriority.setOnClickListener(
new Button.OnClickListener() {public void onClick(View v) {
if (0 == (prioIndx++)%10){
prioIndx = 1;
}
exampleThread1.mPrioritySet(prioIndx);
editTextPriority.setText("Thrd Priority = " +prioIndx+ " Thrd 2 Prio= " + THREAD2_PRIORITY);
exampleThread1.threadCounterClear();
exampleThread2.threadCounterClear();
} });
buttonThreadOnOff = (Button)findViewById(R.id.button_thread_onoff);
buttonThreadOnOff.setText("Thread is On");
buttonThreadOnOff.setOnClickListener(
new Button.OnClickListener() {public void onClick(View v) {
if(exampleThread1.threadStateGet()){
exampleThread1.threadStateSet(false);
buttonThreadOnOff.setText("Thread is Off");
}
else
{
exampleThread1.threadStateSet(true);
buttonThreadOnOff.setText("Thread is On");
exampleThread1 = new ExampleThread();
exampleThread1.start();
}
exampleThread1.mPrioritySet(prioIndx);
} });
}
private void editTextSetup(){
EditText editText1;
editTextThreadOutput = (EditText) findViewById(R.id.edit_text2);
editTextThreadOutput2 = (EditText) findViewById(R.id.edit_text22);
editText1 = (EditText) findViewById(R.id.edit_text1);
editTextPriority = (EditText) findViewById(R.id.edit_text3);
}
private void threadSetup(){
exampleThread1 = new ExampleThread();
exampleThread1.start();
exampleThread1.mPrioritySet(THREAD1_PRIORITY);
editTextPriority.setText("Thrd 1 Prio= " +THREAD1_PRIORITY+ " Thrd 2 Prio= " + THREAD2_PRIORITY);
exampleThread1.threadIDSet(0);
exampleThread2 = new ExampleThread();
exampleThread2.start();
exampleThread2.mPrioritySet(THREAD2_PRIORITY);
exampleThread2.threadIDSet(111111);
}
}
נתרכז באבני הבניין הדרושים לבניית המנגנון:
אוביקט של ה- ExampleThread. אנחנו כאמור יצרנו שניים כאלה. מסומנים בצהוב.
ה
ה
ההפעלה של ה-Thread - גם כאן ע"י start:
exampleThread2.start();
אובייקט ה-runnable:
private final Runnable displayCounter = new Runnable() {
public void run() { displayCounterOnUi(counter, threadId); }
public void run() { displayCounterOnUi(counter, threadId); }
};
displayCounterOnUi מתודה שתופעל ע"י ה-runnable. היא שייכת ל-class הראשי. מסומן באדום.
הפעלת ה-runnable:
mHandler.post(displayCounter);
אין תגובות:
הוסף רשומת תגובה