多媒體開發,包含圖片,音頻,視頻等領域。近期參與的新項目,正好涉及在Android客戶端上進行多媒體開發,藉此一步一步嘗試學習和整理資料。java
第一步就從最簡單的圖片展現來入門:嘗試用三種方式來展現圖片——ImageView,自定義View,SurfaceView。canvas
這個最簡單,稍有Android基礎的開發者都會,能夠經過在layout文件中定義ImageView的時候指定src爲對應圖片,亦可在java代碼中經過ImageView的setImageDrawable或者setImageBitmap來設置圖片,用於展現。ide
代碼過於簡單,這裏不細述。post
自定義View,就是要自定義View的三個方法,onMeasure, onLayout, onDraw,前兩個方法用來定義View的size和位置,後一個onDraw纔是繪製的具體實現,因此自定義View繪製圖片,就要在onDraw中來繪製。學習
public class MyView extends View {
private Bitmap mBitmap;
private Paint mPaint;
public MyView(Context context) {
super(context);
//讀取圖片爲bitmap實例
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
//Paint能夠定義畫筆的顏色粗細等,在畫線條,形狀等的時候生效,而在畫圖片的時候顏色粗細等屬性無效,因此只須要new一個實例就好
mPaint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas意爲「畫布」,便是View的可繪製區域
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
}
}
複製代碼
onDraw會View初始化後進行調用,將圖片繪製到View上。this
除此以外,View的postInvalidate方法也會致使重繪,調用onDraw。spa
SurfaceView在Android系統算是比較複雜的存在,它與View有所不一樣。最大的區別就是 View只能在主線程渲染,SurfaceView則能夠自定義渲染線程。
咱們知道,若是在主線程作過於耗時的操做,超過16ms,就會引發掉幀甚至ANR。而SurfaceView能夠不在主線程渲染,因此用SurfaceView來作渲染視頻之類的耗時操做,就能夠不影響到主線程的渲染。線程
public class SurfaceMainActivity extends Activity implements Callback {
private SurfaceView mSurfaceView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mSurfaceView = new SurfaceView(this);
setContentView(mSurfaceView);
//SurfaceView有本身的生命週期,不能直接使用,要經過callback監聽到Surface在create以後,destroy以前,才能在其上繪製
mSurfaceView.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//Surface已經建立,能夠繪製咱們的圖片了
drawBitmap(holder);
}
private void drawBitmap(SurfaceHolder holder) {
Bitmap bitmap = null;
try {
//從assets中讀test.png建立bitmap實例
bitmap = BitmapFactory.decodeStream(getAssets().open("test.png"));
} catch (IOException e) {
e.printStackTrace();
}
//獲取畫布
Canvas canvas = holder.lockCanvas();
//畫一個大紅色背景(清空畫布)
canvas.drawColor(Color.RED);
if (bitmap != null) {
//將圖片繪製到畫布上
canvas.drawBitmap(bitmap,0,0,new Paint());
}
//完成繪製
holder.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Surface銷燬,在這以後,不能再獲取畫布繪製了
}
}
複製代碼
以上是在SurfaceView上繪製一張圖片的例子,若是是在surfaceCreated以後,另起一個獨立的線程,將視頻解析成一幀一幀繪製到Canvas上,那也就作成了一個視頻播放器。code