最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android SurfaceView與TextureView使用方法詳細(xì)講解

 更新時(shí)間:2022年10月31日 17:00:48   作者:幸大叔  
SurfaceView和TextureView都繼承View,與普通的View不同的是,它倆可以在獨(dú)立線程中繪制渲染,性能更高,所以常被應(yīng)用在對(duì)繪制速率要求比較高的場(chǎng)景,比如相機(jī)預(yù)覽,視頻播放等等

Surface

官方對(duì)Surface的解釋是:由屏幕合成器管理的原始緩沖區(qū)上的句柄,所謂原生緩沖器,是用于保存當(dāng)前窗口的像素?cái)?shù)據(jù)的,也就是說(shuō),通過(guò)Surface可以獲取原生緩沖器以及其中的內(nèi)容。Surface對(duì)應(yīng)一塊屏幕緩沖區(qū),每個(gè)Window對(duì)應(yīng)一個(gè)Surface,任何View都畫(huà)在Surface上,Surface中的Canvas,是用于提供畫(huà)圖的地方。

SurfaceView

SurfaceView與普通的View不同,它擁有自己的Surface,它的工作方式是創(chuàng)建一個(gè)區(qū)別于應(yīng)用窗口的新窗口,與宿主窗口分離,可以在單獨(dú)線程中處理業(yè)務(wù),不受View的屬性控制,無(wú)法進(jìn)行平移縮放等轉(zhuǎn)換,它是通過(guò)“雙緩沖”機(jī)制來(lái)達(dá)到高效的界面刷新效果。

雙緩沖技術(shù)是把要處理的圖片在內(nèi)存中處理好之后,再將其顯示在屏幕上。雙緩沖主要是為了解決反復(fù)局部刷屏帶來(lái)的閃爍。把要畫(huà)的東西先畫(huà)到一個(gè)內(nèi)存區(qū)域里,然后整體的一次性畫(huà)出來(lái)。

下面通過(guò)一個(gè)相機(jī)預(yù)覽的功能,來(lái)看一下SurfaceView的具體使用

private lateinit var surfaceHolder: SurfaceHolder

獲取攝像機(jī)管理類(lèi),打開(kāi)某個(gè)具體的攝像機(jī),在打開(kāi)成功的回調(diào)里面,創(chuàng)建預(yù)覽請(qǐng)求

        val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
        val surfaceView = findViewById<SurfaceView>(R.id.surfaceView)
        surfaceHolder = surfaceView.holder
        surfaceHolder.setKeepScreenOn(true)
        surfaceHolder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(p0: SurfaceHolder) {
                if (ActivityCompat.checkSelfPermission(
                        this@SurfaceActivity,
                        Manifest.permission.CAMERA
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    //無(wú)相機(jī)權(quán)限
                    return
                }
                try {
                    //獲取可用相機(jī)設(shè)備列表
                    val cameraIdList = cameraManager.cameraIdList
                    //打開(kāi)相機(jī)
                    cameraManager.openCamera(
                        cameraIdList[0],
                        //攝像頭創(chuàng)建監(jiān)聽(tīng)
                        object : CameraDevice.StateCallback() {
                            override fun onOpened(p0: CameraDevice) { //打開(kāi)攝像頭
                                try {
                                    startPreview(p0)
                                } catch (e: CameraAccessException) {
                                    e.printStackTrace()
                                }
                            }
                            override fun onDisconnected(p0: CameraDevice) { //關(guān)閉攝像頭
                                p0.close()
                            }
                            override fun onError(p0: CameraDevice, p1: Int) {
                                Log.i(tag, "CameraDevice.StateCallback onError")
                            }
                        },
                        null
                    )
                } catch (e: CameraAccessException) {
                    e.printStackTrace()
                }
            }
            override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {
                Log.i(tag, "surfaceChanged")
            }
            override fun surfaceDestroyed(p0: SurfaceHolder) {
                Log.i(tag, "surfaceDestroyed")
            }
        })

開(kāi)始預(yù)覽

    private fun startPreview(cameraDevice: CameraDevice) {
        val captureRequest = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
        captureRequest.addTarget(surfaceHolder.surface)
        cameraDevice.createCaptureSession(
            listOf(surfaceHolder.surface),
            //會(huì)話狀態(tài)回調(diào)
            object : CameraCaptureSession.StateCallback() {
                override fun onConfigured(p0: CameraCaptureSession) {
                    try {
                        // 創(chuàng)建預(yù)覽需要的CaptureRequest.Builder
                        val previewRequestBuilder =
                            cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
                        previewRequestBuilder.addTarget(surfaceHolder.surface)
                        val previewRequest = previewRequestBuilder.build()
                        p0.setRepeatingRequest(previewRequest, null, null)
                    } catch (e: CameraAccessException) {
                        e.printStackTrace()
                    }
                }
                override fun onConfigureFailed(p0: CameraCaptureSession) {
                    Log.i(tag, "onConfigureFailed")
                }
            }, null
        )
    }

這樣,簡(jiǎn)易的相機(jī)預(yù)覽功能就出來(lái)啦,當(dāng)然,我們還需要申請(qǐng)CAMERA權(quán)限,這里略去。

TextureView

TextureView可以說(shuō)是一個(gè)結(jié)合了View和SurfaceTexture的View對(duì)象,一個(gè)可以把內(nèi)容流作為外部紋理輸出在上面的 View,它只能用于開(kāi)啟了硬件加速的窗口,TextureView不會(huì)創(chuàng)建一個(gè)獨(dú)立的窗口,而是像普通的View一樣,可以進(jìn)行平移、旋轉(zhuǎn)等動(dòng)畫(huà),TextureView在Andriod 4.0之后的 API 中才能使用,不過(guò)現(xiàn)在的安卓設(shè)備基本不存在Andriod 4.0之前的版本了,所以這點(diǎn)不必在意。

TextureView的使用也比較簡(jiǎn)單,需要獲取到它的SurfaceTexture,然后就可以以此來(lái)渲染了,下面通過(guò)一個(gè)簡(jiǎn)易的視頻播放的示例,來(lái)瞧瞧它是怎么使用的。

        val textureView = findViewById<TextureView>(R.id.textureView)
        val mediaPlayer = MediaPlayer()
        textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
            override fun onSurfaceTextureAvailable(p0: SurfaceTexture, p1: Int, p2: Int) {
                with(mediaPlayer) {
                    setDataSource(GlobalData.videoUrl)
                    setSurface(Surface(p0))
                    prepare()
                    start()
                    Log.i(tag, "setOnPreparedListener")
                    setOnPreparedListener {
                        it.start()
                    }
                }
            }
            override fun onSurfaceTextureSizeChanged(p0: SurfaceTexture, p1: Int, p2: Int) {
            }
            override fun onSurfaceTextureDestroyed(p0: SurfaceTexture): Boolean {
                mediaPlayer.stop()
                mediaPlayer.release()
                return true
            }
            override fun onSurfaceTextureUpdated(p0: SurfaceTexture) {
            }
        }

SurfaceTexture

SurfaceTexture是Surface和OpenGL ES紋理的組合,用于提供輸出到OpenGL ES紋理的Surface,和SurfaceView不同的是,它對(duì)圖像流的處理并不直接顯示,而是轉(zhuǎn)為GL外部紋理,因此可用于圖像流數(shù)據(jù)的二次處理,如Camera濾鏡,桌面特效等,但是這樣會(huì)有若干幀的延遲。同時(shí),由于它本身管理BufferQueue,因此內(nèi)存消耗也會(huì)稍微大一些。比如Camera的預(yù)覽數(shù)據(jù),變成紋理后就可以通過(guò)SurfaceTexture交給TextureView作為View層級(jí)中的一個(gè)硬件加速層來(lái)顯示。

SurfaceView和TextureView的區(qū)別

  • SurfaceView是直接輸出的,擁有自己獨(dú)立Surface,它的渲染可以放在單獨(dú)線程,其缺點(diǎn)是不能做變形和動(dòng)畫(huà)。
  • TextureView是一個(gè)可以把內(nèi)容流作為外部紋理輸出的,本身必須是一個(gè)硬件加速層,顯示畫(huà)面更新時(shí)有1~3幀的延遲。
  • TextureView本身也包含了SurfaceTexture,它與SurfaceView+SurfaceTexture組合相比,也可以把內(nèi)容流上的圖像轉(zhuǎn)成紋理輸出,區(qū)別在于TextureView是在View層級(jí)中繪制的,而SurfaceView+SurfaceTexture在單獨(dú)的Surface上做繪制的。
SurfaceViewTextureView
占用內(nèi)存低占用內(nèi)存高
耗電低耗電高
繪制及時(shí)1-3幀延時(shí)
不支持動(dòng)畫(huà)截圖支持動(dòng)畫(huà)截圖

個(gè)人覺(jué)得,對(duì)于需要不斷更新畫(huà)布的游戲來(lái)說(shuō),SurfaceView是最好的選擇,對(duì)于視頻播放器或相機(jī)應(yīng)用的開(kāi)發(fā),則TextureView更加適合。

到此這篇關(guān)于Android SurfaceView與TextureView使用方法詳細(xì)講解的文章就介紹到這了,更多相關(guān)Android SurfaceView與TextureView內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android開(kāi)發(fā)中日期工具類(lèi)DateUtil完整實(shí)例

    Android開(kāi)發(fā)中日期工具類(lèi)DateUtil完整實(shí)例

    這篇文章主要介紹了Android開(kāi)發(fā)中日期工具類(lèi)DateUtil,結(jié)合完整實(shí)例形式分析了Android針對(duì)日期與時(shí)間的計(jì)算、轉(zhuǎn)換、格式化、獲取等相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11
  • Android ActionBarActivity設(shè)置全屏無(wú)標(biāo)題的方法總結(jié)

    Android ActionBarActivity設(shè)置全屏無(wú)標(biāo)題的方法總結(jié)

    這篇文章主要介紹了Android ActionBarActivity設(shè)置全屏無(wú)標(biāo)題的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 詳解flutter之網(wǎng)絡(luò)請(qǐng)求dio,請(qǐng)求,攔截器簡(jiǎn)單示例

    詳解flutter之網(wǎng)絡(luò)請(qǐng)求dio,請(qǐng)求,攔截器簡(jiǎn)單示例

    這篇文章主要介紹了詳解flutter之網(wǎng)絡(luò)請(qǐng)求dio,請(qǐng)求,攔截器簡(jiǎn)單示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • android實(shí)現(xiàn)獲取有線和無(wú)線Ip地址的方法

    android實(shí)現(xiàn)獲取有線和無(wú)線Ip地址的方法

    這篇文章主要介紹了android實(shí)現(xiàn)獲取有線和無(wú)線Ip地址的方法,較為詳細(xì)的分析了Android獲取IP地址的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • Android中SoundPool的使用步驟實(shí)例

    Android中SoundPool的使用步驟實(shí)例

    今天小編就為大家分享一篇關(guān)于Android中SoundPool的使用步驟實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • Android自定義attr的各種坑

    Android自定義attr的各種坑

    開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)自定義View來(lái)實(shí)現(xiàn)各種各樣炫酷的效果,在實(shí)現(xiàn)這些效果的同時(shí),我們往往會(huì)定義很多attr屬性這篇文章主要介紹了Android自定義attr的各種坑,需要的朋友可以參考下
    2016-04-04
  • Android實(shí)現(xiàn)折線圖小工具

    Android實(shí)現(xiàn)折線圖小工具

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)折線圖小工具,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果

    Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果

    對(duì)view比較熟悉的同學(xué)們應(yīng)該發(fā)現(xiàn)了,其實(shí)我們的懸浮窗就是一個(gè)view,我們只需要把view添加到windowManager上就可以了。那么,下面通過(guò)本文給大家分享Android仿騰訊視頻實(shí)現(xiàn)懸浮窗效果,一起看看吧
    2021-06-06
  • Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法

    Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法

    這篇文章主要介紹了Android自定義照相機(jī)Camera出現(xiàn)黑屏的解決方法,分析了黑屏出現(xiàn)的原因及參考解決方法,需要的朋友可以參考下
    2016-08-08
  • Android仿頭條、微信大圖預(yù)覽視圖的方法詳解

    Android仿頭條、微信大圖預(yù)覽視圖的方法詳解

    大圖預(yù)覽應(yīng)該對(duì)大家來(lái)說(shuō)都不陌生,下面這篇文章主要給大家介紹了關(guān)于Android仿頭條、微信大圖預(yù)覽視圖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03

最新評(píng)論

攀枝花市| 宁夏| 鸡西市| 民丰县| 朔州市| 离岛区| 许昌县| 石河子市| 西华县| 开原市| 江川县| 丰镇市| 来宾市| 安义县| 嘉善县| 东辽县| 龙海市| 亳州市| 康平县| 内丘县| 福海县| 伊宁县| 两当县| 宜春市| 阿坝县| 望城县| 仁布县| 自治县| 恩施市| 黑水县| 全椒县| 浮山县| 酒泉市| 固始县| 剑阁县| 樟树市| 阜宁县| 普兰县| 邹平县| 开封市| 临武县|