พฤศจิกายน 22, 2017, 10:56:15 am *
ยินดีต้อนรับคุณ, บุคคลทั่วไป กรุณา เข้าสู่ระบบ หรือ ลงทะเบียน
ส่งอีเมล์ยืนยันการใช้งาน?

เข้าสู่ระบบด้วยชื่อผู้ใช้ รหัสผ่าน และระยะเวลาในเซสชั่น
   หน้าแรก   ช่วยเหลือ เข้าสู่ระบบ สมัครสมาชิก  
หน้า: [1]   ลงล่าง
  พิมพ์  
ผู้เขียน หัวข้อ: Thread and Handler with Progress Dialog  (อ่าน 4903 ครั้ง)
0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8267


ShadowWares


| |
« เมื่อ: ธันวาคม 18, 2012, 01:19:08 pm »

Thread and Handler with Progress Dialog

เรื่องการเขียนการทำงานอบบ Multi-threading ที่ต้องมีการเข้าถึง UI เป็นปัญหาหนักหัวใจในทุกภาษา (นั่นยังไม่รวมเรื่องการ Synchronization รูปแบบต่างๆ) ไม่เว้นแม้กระทั่งภาษาระดับสูงที่ถูกออกแบบมาให้ง่ายต่อการเขียนโปรแกรม เช่น C# และ Java

สำหรับ C/C++ Programmer เรื่องการจัดการกับอะไรต่อมิอะไร ที่รันอยู่บนคอมพิวเตอร์เครื่องเดียวกัน หรือเครือข่ายเดียวกันนั้น ปัญหาเหล่านี้แก้ได้อย่างง่ายดายเพียงแค่รู้เรื่อง "pointer to void" และ "Data structure" แต่ไม่ง่ายเลยที่จะรู้ไปถึงระดับใช้งานจริงได้ เพราะนอกจากจะต้องเชี่ยวชาญเรื่อง pointer แล้วยังจะต้องรู้เรื่องพฤติกรรมของ Graphic Driver และ การทำงาของ Kernel อีกด้วย เพราะฉนั้นห่างๆ มันไว้อาจจะทำให้ชีวิตง่ายขึ้น

C# และ Java ไม่ต้องการความรู้เชิงลึก แต่ต้องการความรอบรู้ของ Programmer เพราะการเขียนโปรแกรมด้วยภาษาระดับสูงเหล่านี้คือการเลือกใช้เครื่องมือให้เหมาะกับงาน ไม่ใช่การเขียนโปรแกรมควบคุม OS หรือ CPU เหมือน C/C++ และภาษาที่เกิดขึ้นมาในยุคต้นๆ

เรื่องของ Thread และ GUI ในมุมมองของ C/C++ Programmer เชื่อมไป C# และ Java:
สำหรับ C# Programmer สิ่งที่ต้องรู้คือ Delegate (มองเป็น Pointer to function/object ใน C/C++)
และ สำหรับ Java Programmer สิ่งที่ต้องรู้คือ Handler (มองเป็น WaitForSingleObject ใน Win32 C/C++ Programming)
(ผมมองในฐานะที่ผมเป็น Programmer มือสมัครเล่นคนหนึ่ง ที่เขียนโปรแกรมหลากภาษา และหาลู่ทางเชื่อมโยงความสัมพันธ์ของสิ่งต่างๆ ที่ผมเรียนรู้อยู่เท่านั้น อย่าปักใจเชื่อจนกว่าจะพิสูจน์ให้เห็นด้วยตัวเอง หรือได้รับการชี้แจงจากผู้เชี่ยวชาญในศาสตร์นั้นๆ)
นอกจากนี้ยังมีสิ่งที่อำนวยความสะดวกได้อีกนับไม่ถ้วน ที่จะมาช่วยอำนวยความสะดวก




เพื่อให้เห็นถึงความง่ายของ Java ในบทความนี้จะแนะนำเทคนิคการ update Progress Dialog ในส่วนของ Message (ข้อความที่แสดงผลอยู่บน Progress Dialog ) โดยใช้ความสามารถของ Handler และ Thread ซึ่งเป็นความสามารถของ Java
การทำงานคือ จะให้แสดงหน้าต่าง Progress Dialog และแสดงผลคำว่า "Please wait X second(s)" เมื่อ X คือตัวเลขที่จะนับลงเรื่อยๆ จาก 10 ถึง 0
และเมื่อนับลงถึง 0 จะทำการปิด Progress Dialog

รูปร่างของ Progress Dialog จะเป็นแบบนี้ (รายละเอียดที่เห็นขึ้น version และ theme)


 


เริ่มจากการออกแบบ UI ง่ายๆ นั่นคือมีปุ่ม (Button) หนึ่งตัว มองในรูปของ XML ได้ตามนี้



ต่อไปเขียนโปรแกรมควบคุมการทำงานดังนี้
Code: (java)
package com.shadowwares.santi.threadhandler;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

   protected ProgressDialog dialog;
   protected Handler handler;
   protected int sec = 10;
   volatile boolean  running = true;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Button button = (Button) findViewById(R.id.button1);
      button.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            sec = 10;  running  = true;
            dialog = ProgressDialog.show(MainActivity.this, "Loading", "Please wait " + sec + " seconds");
            handler = new Handler() {
               @Override
               public void handleMessage(Message msg) {
                  // super.handleMessage(msg);
                  dialog.setMessage("Please wait "+(--sec)+" second"+((sec>1)?"s":""));
                  if (sec <= 0){
                     dialog.dismiss();
                     running = false;
                  }
               }
            };

            new Thread() {
               @Override
               public void run() {
                  // super.run();
                  while (running) {
                     try {
                        Thread.sleep(1000);
                        handler.sendEmptyMessage(0);
                     } catch (InterruptedException e) {
                        e.printStackTrace();
                     }
                  }
               }
            }.start();
         }
      });
   }
}




ในส่วนของ onClick() แยกได้เป็นสองส่วนคือ ส่วนของ Handler:
Code: (java)
handler = new Handler() {
   @Override
   public void handleMessage(Message msg) {
      // super.handleMessage(msg);
      dialog.setMessage("Please wait "+(--sec)+" second"+((sec>1)?"s":""));
      if (sec <= 0){
         dialog.dismiss();
         running = false;
      }
   }
};


และส่วนของ Thread:
Code: (java)
new Thread() {
   @Override
   public void run() {
      // super.run();
      while (running) {
         try {
            Thread.sleep(1000);
            handler.sendEmptyMessage(0);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }
}.start();


จะเห็นได้ว่าเมื่อ Button ถูกคลิก Progress Dialog จะถูกสร้างและสั่งให้แสดงผลขึ้นมา และในเวลาเดียวกันนี้ Handler และ Thread จะถูกสร้างขึ้นมา และทำงานทันที

Handler จะทำการรอ Thread's Message (มองเป็นสัญญาณกระตุ้น หรือไฟเขียวก็ได้) จาก Thread และทันที่ได้ที่ได้รับไฟเขียวจาก Thread จะทำการลดค่าตัวแปร sec ลงหนึ่ง ตามด้วยการ update ข้อความที่ Progress Dialog การทำงานจะเป็นแบบนี้ไปเรื่อยๆ จนกระทั่งตัวแปร sec มีค่าลดลงถึง 0
เมื่อตัวแปร sec มีค่าลดลงถึง 0 แล้ว  Progress Dialog จะถูกปิดลง ในเวลาเดียวกันนี้ตัวแปร running จะถูกทำให้มีค่าเป็น false เพื่อส่งสัญญาณบอก Thread ให้ทราบว่า "หยุดได้แล้ว งานเสร็จสิ้น"

พิจารณาที่ Thread จะเห็นได้ว่าไม่มีอะไรมากไปกว่าการวนลูปกระทำซ้ำแบบมีเงื่อนไข นั่นคือวนลูปไปเรื่อยๆ ตราบเท่าที่ตัวแปร running ยังคงมีค่าเท่ากับ true ในแต่ละลูปของการทำงาน จะทำการหน่วงเวลา 1 วินาที และส่ง Message ไปให้ Handler และการวนลูปทำงานนี้จะจบลงเมื่อตัวแปร running มีค่าเท่ากับ false นั่นเอง

เทคนิคนี้สามารถนำไปใช้กับ Progress Bar  ฝากให้คิดเป็นแบบฝึกหัด และแก้ปัญหาการเข้าถึง Widget แบบอื่นๆ จาก Thread ที่ได้กล่าวถึงไปในบทความตอนก่อนหน้า ได้เช่นกัน
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
หน้า: [1]   ขึ้นบน
  พิมพ์  
 
กระโดดไป: