1. 程式人生 > >android 雙緩衝機制

android 雙緩衝機制

看了很多資料,翻啊翻啊,似乎有些瞭解了。

Android中對View的更新有很多種方式,使用時要區分不同的應用場合。我感覺最要緊的是分清:多執行緒和雙緩衝的使用情況。

現在可以嘗試理解下面的模擬場景:

兩個人:一對夫妻,老公上班,老婆在家,現在他們都要吃飯。

     “不使用多執行緒和雙緩衝”的情況是:老公在公司吃,老婆在家吃,互不干擾,吃就是了。

     “使用多執行緒和不使用雙緩衝”的情況是:老婆做好飯,另外讓人送一份到公司,老公收到飯就可以吃了。

     “使用多執行緒和使用雙緩衝”的情況是:老婆做好飯,等老公回家一起吃。

1.不使用多執行緒和雙緩衝

     這種情況最簡單了,一般只是希望在View發生改變時對UI進行重繪。你只需在Activity中顯式地呼叫View物件中的invalidate()方法即可。系統會自動呼叫

 View的onDraw()方法。

2.使用多執行緒和不使用雙緩衝

     這種情況需要開啟新的執行緒,新開的執行緒就不好訪問View物件了。強行訪問的話會報:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

     這時候你需要建立一個繼承了android.os.Handler的子類,並重寫handleMessage(Message msg)方法。android.os.Handler是能傳送和處理訊息的,你需要在Activity中發出更新UI的訊息,然後再你的Handler(可以使用匿名內部類)中處理訊息(因為匿名內部類可以訪問父類變數,

 你可以直接呼叫View物件中的invalidate()方法 )。也就是說:在新執行緒建立併發送一個Message,然後再主執行緒中捕獲、處理該訊息。

Java程式碼  收藏程式碼
  1. /** 
  2.  * 要在Activity中開啟一個用於更新的執行緒 
  3.  * timeViewHandler 繼承自Handler,用於處理和傳送訊息 
  4.  * MSG_UPDATE 是自定義的一個int常量,用於區分訊息型別,可自由取值。 
  5.  */  
  6. new Thread(new Runnable() {  
  7.     @Override  
  8.     public void run() {  
  9.         while(true
    ){  
  10.             try {  
  11.                 timeViewHandler.sendMessage(Message.obtain(timeViewHandler, MSG_UPDATE));  
  12.                 Thread.sleep(1000);  
  13.             } catch (InterruptedException e) {  
  14.                 e.printStackTrace();  
  15.             }   
  16.         }  
  17.     }  
  18. }).start();  
Java程式碼  收藏程式碼
  1. /** 
  2.  * Handler示例,用於重新整理時間 
  3.  * DateHelper是我自己寫的日期格式化工具哦 
  4.  * @author Dreamworker 
  5.  * 
  6.  */  
  7. public class TimeViewHandler extends Handler {  
  8.     private TextView timeView;  
  9.     public TextView getTimeView() {  
  10.         return timeView;  
  11.     }  
  12.     public void setTimeView(TextView timeView) {  
  13.         this.timeView = timeView;  
  14.     }  
  15.     public TimeViewHandler(TextView timeView) {  
  16.         super();  
  17.         this.timeView = timeView;  
  18.     }  
  19.     @Override  
  20.     public void handleMessage(Message msg) {  
  21.         switch (msg.what) {  
  22.             case MSG_UPDATE:  
  23.                 timeView.setText(DateHelper.getNow("kk:mm:ss"));  
  24.                 timeView.invalidate();  
  25.                 break;  
  26.         }  
  27.         super.handleMessage(msg);  
  28.     }  
  29. }  

3.使用多執行緒和雙緩衝

    Android中SurfaceView是View的子類,她同時也實現了雙緩衝。你可以定義一個她的子類並實現SurfaceHolder.Callback介面。由於實現SurfaceHolder.Callback介面,新執行緒就不需要android.os.Handler幫忙了。SurfaceHolder中lockCanvas()方法可以鎖定畫布,繪製玩新的影象後呼叫unlockCanvasAndPost(canvas)解鎖(顯示),還是比較方便得。

Java程式碼  收藏程式碼
  1. /** 
  2. * SurfaceView使用示例,TouchDrawView主要完成螢幕的指尖繪畫 
  3. * TouchDrawListener是我自己寫的監聽器,就不妨礙大家視線了。 
  4. */  
  5. public class TouchDrawView extends SurfaceView implements SurfaceHolder.Callback{  
  6.     private SurfaceHolder holder;  
  7.     private TouchDrawListener listener;  
  8.     public TouchDrawListener getListener() {  
  9.         return listener;  
  10.     }  
  11.     public void setListener(TouchDrawListener listener) {  
  12.         this.listener = listener;  
  13.     }  
  14.     public TouchDrawView(Context context) {  
  15.         super(context);  
  16.         holder = getHolder();  
  17.         holder.addCallback(this);  
  18.         listener = new TouchDrawListener(holder);  
  19.         listener.setShape(TouchDrawListener.SHAPE_LINE);  
  20.         listener.setShape_style(TouchDrawListener.SHAPE_STYLE_FILL);  
  21.         this.setOnTouchListener(listener);//設定螢幕事件監聽器  
  22.         this.setLongClickable(true);//不設定將無法捕捉onFling()事件  
  23.         setFocusable(true);//設定鍵盤焦點  
  24.         setFocusableInTouchMode(true);//設定觸控式螢幕焦點  
  25.     }  
  26.     public TouchDrawView(Context context, AttributeSet as) {  
  27.         this(context);  
  28.     }  
  29.     @Override  
  30.     protected void onDraw(Canvas canvas) {    
  31.     }  
  32.     @Override  
  33.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  34.             int height) {  
  35.     }  
  36.     @Override  
  37.     public void surfaceCreated(SurfaceHolder holder) {  
  38.                  //關鍵部分  
  39.         Canvas canvas = holder.lockCanvas(null);//獲取畫布    
  40.         canvas.drawColor(Color.WHITE);//白色背景  
  41.         holder.unlockCanvasAndPost(canvas);//解鎖畫布,提交畫好的影象    
  42.     }  
  43.     @Override  
  44.     public void surfaceDestroyed(SurfaceHolder holder) {  
  45.     }  
  46. }  

相關推薦

android 緩衝機制

看了很多資料,翻啊翻啊,似乎有些瞭解了。 Android中對View的更新有很多種方式,使用時要區分不同的應用場合。我感覺最要緊的是分清:多執行緒和雙緩衝的使用情況。 現在可以嘗試理解下面的模擬場景: 兩個人:一對夫妻,老公上班,老婆在家,現在他們都要吃飯。  

SurfaceView緩衝機制

什麼是緩衝? 在我們的介面中圖形都是在畫布上繪製出來的,所以這個繪製的過程就叫緩衝,而畫布也就可以稱作緩衝區。 緩衝的種類: 無緩衝:不使用畫布的情況下直接在視窗上進行繪圖就叫做無緩衝繪圖。 單緩衝:用了一個畫布,將所有的內容先繪製到畫布上,再整體繪製到視窗,這個就叫做單緩衝繪圖

c# 窗體緩衝機制

以下是msdn的說明: 雙緩衝使用記憶體緩衝區來解決由多重繪製操作造成的閃爍問題。 當啟用雙緩衝時,所有繪製操作首先呈現到記憶體緩衝區,而不是螢幕上的繪圖圖面。所有繪製操作完成後,記憶體緩衝區直接複製到與其關聯的繪圖圖面。因為只在螢幕上執行一項圖形操作,所以消除了與複雜繪圖

VC GDI緩衝機制繪圖防螢幕閃爍實現步驟

引用:http://blog.csdn.net/xgx198831/article/details/8268731 在OnDraw(CDC* pDC) 中新增如下程式碼      CDC MemDC; //首先定義一個顯示裝置物件   CBitmap MemBitma

Android緩衝技術

    Android中的SurfaceView類就是雙緩衝機制。因此,開發遊戲時儘量使用SurfaceView而不要使用View,這樣的話效率較高,而且SurfaceView的功能也更加完善。為了更容

android緩衝

 canvas的頁面交換的確為遊戲開發初學者帶來了困擾我經過多次實踐之後發現了一個完美的方法:用一個後臺畫布bk_canvas,所有更新畫圖都在這上面進行。當然dirtyRectList你只用維護一個了,每次畫的時候先在bk_canvas上畫好了,然後在把bk_canvas拷

STM32 USB 程式將BULK EP改成緩衝機制後,接收OUT資料的速度從原先的500KB/S,

前天測試自己編寫的USB驅動程式時候發現從主機到STM32的OUT傳輸(主機到裝置)速率竟然只有最高33KB/S,實在是暈死了。經過研究後發現是驅動程式中設定的PIPE MaxTransferSize引數的關係,原先設定64只能33KB/S,後參考其他USB裝置驅動程式的值,設定成了65535,再測試USB

Android緩衝繪圖 Bitmap和Canvas 一看就懂

package graphics; import java.util.Random; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.gr

初學Android 圖形影象之使用緩衝畫圖 二十七

                 當資料量很大時,繪圖可能需要幾秒鐘甚至更長的時間,而且有時還會出現閃爍現象,為了解決這些問題,可採用雙緩衝技術來繪圖。 雙緩衝即在記憶體中建立一個與螢幕繪圖區域一致的物件,先將圖形繪製到記憶體中的這個物件上,再一次性將這個物件上的圖形拷貝到螢幕上,這樣能大大加快繪圖的速度。雙

初學Android,圖形影象之使用緩衝畫圖(二十七)

 當資料量很大時,繪圖可能需要幾秒鐘甚至更長的時間,而且有時還會出現閃爍現象,為了解決這些問題,可採用雙緩衝技術來繪圖。 雙緩衝即在記憶體中建立一個與螢幕繪圖區域一致的物件,先將圖形繪製到記憶體中的這個物件上,再一次性將這個物件上的圖形拷貝到螢幕上,這樣能大大加快繪圖的速度。

Android圖形系統的分析與移植--七、緩衝framebuffer的實現

1  實現原理在基本的FrameBuffer已經實現的基礎上,需要實現的是與Android原本模擬器所使用的goldfish FrameBuffer之間的區別。比較一下不難發現,從以下及方面著手:1.                  修改初始化FrameBuffer資訊;2

android surfaceView緩衝問題的髒矩形重新整理

surfaceView是安卓中畫圖的重要元件,好處及基本用法就不說了,網上一把一把的,今天我們要討論的是surfaceview在使用過程中容易出現的背景丟失及閃爍的問題,這就是這篇文章要討論的surfaceView雙緩衝問題的髒矩形重新整理.我將通過surfac

Android中 view的緩衝技術

view實現雙緩衝技術 當要繪製的資料量比較大,繪圖時間比較長時,重複繪圖會出現閃爍現象,引起閃爍現象的主要原因是視覺反差比較大。 使用雙緩衝技術可以解決這個問題,Surfaceview預設是使用雙緩衝技術的。 在Android上實現雙緩衝技術的步驟是: 建立一個螢幕大小(實際繪圖區域)的緩衝區(

Android View 緩衝技術

Android中的SurfaceView類就是雙緩衝機制。因此,開發遊戲時儘量使用SurfaceView而不要使用View,這樣的話效率較高,而且SurfaceView的功能也更加完善。為了更容易的瞭解雙緩衝技術,下面介紹用View實現雙緩衝的方法。     先概述一下

android繪製知識--緩衝繪圖技術

今天我們說下雙緩衝繪圖技術。其實也沒有那麼神祕,可以理解為就是一個裝載工具,說點接地氣的比如搬磚。我們每次可以搬十塊磚,從A搬到B,如果是就搬十塊我們當然是直接搬過去比較快,但是如果是一百或者一千塊呢?你直接搬效率肯定很低,於是我們用身邊的小推車一直裝上然後推過

Android消息機制1-Handler(Java層)(轉)

word get() als php lib light ora out getc 轉自:http://gityuan.com/2015/12/26/handler-message-framework/ 相關源碼 framework/base/core/java/an

Android消息機制——Handler

code port 過程 imp set mpat current ppc 銷毀 1 /**android的消息處理有三個核心類:Looper,Handler和Message。其實還有一個MessageQueue(消息隊列), 2 * 但是Messag

【原創】源碼角度分析Android的消息機制系列(一)——Android消息機制概述

run 權限 開發 等待 通過 讀取 概述 走了 color ι 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 1.為什麽需要Android的消息機制 因為Android系統不允許在子線程中去訪問UI,即Android系統不允許在子線程中更新UI。 為什麽不允許

android 消息機制與仿新聞客戶端

android 消息機制 仿新聞客戶端 效果圖如下:具體步驟如下:1 布局文件中控件的設計2 訪問遠程服務器的資源xml文件,該文件包含新聞的內容等信息3 訪問到內容後把訪問內容顯示到頁面上具體代碼如下:1 MainActivitypackage com.yuanlp.newsclient; i

Android 消息機制

new 需要 一個 目標 width handle rri his 技術 一、 Handler 1、使用 <1>在主線程中定義一個 Handler, 重寫 handleMessage 方法 //在主線程中定義一個Handler private