Android 中 View 與 SurfaceView 主動(dòng)與被動(dòng)更新的應(yīng)用場(chǎng)景

在 Android 開(kāi)發(fā)中,ViewSurfaceView 是兩種常用的視圖繪制組件睛琳。它們雖然都能用于繪制內(nèi)容,但其更新機(jī)制不同踏烙,分別適用于不同的場(chǎng)景师骗。理解它們的區(qū)別,有助于在開(kāi)發(fā)中選擇合適的組件讨惩。


View 是 Android 中最常見(jiàn)的 UI 組件辟癌,它的繪制過(guò)程由系統(tǒng)的主線(xiàn)程(UI 線(xiàn)程)管理。通常情況下荐捻,View 只有在需要時(shí)才會(huì)刷新黍少,比如當(dāng)我們調(diào)用 invalidate() 方法時(shí),系統(tǒng)會(huì)在下一次繪制周期內(nèi)更新視圖处面。這種機(jī)制被稱(chēng)為主動(dòng)更新厂置,因?yàn)殚_(kāi)發(fā)者需要顯式請(qǐng)求視圖更新。

示例

假設(shè)有一個(gè)按鈕魂角,點(diǎn)擊按鈕后改變其背景顏色昵济。此時(shí)可以在 onClick() 方法中調(diào)用 invalidate() 來(lái)觸發(fā)更新。系統(tǒng)將會(huì)在下一個(gè)繪制周期重新繪制這個(gè)按鈕野揪。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        button.setBackgroundColor(Color.RED);
        button.invalidate();  // 主動(dòng)請(qǐng)求重新繪制
    }
});

總結(jié)

View 適用于不需要頻繁刷新的場(chǎng)景访忿,通過(guò)事件觸發(fā)或手動(dòng)調(diào)用 invalidate(),系統(tǒng)會(huì)在下一次繪制周期中進(jìn)行更新斯稳。典型應(yīng)用場(chǎng)景包括用戶(hù)交互驅(qū)動(dòng)的 UI 更新海铆,如點(diǎn)擊按鈕、滑動(dòng)手勢(shì)等挣惰。


2. SurfaceView:適用被動(dòng)更新游添,頻繁刷新

SurfaceView 則是另一種更適合高頻率繪制任務(wù)的組件。與 View 不同通熄,SurfaceView 擁有自己的獨(dú)立繪制線(xiàn)程唆涝,通常在子線(xiàn)程中進(jìn)行復(fù)雜的繪制操作。這意味著 SurfaceView 能夠在主線(xiàn)程之外進(jìn)行繪制唇辨,并且支持更頻繁的內(nèi)容更新廊酣。被動(dòng)更新 指的是通過(guò)持續(xù)的刷新循環(huán)更新視圖內(nèi)容,適合用于高幀率動(dòng)畫(huà)赏枚、游戲渲染亡驰、視頻播放等場(chǎng)景晓猛。

示例

在游戲場(chǎng)景中,角色的移動(dòng)和場(chǎng)景的動(dòng)畫(huà)需要頻繁更新凡辱。這時(shí)可以使用 SurfaceView 并在獨(dú)立的線(xiàn)程中不斷刷新屏幕戒职。

class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private GameThread gameThread;

    public GameSurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        gameThread = new GameThread(holder);
        gameThread.setRunning(true);
        gameThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        gameThread.setRunning(false);
        while (retry) {
            try {
                gameThread.join();
                retry = false;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class GameThread extends Thread {
        private SurfaceHolder surfaceHolder;
        private boolean running;

        public GameThread(SurfaceHolder surfaceHolder) {
            this.surfaceHolder = surfaceHolder;
        }

        public void setRunning(boolean running) {
            this.running = running;
        }

        @Override
        public void run() {
            while (running) {
                Canvas canvas = null;
                try {
                    canvas = surfaceHolder.lockCanvas();
                    synchronized (surfaceHolder) {
                        // 執(zhí)行頻繁的繪制操作
                        canvas.drawColor(Color.BLACK);  // 清空畫(huà)布
                        // 其他繪制操作...
                    }
                } finally {
                    if (canvas != null) {
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
    }
}

總結(jié)

SurfaceView 適用于需要頻繁刷新和復(fù)雜渲染的場(chǎng)景。它通過(guò)獨(dú)立線(xiàn)程進(jìn)行渲染透乾,避免了主線(xiàn)程的阻塞洪燥,特別適合游戲、視頻播放或需要高幀率更新的場(chǎng)景乳乌。


3. 主動(dòng)更新 vs 被動(dòng)更新 總結(jié)

  • View 的主動(dòng)更新:適合不頻繁更新的操作捧韵,如按鈕點(diǎn)擊、UI 交互汉操。這些更新通過(guò) invalidate() 請(qǐng)求再来,由系統(tǒng)在下一個(gè)繪制周期進(jìn)行處理。適合大部分 UI 控件的場(chǎng)景磷瘤。
  • SurfaceView 的被動(dòng)更新:適用于高頻更新的場(chǎng)景芒篷,通過(guò)子線(xiàn)程不斷進(jìn)行繪制,適合游戲渲染采缚、視頻播放等需要持續(xù)梭伐、頻繁更新的場(chǎng)景。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仰担,一起剝皮案震驚了整個(gè)濱河市糊识,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摔蓝,老刑警劉巖赂苗,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異贮尉,居然都是意外死亡拌滋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)猜谚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)败砂,“玉大人,你說(shuō)我怎么就攤上這事魏铅〔蹋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵览芳,是天一觀(guān)的道長(zhǎng)斜姥。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么铸敏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任缚忧,我火速辦了婚禮,結(jié)果婚禮上杈笔,老公的妹妹穿的比我還像新娘闪水。我一直安慰自己,他們只是感情好蒙具,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布球榆。 她就那樣靜靜地躺著,像睡著了一般店量。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鞠呈,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天融师,我揣著相機(jī)與錄音,去河邊找鬼蚁吝。 笑死旱爆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窘茁。 我是一名探鬼主播怀伦,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼山林!你這毒婦竟也來(lái)了房待?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驼抹,失蹤者是張志新(化名)和其女友劉穎桑孩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體框冀,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡流椒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了明也。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宣虾。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖温数,靈堂內(nèi)的尸體忽然破棺而出绣硝,到底是詐尸還是另有隱情,我是刑警寧澤撑刺,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布域那,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏次员。R本人自食惡果不足惜败许,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淑蔚。 院中可真熱鬧市殷,春花似錦、人聲如沸刹衫。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)带迟。三九已至音羞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仓犬,已是汗流浹背嗅绰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搀继,地道東北人窘面。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叽躯,于是被迫代替她去往敵國(guó)和親财边。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容