欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android開(kāi)發(fā)中的Surface庫(kù)及用其制作播放器UI的例子

 更新時(shí)間:2016年04月12日 15:01:25   作者:chenzheng_java  
這篇文章主要介紹了Android開(kāi)發(fā)中的Surface庫(kù)及用其制作播放器界面的例子,利用SurfaceView和SurfaceHolder可以高效地繪制和控制圖形界面,需要的朋友可以參考下

1、Surface
1.1、 就如在C語(yǔ)言編程一樣,通過(guò)一個(gè)文件的句柄,就可以操作文件,獲取文件的內(nèi)容。 同樣的,通過(guò)Surface就可以獲取raw buffer其中的內(nèi)容。原生緩沖區(qū)(raw buffer)存儲(chǔ)著當(dāng)前窗口的像素?cái)?shù)據(jù)。

1.2、事實(shí)上,當(dāng)?shù)玫揭粋€(gè)Surface對(duì)象時(shí),同時(shí)會(huì)得到一個(gè)Canvas(畫(huà)布)對(duì)象。這一點(diǎn)可以通過(guò)查看\frameworks\base\core\java\android\view\Surface.java文件可知道Surface類(lèi)定義了一個(gè)Canvas成員變量

private int mSurfaceControl; 
private int mSaveCount; 
private Canvas mCanvas; 
private int mNativeSurface; 
private int mSurfaceGenerationId; 
private String mName; 

1.3、 理解Canvas對(duì)象,可以把它當(dāng)做畫(huà)布,Canvas的方法大多數(shù)是設(shè)置畫(huà)布的大小、形狀、畫(huà)布背景顏色等等,要想在畫(huà)布上面畫(huà)畫(huà),一般要與Paint對(duì)象結(jié)合使用,顧名思義,Paint就是畫(huà)筆的風(fēng)格,顏料的色彩之類(lèi)的。

// 創(chuàng)建畫(huà)筆  
Paint paint = new Paint();  
paint.setColor(Color.RED);// 設(shè)置紅色  
 
canvas.drawCircle(60, 20, 10, paint);// 畫(huà)一個(gè)圓  

1.4、Surface本身的作用類(lèi)似一個(gè)句柄,得到了這個(gè)句柄就可以得到其中的Canvas、原生緩沖器以及其它方面的內(nèi)容。

1.5、Surface實(shí)現(xiàn)了Parcelable接口,(implements Parcelable),也就是說(shuō)Surface對(duì)象可以把顯示內(nèi)容的數(shù)據(jù)寫(xiě)入到 Parcel 中,并且能夠從Parcel讀回?cái)?shù)據(jù)。

2、SurfaceView
SurfaceView提供了一個(gè)專(zhuān)門(mén)用于繪制的surface,這個(gè)surface內(nèi)嵌于。你可以控制這個(gè)Surface的格式和尺寸。Surfaceview控制這個(gè)Surface在屏幕的正確繪制位置。
surface是Z-ordered的(也就是說(shuō)在xyz坐標(biāo)系中,按照Z(yǔ)坐標(biāo)排序的,Z值大的表面覆蓋在Z值小的表面的上方),這表明它總在自己所在窗口的后面。surfaceview在顯示窗口處為Surface提供了一個(gè)可見(jiàn)區(qū)域,通過(guò)這個(gè)區(qū)域,才能看到Surface里面的內(nèi)容??梢苑胖靡恍└采w圖層(overlays)在Surface上面,如Button、Textview之類(lèi)的。但是,需要注意的是,如果Surface上面有全透明的控件,那么隨著Surface的每一次變化,這些全透明的控件就會(huì)重新渲染,這樣的話(huà),就影響性能與顯示的效果。
你可以通過(guò)SurfaceHolder這個(gè)接口去訪(fǎng)問(wèn)Surface,而執(zhí)行g(shù)etHolder()方法可以得到SurfaceHolder接口。
當(dāng)SurfaceView的窗口可見(jiàn)時(shí),Surface就會(huì)被創(chuàng)建,當(dāng)SurfaceView窗口隱藏時(shí),Surface就會(huì)被銷(xiāo)毀。當(dāng)然了,你也可以通過(guò)復(fù)寫(xiě)surfaceCreated(SurfaceHolder) 和 surfaceDestroyed(SurfaceHolder)  這兩個(gè)方法來(lái)驗(yàn)證一下Surface何時(shí)被創(chuàng)建與何時(shí)被銷(xiāo)毀。
SurfaceView提供了一個(gè)運(yùn)行在渲染線(xiàn)程的surface,若你要更新屏幕,你需要了解以下線(xiàn)程知識(shí)。
所有SurfaceView 和 SurfaceHolder.Callback的方法都應(yīng)該在主線(xiàn)程(UI線(xiàn)程)里面調(diào)用,應(yīng)該要確保渲染進(jìn)程所訪(fǎng)問(wèn)變量的同步性。
你必須確保只有當(dāng)Surface有效的時(shí)候,(也就是當(dāng)Surface的生命周期在SurfaceHolder.Callback.surfaceCreated() 和SurfaceHolder.Callback.surfaceDestroyed()之間)才能讓渲染進(jìn)程訪(fǎng)問(wèn)。

2.1、SurfaceView與Surface的聯(lián)系
簡(jiǎn)單來(lái)說(shuō),SurfaceView與Surface的聯(lián)系就是,Surface是管理顯示內(nèi)容的數(shù)據(jù)(implementsParcelable),包括存儲(chǔ)于數(shù)據(jù)的交換。而SurfaceView就是把這些數(shù)據(jù)顯示出來(lái)到屏幕上面。
兩者聯(lián)系如圖所示:

2016412145144865.png (1024×654)

3、SurfaceHolder
SurfaceHolder是控制surface的一個(gè)抽象接口,你可以通過(guò)SurfaceHolder來(lái)控制surface的尺寸和格式,或者修改surface的像素,監(jiān)視surface的變化等等,SurfaceHolder是SurfaceView的典型接口。
與直接控制SurfaceView來(lái)修改surface不同,使用SurfaceHolder來(lái)修改surface時(shí),需要注意lockCanvas() 和Callback.surfaceCreated().這兩個(gè)方法。
SurfaceHolder控制surface的流程所使用的幾個(gè)方法。

3.1、abstract void    addCallback(SurfaceHolder.Callback callback)
給SurfaceHolder一個(gè)回調(diào)對(duì)象。

3.2、abstract Canvas    lockCanvas(Rect dirty)
鎖定畫(huà)布中的某一個(gè)區(qū)域,返回的畫(huà)布對(duì)象Canvas(當(dāng)更新的內(nèi)容只有一個(gè)區(qū)域時(shí),同時(shí)要追求高效,可以只更
新一部分的區(qū)域,而不必更新全部畫(huà)布區(qū)域)

3.3、abstract Canvas    lockCanvas()
鎖定畫(huà)布,返回的畫(huà)布對(duì)象Canvas

3.4、abstract void    removeCallback(SurfaceHolder.Callback callback)
移除回調(diào)對(duì)象

3.5、abstract void    unlockCanvasAndPost(Canvas canvas)
結(jié)束鎖定畫(huà)圖,并提交改變。

4、SurfaceHolder.Callback
SurfaceHolder.Callback是監(jiān)聽(tīng)surface改變的一個(gè)接口

4.1、public abstract voidsurfaceChanged(SurfaceHolder holder, int format, int width, int height)
surface發(fā)生改變時(shí)被調(diào)用

4.2、public abstract voidsurfaceCreated(SurfaceHolder holder)
在surface創(chuàng)建時(shí)被調(diào)用,一般在這個(gè)方法里面開(kāi)啟渲染屏幕的線(xiàn)程。

4.3、public abstract voidsurfaceDestroyed(SurfaceHolder holder)
銷(xiāo)毀時(shí)被調(diào)用,一般在這個(gè)方法里將渲染的線(xiàn)程停止。

附上上述所說(shuō)幾種的聯(lián)系方法

SurfaceHolder = SurfaceView.getHolder(); 
 
Surface = SurfaceHolder.getSurface(); 
 
Canvas =SurfaceHolder.LockCanvas(Rect dirty) 
 
Canvas  =Surface.lockCanvas(Rect dirty) 

5、DEMO:通過(guò)SurfaceView以及SurfaceHolder進(jìn)行視頻播放
使用AudioView進(jìn)行視頻播放的時(shí)候,是不是很不爽,千篇一律的模式,惡心吧。這里,我們可以通過(guò)一些方式對(duì)MediaPlayer進(jìn)行包裝。而所用到的正是SurfaceView以及SurfaceHolder。
最終效果圖:

2016412145237293.gif (356×299)

我們提供了四個(gè)按鈕,可以進(jìn)行播放控制。

布局文件media.xml代碼:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" android:layout_height="fill_parent" 
  android:orientation="vertical"> 
  <SurfaceView android:id="@+id/surfaceView1" 
    android:layout_width="320px" android:layout_height="160px"></SurfaceView> 
  <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" 
  android:orientation="horizontal" 
  > 
  <ImageButton android:id="@+id/button_play" android:src="@drawable/play" android:onClick="buttonClick" 
    android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageButton> 
  <ImageButton android:id="@+id/button_pause" android:src="@drawable/pause" android:onClick="buttonClick" 
    android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageButton> 
  <ImageButton android:id="@+id/button_stop" android:src="@drawable/stop" android:onClick="buttonClick" 
    android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageButton> 
  <ImageButton android:id="@+id/button_reset" android:src="@drawable/reset" android:onClick="buttonClick" 
  android:layout_width="wrap_content" android:layout_height="wrap_content"></ImageButton> 
  </LinearLayout>   
</LinearLayout> 

activity代碼:

package cn.com.chenzheng_java.media; 
 
import android.app.Activity; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
/** 
 * @description 通過(guò)SurfaceView/SurfaceHolder實(shí)現(xiàn)自己的播放器 
 * @author chenzheng_java 
 * @since 2011/03/23 
 * @description 這里進(jìn)行一下補(bǔ)充說(shuō)明,我們可以通過(guò)mediaplayer添加OnPreparedListener 
 * 以及OnCompletionListener等事件對(duì)準(zhǔn)備好播放以及播放完成后的操作進(jìn)行控制。 
 * 使用SurfaceView以及SurfaceHolder進(jìn)行視頻播放時(shí),結(jié)構(gòu)是這樣的: 
 * 1、首先,我們從布局文件中獲取一個(gè)surfaceView 
 * 2、通過(guò)surfaceView.getHolder()方法獲取與該容器想對(duì)應(yīng)的surfaceHolder 
 * 3、對(duì)srufaceHolder進(jìn)行一些默認(rèn)的設(shè)置,如addCallback()和setType() 
 * 4、通過(guò)mediaPlayer.setDisplay()方法將視頻播放與播放容器鏈接起來(lái) 
 */ 
public class MyMediaPlayerActivity extends Activity { 
 
  MediaPlayer mediaPlayer ; // 播放器的內(nèi)部實(shí)現(xiàn)是通過(guò)MediaPlayer 
  SurfaceView surfaceView ;// 裝在視頻的容器 
  SurfaceHolder surfaceHolder;// 控制surfaceView的屬性(尺寸、格式等)對(duì)象 
  boolean isPause ; // 是否已經(jīng)暫停了 
   
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.media); 
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView1); 
    /** 
     * 獲取與當(dāng)前surfaceView相關(guān)聯(lián)的那個(gè)的surefaceHolder 
     */ 
    surfaceHolder = surfaceView.getHolder(); 
    /** 
     * 注冊(cè)當(dāng)surfaceView創(chuàng)建、改變和銷(xiāo)毀時(shí)應(yīng)該執(zhí)行的方法 
     */ 
    surfaceHolder.addCallback(new SurfaceHolder.Callback() { 
       
      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
        Log.i("通知", "surfaceHolder被銷(xiāo)毀了"); 
        if(mediaPlayer!=null) 
        mediaPlayer.release(); 
      } 
       
      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 
        Log.i("通知", "surfaceHolder被create了"); 
      } 
       
      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, 
          int height) { 
        Log.i("通知", "surfaceHolder被改變了"); 
      } 
    }); 
     
    /** 
     * 這里必須設(shè)置為SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS哦,意思 
     * 是創(chuàng)建一個(gè)push的'surface',主要的特點(diǎn)就是不進(jìn)行緩沖 
     */ 
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
  } 
   
  /*** 
   * @param targetButton 被用戶(hù)點(diǎn)擊的按鈕 
   */ 
  public void buttonClick(View targetButton){ 
    int buttonId = targetButton.getId(); 
    switch (buttonId) { 
    case R.id.button_play: 
      play(); 
      break; 
    case R.id.button_pause: 
      pause(); 
      break; 
    case R.id.button_reset: 
      reset(); 
      break; 
    case R.id.button_stop: 
      stop(); 
      break; 
    default: 
      break; 
    } 
     
  } 
   
  /** 
   * 播放 
   */ 
  private void play(){ 
     
    mediaPlayer = new MediaPlayer(); 
    // 設(shè)置多媒體流類(lèi)型 
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     
    // 設(shè)置用于展示mediaPlayer的容器 
    mediaPlayer.setDisplay(surfaceHolder); 
    try { 
      mediaPlayer.setDataSource("/data/jinsha.3gp"); 
      mediaPlayer.prepare(); 
      mediaPlayer.start(); 
      isPause = false; 
    } catch (Exception e) { 
      Log.i("通知", "播放過(guò)程中出現(xiàn)了錯(cuò)誤哦"); 
    } 
  } 
   
  /** 
   * 暫停 
   */ 
  private void pause(){ 
    Log.i("通知", "點(diǎn)擊了暫停按鈕"); 
    if(isPause==false){ 
      mediaPlayer.pause(); 
      isPause=true; 
    }else{ 
      mediaPlayer.start(); 
      isPause=false; 
    } 
     
     
  } 
   
  /** 
   * 重置 
   */ 
  private void reset(){ 
    Log.i("通知", "點(diǎn)擊了reset按鈕"); 
    // 跳轉(zhuǎn)到視頻的最開(kāi)始 
    mediaPlayer.seekTo(0); 
    mediaPlayer.start(); 
  } 
   
  /** 
   * 停止 
   */ 
  private void stop(){ 
    Log.i("通知", "點(diǎn)擊了stop按鈕"); 
    mediaPlayer.stop(); 
    mediaPlayer.release(); 
     
  } 
   
} 

相關(guān)文章

  • Android自定義View展示W(wǎng)ifi信號(hào)強(qiáng)弱指示方法示例

    Android自定義View展示W(wǎng)ifi信號(hào)強(qiáng)弱指示方法示例

    這篇文章主要給大家介紹了關(guān)于Android自定義View展示W(wǎng)ifi信號(hào)強(qiáng)弱指示的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),文末給出了完整的實(shí)例供大家參考學(xué)習(xí),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • Android WebView實(shí)現(xiàn)全屏播放視頻

    Android WebView實(shí)現(xiàn)全屏播放視頻

    WebView是Android系統(tǒng)中的原生控件,其主要功能與前端頁(yè)面進(jìn)行響應(yīng)交互,快捷省時(shí)地實(shí)現(xiàn)如期的功能,相當(dāng)于增強(qiáng)版的內(nèi)置瀏覽器。這篇文章主要介紹的是利用WebView實(shí)現(xiàn)全屏播放視頻的功能,感興趣的小伙伴可以了解一下
    2021-12-12
  • android I/0流操作文件(文件存儲(chǔ))

    android I/0流操作文件(文件存儲(chǔ))

    Java提供一套完整的I/О流體系,通過(guò)I/О流可以非常方便地訪(fǎng)問(wèn)磁盤(pán)中的文件,同樣Android 也支持I/O流方式來(lái)訪(fǎng)問(wèn)手機(jī)等移動(dòng)設(shè)備中的存儲(chǔ)文件。希望可以為大家提供幫助
    2021-06-06
  • Android 自定義View結(jié)合自定義TabLayout實(shí)現(xiàn)頂部標(biāo)簽滑動(dòng)效果

    Android 自定義View結(jié)合自定義TabLayout實(shí)現(xiàn)頂部標(biāo)簽滑動(dòng)效果

    小編最近在做app的項(xiàng)目,需要用到tablayout實(shí)現(xiàn)頂部的滑動(dòng)效果,文中代碼用到了自定義item,代碼也很簡(jiǎn)單,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-07-07
  • Android 自定義view和屬性動(dòng)畫(huà)實(shí)現(xiàn)充電進(jìn)度條效果

    Android 自定義view和屬性動(dòng)畫(huà)實(shí)現(xiàn)充電進(jìn)度條效果

    近期項(xiàng)目中需要使用到一種類(lèi)似手機(jī)電池充電進(jìn)度的動(dòng)畫(huà)效果,以前沒(méi)學(xué)屬性動(dòng)畫(huà)的時(shí)候,是用圖片+定時(shí)器的方式來(lái)完成的,下面給大家分享android自定義view和屬性動(dòng)畫(huà)實(shí)現(xiàn)充電進(jìn)度條
    2016-12-12
  • 從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解

    從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解

    這篇文章主要為大家介紹了從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Android仿微信加號(hào)菜單模式

    Android仿微信加號(hào)菜單模式

    這篇文章主要為大家詳細(xì)介紹了Android仿微信加號(hào)菜單模式的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android注冊(cè)登錄實(shí)時(shí)自動(dòng)獲取短信驗(yàn)證碼

    Android注冊(cè)登錄實(shí)時(shí)自動(dòng)獲取短信驗(yàn)證碼

    注冊(cè)登錄或修改密碼功能常常需要輸入短信驗(yàn)證碼,如何自動(dòng)獲取短信驗(yàn)證碼,這篇文章就為大家介紹了Androidcv注冊(cè)登錄自動(dòng)獲取短信驗(yàn)證碼的實(shí)現(xiàn)代碼,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Android實(shí)現(xiàn)圖片雙指縮放

    Android實(shí)現(xiàn)圖片雙指縮放

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片雙指縮放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Android編程之退出整個(gè)應(yīng)用程序的方法

    Android編程之退出整個(gè)應(yīng)用程序的方法

    這篇文章主要介紹了Android編程之退出整個(gè)應(yīng)用程序的方法,實(shí)例分析了Android直接關(guān)閉所有的Acitivity并退出應(yīng)用程序的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-12-12

最新評(píng)論