編輯:關於Android編程
摘要 調試Media播放時,不時用到SurfaceView與SurfaceHolder對象,寫case測試及實際運行效果, 基本上搞清楚這兩個對象的用法及區別 1、SurfaceView public class SurfaceView extends View SurfaceView是視圖(View)的繼承類, 這個視圖裡內嵌了一個專門用於繪制
調試Media播放時,不時用到SurfaceView與SurfaceHolder對象,寫case測試及實際運行效果,
基本上搞清楚這兩個對象的用法及區別
1、SurfaceView
public class SurfaceView extends View
SurfaceView是視圖(View)的繼承類,這個視圖裡內嵌了一個專門用於繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
surface是縱深排序(Z-ordered)的,這表明它總在自己所在窗口的後面。surfaceview提供了一個可見區域,只有在這個可見區域內 的surface部分內容才可見,可見區域外的部分不可見。surface的排版顯示受到視圖層級關系的影響,它的兄弟視圖結點會在頂端顯示。這意味者 surface的內容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控件)。注意,如果surface上面 有透明控件,那麼它的每次變化都會引起框架重新計算它和頂層控件的透明效果,這會影響性能。你可以通過SurfaceHolder接口訪問這個Surface.用getHolder()方法可以得到這個接口。
surfaceview變得可見時,surface被創建;surfaceview隱藏前,surface被銷毀。這樣能節省資源。
如果你要查看 surface被創建和銷毀的時機,可以重載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在於提供了兩個線程:UI線程和渲染線程。
這裡應注意:
1> 所有SurfaceView和SurfaceHolder.Callback的方法都應該在UI線程裡調用,一般來說就是應用程序主線程。顯示一個surface的抽象接口,使你可以控制surface的大小和格式, 以及在surface上編輯像素,和監視surace的改變。
這個接口通常通過SurfaceView類實現。
下面我們舉個例子說明一下這幾個對象的用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98package
com.test.surfaceview;
import
android.app.Activity;
import
android.content.Context;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.graphics.Rect;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.SurfaceHolder;
import
android.view.SurfaceView;
public
class TestsurfaceviewActivity extends Activity {
private
final static String TAG =
"TestsurfaceviewActivity"
;
/**
Called when the activity is first created. */
@Override
public
void onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
//setContentView(R.layout.main);
setContentView(
new
MySurfaceView(
this
));
//
這裡以MySurfaceView作為顯示View
}
class
MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private
SurfaceHolder holder;
private
MyThread mThread ;
public
MySurfaceView(Context context){
super
(context);
holder
=
this
.getHolder();
//獲取holder對象
holder.addCallback(
this
);
//
添加surface回調函數
mThread
=
new
MyThread(holder);
//創建一個繪圖線程
}
@Override
public
void surfaceChanged(SurfaceHolder holder, int format, int width,
int
height) {
//
TODO Auto-generated method stub
Log.i(TAG,
"surfaceChanged
is called"
);
}
@Override
public
void surfaceCreated(SurfaceHolder holder) {
//
TODO Auto-generated method stub
Log.i(TAG,
"surfaceCreated
is called"
);
mThread.isRun
=
true
;
mThread.start();
}
@Override
public
void surfaceDestroyed(SurfaceHolder holder) {
//
TODO Auto-generated method stub
Log.i(TAG,
"surfaceDestroyed
is called"
);
mThread.isRun
=
false
;
mThread.stop();
}
}
class
MyThread extends Thread{
private
SurfaceHolder holder ;
public
boolean isRun =
false
;
public
MyThread(SurfaceHolder holder){
this
.holder
= holder;
isRun
=
true
;
Log.i(TAG,
"MyThread
set surface holder"
);
}
@Override
public
void run(){
Canvas
canvas =
null
;
int
count = 0;
while
(isRun) {
try
{
synchronized
(holder) {
canvas
= holder.lockCanvas();
//
鎖定畫布,一般在鎖定後就可以通過其返回的畫布對象Canvas,在其上面畫圖等操作了。
canvas.drawColor(Color.BLACK);
//
設置畫布背景顏色
Paint
p =
new
Paint();
//
創建畫筆
p.setColor(Color.RED);
Rect
r =
new
Rect(500, 200, 300, 250);
canvas.drawRect(r,
p);
canvas.drawText(
"這是第"
+ (count++) +
"秒"
,
300, 310, p);
Thread.sleep(1000);
//
睡眠時間為1秒
}
}
catch
(Exception e) {
e.printStackTrace();
}
finally {
if
(canvas !=
null
)
{
holder.unlockCanvasAndPost(canvas);
//
結束鎖定畫圖,並提交改變。
}
}
}
}
}
}
在Media 播放過程中會需要用到兩個SurfaceView,一個用於繪制顯示界面,另外一個用於播放視頻的顯示
首先在main.xml中定義兩個SurfaceView:
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
然後使用的片斷代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45private
SurfaceView mUIView;
private
SurfaceView mPlayView;
private
MyMediaplayerManager mPlayManager;
mUIView
= (SurfaceView)findViewById(R.id.mainSurface);
mSurfaceHolder.addCallback(
new
SurfaceHolder.Callback() {
@Override
public
void surfaceDestroyed(SurfaceHolder holder) {
//
TODO Auto-generated method stub
}
@Override
public
void surfaceCreated(final SurfaceHolder holder) {
//
TODO Auto-generated method stub
}
@Override
public
void surfaceChanged(SurfaceHolder holder, int format,
int
width, int height) {
//
TODO Auto-generated method stub
}
});
mPlayView
= (SurfaceView)findViewById(R.id.playSurface);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(
new
SurfaceHolder.Callback() {
@Override
public
void surfaceDestroyed(SurfaceHolder holder) {
//
TODO Auto-generated method stub
}
@Override
public
void surfaceCreated(SurfaceHolder holder) {
mPlayManager.setDisplay(holder);
//
這裡設置video視頻的顯示Holder
}
@Override
public
void surfaceChanged(SurfaceHolder holder, int format, int width,
int
height) {
//
TODO Auto-generated method stub
}
});
//
設定SurfaceView的顯示zorder序
mUIView.setZOrderMediaOverlay(
true
);
mPlayView.setZOrderMediaOverlay(
false
);
view 可看作就是一個圖層,以上使用兩個圖層,一個是圖形層,另一個是視頻層,需要播放視頻時只需要將圖形層透明掉即可。
一、為什麼Android要進行分辨率與屏幕適配最大的原因是碎片化,因為Android的開源措施和各個廠商的自己細微修改,結果就變成了這個樣需要適配的屏幕尺寸就有這麼多:這
??Activity作為四大組件之一,出現的頻率相當高,基本上我們在android的各個地方都能看見它的蹤影,因此深入了解Activity,對於開發高質量應用程序是很有幫
什麼是RecyclerView?RecyclerView其實就是一個在5.0推出的控件,可以用它來代替ListView和GridView,從這一點也能看出來它的特性和Li
Android4.4 fence機制分析 在任何一個系統中,無可避免的都會跟各種buffers打交道,最經典的模式就是消費-生產者模式,一個獨立的buffer在它們之間