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

เข้าสู่ระบบด้วยชื่อผู้ใช้ รหัสผ่าน และระยะเวลาในเซสชั่น
   หน้าแรก   ช่วยเหลือ เข้าสู่ระบบ สมัครสมาชิก  
หน้า: [1]   ลงล่าง
  พิมพ์  
ผู้เขียน หัวข้อ: Using The SurfaceView in High Frame Rate Application (For GAME Developers)  (อ่าน 4368 ครั้ง)
0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

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


ShadowWares


| |
« เมื่อ: ธันวาคม 29, 2012, 01:26:35 pm »

Using The SurfaceView/SurfaceHolder in High Frame Rate Application (For GAME Developers)

SurfaceView/SurfaceHolder ออกแบบมาสำหรับการวาดการแสดงผลแบบ Low-Level ให้ประสิทธิภาพสูงกว่าการวาดลงไปยัง Canvas (วาดที่ OnDraw())  
SurfaceView/SurfaceHolder เหมาะกับ Application ที่ต้องการ Update การแสดงผลด้วย Frame Rate สูงๆ เช่นเกมส์ หรือ Animation รูปแบบต่างๆ ซึ่ง Apllication เหล่านี้จะมาพร้อมกับ Thread ที่เป็นตัวควบคุมจังหวะ หรือความถี่ในการ Update การแสดงผลอยู่เสมอ
ในระดับของการ Implement นั้นยังคงความยืดหยุ่นไปตามรูปแบบการเขียนโปรแกรมด้วยภาษา Java ในที่นี้จะยกตัวอย่างรูปแบบการใช้งาน เพื่อให้เห็นว่า การใช้ SurfaceView/SurfaceHolder ร่วมกับ Thread นั้นมีองค์ประกอบอะไรบ้าง



Main-Class (MainActivity)
Code: (java)
package com.shadowwares.santi.usingsurefaceview;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

   SurfView SurfView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      SurfView = new SurfView(this);
      setContentView(SurfView);
   }

   protected void onResume() {
      super.onResume();
      SurfView.onResumeTheSurfaceView();
   }

   @Override
   protected void onPause() {
      super.onPause();
      SurfView.onPauseTheSurfaceView();
   }

   protected void onStop() {
      super.onStop();
      SurfView.onPauseTheSurfaceView();
   }
}


SurfView-Class (SurfaceView)
Code: (java)
package com.shadowwares.santi.usingsurefaceview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfView extends SurfaceView implements Runnable {
   Thread thread = null;
   SurfaceHolder surfaceHolder;
   volatile boolean running = false;
   private Paint paint = new Paint();

   public SurfView(Context context) {
      super(context);
      surfaceHolder = getHolder();
   }

   public void onResumeTheSurfaceView() {
      running = true;
      thread = new Thread(this);
      thread.start();
   }

   public void onPauseTheSurfaceView() {
      boolean retry = true;
      running = false;
      while (retry) {
         try {
            thread.join();
            retry = false;
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

   @Override
   public void run() {
      while (running) {
         Canvas canvas = null;
         if (surfaceHolder.getSurface().isValid()) {
            try{
               canvas = surfaceHolder.lockCanvas();
               synchronized (surfaceHolder) {
                  /*
                   ***********************************
                   *        Draw to the canvas       *
                   ***********************************
                   */
               }
            }
            finally{
               if(canvas != null){
                  surfaceHolder.unlockCanvasAndPost(canvas);
               }
            }
         }
      }

      try {
         Thread.sleep(33);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
   }
}


สิ่งที่ต้องพึงระวังให้มากในการเขียนโปรแกรมเกี่ยวกับ Thread ใน Android-Based Mobile Devices คือ Thread จะต้องไม่ทำงาน ถ้าการทำงานนั้นไม่ส่งผลต่อ Application ยกตัวอย่างเช่น  Thread ที่ใช้ในการวาด UI ของ Application นี้ไม่ควรจะทำงานต่อไป และ/หรือ ควรจะคืนหน่วยความจำให้ระบบเมื่อ User เปิดโปรแกรมอื่นขึ้นมาใช้งาน เมื่อ User ทำการเปิด Application นี้ขึ้นมาอีกครั้ง จึงค่อยทำการสั่งให้ Thread ทำงาน และ/หรือ ขอหน่วยความจำมาทำการจัดการกับ UI ต่อไป (ประหยัดทรัพยากรของระบบ ไม่ว่าจะเป็น CPU, Memory และ Battery)
อีกตัวนึงที่ต้องศึกษาและระวังให้มากคือ เมื่อจอถูกหมุน (แนวตั้ง แนวนอน) มี Events/Handers อะไรเกิดขึ้นบ้าง ยกตัวอย่างเช่น เมื่อ Application ถูกสั่งให้รันจะมี Event onCreate() ตามด้วย onResume() เกิดขึ้น และเมื่อจอถูกหมุน จะมี onPause() ตามด้วย onResume() หรือเมื่อ Application ถูกปิดจะมี onStop() เกิดขึ้น เป็นต้น  สิ่งเหล่านี้จำเป็นจะต้องศึกษาให้เข้าใจก่อนที่จะสร้าง Application ต่างๆ บนโลกของ Android รวมถึง Mobile OS อื่นๆ

ในที่นี้จะเห็นว่าผมทำการสร้าง Thread ที่จัดการกับ UI (Update Display) ที่ onResume() และทำการสั่งให้ Thread หยุดการทำงานที่ onPause() และ onStop()  

สิ่งที่ต้องให้ความสำคัญไม่แพ้ส่วนอื่นคือ การตรวจสอบและจัดการกับความผิดพลาดที่เกิดขึันตอนที่โปรแกรมกำลังทำงานอยู่ (Run-time Error Handle) ในที่นี้คือ try/catch/finally รวมไปถึงการทำ Thread Synchronization เพื่อป้องกันปัญหาที่เกิดขึ้นจากการทำงานแบบ Multitasking ในที่นี้คือ synchronized(){ } นั่นเอง
บันทึกการเข้า

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