Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)課件 第8單元 高級(jí)編程_第1頁(yè)
Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)課件 第8單元 高級(jí)編程_第2頁(yè)
Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)課件 第8單元 高級(jí)編程_第3頁(yè)
Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)課件 第8單元 高級(jí)編程_第4頁(yè)
Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)課件 第8單元 高級(jí)編程_第5頁(yè)
已閱讀5頁(yè),還剩83頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第8單元高級(jí)編程Android移動(dòng)開(kāi)發(fā)基礎(chǔ)教程(慕課版)(第2版)8.1網(wǎng)絡(luò)編程【知識(shí)描述】網(wǎng)絡(luò)編程是指多臺(tái)設(shè)備之間通過(guò)網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交換。網(wǎng)絡(luò)通信基于“請(qǐng)求響應(yīng)模型”,即一臺(tái)設(shè)備發(fā)送通信請(qǐng)求,另一臺(tái)設(shè)備進(jìn)行反饋。發(fā)送請(qǐng)求端稱為客戶端,響應(yīng)請(qǐng)求端稱為服務(wù)端。例如常見(jiàn)的QQ程序,用戶打開(kāi)QQ客戶端程序之后,輸入用戶名和密碼,再單擊“登錄”,即向騰訊服務(wù)端發(fā)送登錄請(qǐng)求,服務(wù)端把請(qǐng)求結(jié)果反饋到客戶端。Android是基于Java進(jìn)行開(kāi)發(fā)的,所以JDK中關(guān)于網(wǎng)絡(luò)編程的API在Android中均可使用。8.1.1TCP、UDP基礎(chǔ)兩臺(tái)設(shè)備之間進(jìn)行通信,一定要通過(guò)通信協(xié)議,即客戶端以一定的格式將數(shù)據(jù)發(fā)送出去,服務(wù)端接收到數(shù)據(jù)之后,可以根據(jù)同樣的協(xié)議將數(shù)據(jù)的內(nèi)容解析出來(lái)。01TCP(TransmissionControlProtocol,傳輸控制協(xié)議)提供的是面向連接、可靠的字節(jié)流服務(wù),通信雙方必須先建立一個(gè)TCP連接,然后才能傳輸數(shù)據(jù)。而且TCP還提供了超時(shí)重發(fā)、數(shù)據(jù)校驗(yàn)、擁塞控制等功能,保證了數(shù)據(jù)的可靠傳輸。02UDP(UserDatagramProtocol,用戶數(shù)據(jù)報(bào)協(xié)議)應(yīng)用于需要安全可靠地傳輸數(shù)據(jù)的場(chǎng)景,但是開(kāi)銷(xiāo)比較大。UDP應(yīng)用于對(duì)數(shù)據(jù)可靠性要求不是太高的場(chǎng)景,其優(yōu)點(diǎn)是開(kāi)銷(xiāo)小,另外UDP沒(méi)有數(shù)據(jù)校驗(yàn)、擁塞控制等功能,故而傳輸速度比較快。8.1.1TCP、UDP基礎(chǔ)對(duì)于上層應(yīng)用來(lái)說(shuō),無(wú)論是TCP還是UDP,通信都包括客戶端和服務(wù)端,處理流程也具有一般性,具體如表8.1所示??蛻舳颂幚砹鞒蹋海?)根據(jù)服務(wù)端的IP地址和端口號(hào)建立網(wǎng)絡(luò)連接;(2)建立連接之后,進(jìn)行數(shù)據(jù)交換,向服務(wù)端發(fā)送請(qǐng)求和接收服務(wù)端反饋的數(shù)據(jù);(3)關(guān)閉連接服務(wù)端處理流程:(1)服務(wù)端啟動(dòng)之后,監(jiān)聽(tīng)一個(gè)固定的端口,被動(dòng)地等待客戶端連接;(2)在客戶端連接到服務(wù)端之后,服務(wù)端可以獲取客戶端的IP地址等信息,可以進(jìn)行數(shù)據(jù)交換;(3)接收客戶端發(fā)送的數(shù)據(jù),然后把處理的結(jié)果反饋給客戶端;(4)關(guān)閉連接表8.1客戶端和服務(wù)端的處理流程8.1.2Socket通信任務(wù)8.1實(shí)現(xiàn)網(wǎng)絡(luò)通信【任務(wù)代碼】客戶端代碼:privatevoidstartClient(){Stringdata="HelloWorld";InputStreamis=null;OutputStreamos=null;Socketc=null;try{c=newSocket("01",7005);//建立連接

os=c.getOutputStream();//獲得輸出流

os.write(data.getBytes());//發(fā)送數(shù)據(jù)

is=c.getInputStream();//獲得輸入流

byte[]b=newbyte[1024];is.read(b);//接收反饋數(shù)據(jù)

}catch(Exceptione){e.printStackTrace();}finally{try{if(null!=c){c.close();}if(null!=is){is.close();is=null;}if(null!=os){os.close();os=null;}}catch(IOExceptione){e.printStackTrace();}}}8.1.2Socket通信客戶端首先定義了一個(gè)Socket對(duì)象向服務(wù)端請(qǐng)求建立連接,構(gòu)造函數(shù)以服務(wù)端的IP地址和端口號(hào)作為參數(shù)。建立連接之后,調(diào)用getOutputStream()獲取輸出流,向服務(wù)端發(fā)送數(shù)據(jù)?!救蝿?wù)代碼】服務(wù)端代碼:privatevoidstartServer(){ServerSocketsc=null;try{sc=newServerSocket(7005);//監(jiān)聽(tīng)端口號(hào)

while(true){Socketc=sc.accept();//被動(dòng)地等待連接

newServerThread(c);//開(kāi)啟一個(gè)線程處理客戶端請(qǐng)求

}}catch(Exceptione){e.printStackTrace();}finally{try{if(null!=sc){sc.close();sc=null;}}catch(Exceptione1){e1.printStackTrace();}}}8.1.2Socket通信服務(wù)端首先定義了一個(gè)ServerSocket對(duì)象,構(gòu)造函數(shù)以將要監(jiān)聽(tīng)的端口號(hào)作為參數(shù),然后調(diào)用accept()方法被動(dòng)地等待連接。ServerThread代碼包含的是基本的I/O流操作ServerThread代碼:publicclassServerThreadextendsThread{privateSocketc=null;publicServerThread(Socketc){this.c=c;start();//啟動(dòng)線程

}@Overridepublicvoidrun(){InputStreamis=null;try{if(null!=c){is=c.getInputStream();//獲取輸入流

}8.1.2Socket通信if(null!=is){byte[]b=newbyte[1024];intsize=is.read(b);//讀取接收到的消息

Log.i("Socket","themsgis:"+newString(b,0,size));}}catch(Exceptione){e.printStackTrace();}finally{try{if(null!=is){is.close();is=null;}if(null!=c){c.close();c=null;}}catch(Exceptione1){e1.printStackTrace();}}}}8.1.3下載網(wǎng)絡(luò)資源任務(wù)8.2下載網(wǎng)絡(luò)圖片【任務(wù)代碼】privateBitmapgetBitmap(Stringpath){Bitmapbm=null;try{URLurl=newURL(path);//創(chuàng)建一個(gè)URL對(duì)象,其參數(shù)為網(wǎng)絡(luò)圖片的超鏈接地址

//調(diào)用openConnection()方法開(kāi)啟一個(gè)超鏈接

HttpURLConnectioncon=(HttpURLConnection)url.openConnection();//設(shè)置相關(guān)參數(shù)

con.setDoInput(true);con.setConnectTimeout(5000);con.setReadTimeout(2000);con.connect();InputStreamis=con.getInputStream();//獲取輸入流

bm=BitmapFactory.decodeStream(is);//將輸入流解析為Bitmap對(duì)象

is.close();}catch(Exceptione){e.printStackTrace();}returnbm;}8.2圖形圖像和動(dòng)畫(huà)【知識(shí)描述】對(duì)于一個(gè)應(yīng)用來(lái)說(shuō),圖片是一種很豐富的表達(dá)形式。Android中為圖片的處理提供了大量的API,不僅包括圖片的顯示、繪制,還包括一些簡(jiǎn)單的動(dòng)畫(huà)效果。8.2.1Bitmap和BitmapFactoryAndroid中提供了Bitmap類(lèi)用于圖片處理,一個(gè)Bitmap對(duì)象代表一張位圖,其中存儲(chǔ)了圖片的尺寸、顏色、像素點(diǎn)等信息,Bitmap類(lèi)提供了大量的方法,其常見(jiàn)的方法如表8.2所示。staticBitmapcreateBitmap(Bitmapsource,intx,inty,intwidth,intheight)靜態(tài)方法,以source圖片的(x,y)位置為起點(diǎn),截取寬為width、高為height的圖片staticBitmapcreateBitmap(intwidth,intheight,Bitmap.Configconfig)創(chuàng)建一個(gè)Bitmap對(duì)象staticBitmapcreateScaledBitmap(Bitmapsrc,intdstWidth,intdstHeight,booleanfilter)將src圖像縮放后創(chuàng)建一個(gè)新的Bitmap對(duì)象finalintgetHeight()獲取Bitmap的高finalintgetWidth()獲取Bitmap的寬voidrecycle()回收Bitmap對(duì)象和對(duì)應(yīng)像素點(diǎn)所占內(nèi)存finalbooleanisRecycled()判斷Bitmap對(duì)象是否被回收intgetPixel(intx,inty)獲取圖片指定位置處像素點(diǎn)的值voidsetPixel(intx,inty,intcolor)設(shè)置圖片指定位置處像素點(diǎn)的值表8.2Bitmap常見(jiàn)的方法8.2.1Bitmap和BitmapFactoryBitmapFactory主要用于加載Bitmap對(duì)象,可以從資源文件解析,也可以根據(jù)圖片的路徑進(jìn)行加載,還可以根據(jù)輸入流對(duì)Bitmap對(duì)象進(jìn)行解析,相應(yīng)的方法如表8.3所示。表8.3BitmapFactory的方法staticBitmapdecodeByteArray(byte[]data,intoffset,intlength,BitmapFactory.Optionsopts)將字節(jié)數(shù)組解析成Bitmap對(duì)象staticBitmapdecodeFile(StringpathName,BitmapFactory.Optionsopts)根據(jù)圖片的路徑加載Bitmap對(duì)象staticBitmapdecodeResource(Resourcesres,intid,BitmapFactory.Optionsopts)將資源文件解析成Bitmap對(duì)象staticBitmapdecodeStream(InputStreamis)將輸入流解析成Bitmap對(duì)象8.2.2Android繪圖基礎(chǔ)除了顯示已有的圖片之外,Android還支持一些簡(jiǎn)單的二維繪圖,其實(shí)Android的一些基本組件,如TextView、Button等,也都是系統(tǒng)繪制出來(lái)的。繪制的操作在View類(lèi)的onDraw(Canvascanvas)方法中,每個(gè)組件需要實(shí)現(xiàn)onDraw(Canvascanvas)方法進(jìn)行自定義的繪制。Android的繪圖應(yīng)該定義一個(gè)類(lèi),它繼承自View組件,并重新定義onDraw(Canvascanvas)方法。其中,參數(shù)Canvas可以理解為畫(huà)布,繪制操作均在Canvas上執(zhí)行。8.2.2Android繪圖基礎(chǔ)表8.4Canvas類(lèi)支持的一些方法drawBitmap(Bitmapbitmap,floatleft,floattop,Paintpaint)從Bitmap對(duì)象的左上角開(kāi)始繪制drawCircle(floatcx,floatcy,floatradius,Paintpaint)繪制一個(gè)圓drawLine(floatstartX,floatstartY,floatstopX,floatstopY,Paintpaint)繪制一條線drawPoint(floatx,floaty,Paintpaint)繪制一個(gè)點(diǎn)drawRect(floatleft,floattop,floatright,floatbottom,Paintpaint)繪制一個(gè)矩形drawText(Stringtext,floatx,floaty,Paintpaint)繪制一個(gè)字符串8.2.2Android繪圖基礎(chǔ)表8.5與Paint類(lèi)相關(guān)的部分方法從表8.4中可以看出,每一個(gè)方法中都包含一個(gè)Paint類(lèi)的參數(shù)。Paint類(lèi)代表畫(huà)筆,Paint類(lèi)的參數(shù)指定了畫(huà)筆的顏色和粗細(xì)等,與它相關(guān)的部分方法如表8.5所示。setAlpha(inta)設(shè)置畫(huà)筆的透明度setAntiAlias(booleanaa)設(shè)置是否抗鋸齒setColor(intcolor)設(shè)置畫(huà)筆的顏色setShader(Shadershader)設(shè)置畫(huà)筆的填充效果setShadowLayer(floatradius,floatdx,floatdy,intcolor)設(shè)置畫(huà)筆的陰影效果setStrokeWidth(floatwidth)設(shè)置畫(huà)筆的粗細(xì)setTextSize(floattextSize)設(shè)置繪制文字的大小8.2.2Android繪圖基礎(chǔ)任務(wù)8.3使用線性布局【任務(wù)代碼】自定義View代碼:publicclassCanvasViewextendsView{//自定義一個(gè)類(lèi)繼承View組件

publicCanvasView(Contextcontext,AttributeSetattrs){super(context,attrs);}@OverrideprotectedvoidonDraw(Canvascanvas){//重寫(xiě)onDraw()方法

super.onDraw(canvas);Paintpaint=newPaint();//定義一個(gè)畫(huà)筆對(duì)象

paint.setAntiAlias(true);//設(shè)置抗鋸齒

paint.setStyle(Paint.Style.STROKE);//設(shè)置畫(huà)筆的風(fēng)格

paint.setStrokeWidth(5);//設(shè)置畫(huà)筆的粗細(xì)

paint.setColor(Color.GREEN);//設(shè)置畫(huà)筆的顏色

paint.setTextSize(24);//設(shè)置繪制的文字大小

canvas.drawCircle(60,60,50,paint);//繪制圓

canvas.drawLine(10,100,100,100,paint);//繪制線

canvas.drawRect(10,150,100,300,paint);//繪制矩形

canvas.drawText("HelloWorld",10,300,paint);//繪制字符串

}}圖8.1圖形的繪制8.2.3補(bǔ)間動(dòng)畫(huà)表8.5與Paint類(lèi)相關(guān)的部分方法在Android應(yīng)用中,經(jīng)常會(huì)出現(xiàn)一些動(dòng)畫(huà)效果,例如控件的滑入與滑出、圖片的漸隱等。常見(jiàn)的實(shí)現(xiàn)方式有補(bǔ)間動(dòng)畫(huà)和屬性動(dòng)畫(huà)。補(bǔ)間動(dòng)畫(huà)是指開(kāi)發(fā)者指定控件的初始狀態(tài)和結(jié)束狀態(tài),系統(tǒng)自動(dòng)補(bǔ)齊顯示控件的中間狀態(tài)。Android補(bǔ)間動(dòng)畫(huà)支持的效果比較簡(jiǎn)單,包括平移、縮放、旋轉(zhuǎn)、透明度變換,對(duì)應(yīng)的類(lèi)如表8.6所示。類(lèi)說(shuō)明TranslateAnimation用于實(shí)現(xiàn)平移動(dòng)畫(huà)的類(lèi),需要指定控件起始和結(jié)束時(shí)的位置ScaleAnimation用于實(shí)現(xiàn)縮放動(dòng)畫(huà)的類(lèi),需要指定動(dòng)畫(huà)的縮放中心、起始的縮放比和結(jié)束時(shí)的縮放比RotateAnimation用于實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫(huà)的類(lèi),需要指定旋轉(zhuǎn)中心的坐標(biāo)、起始的旋轉(zhuǎn)角度和結(jié)束時(shí)的旋轉(zhuǎn)角度AlphaAnimation用于實(shí)現(xiàn)透明度變換的類(lèi),需要指定起始的透明度和結(jié)束時(shí)的透明度8.2.3補(bǔ)間動(dòng)畫(huà)任務(wù)8.4使用補(bǔ)間動(dòng)畫(huà)本任務(wù)在Activity中定義了一張圖片和4個(gè)按鈕,這4個(gè)按鈕分別用于觸發(fā)4種動(dòng)畫(huà),運(yùn)行結(jié)果如圖8.2所示。圖8.2補(bǔ)間動(dòng)畫(huà)8.2.3補(bǔ)間動(dòng)畫(huà)【任務(wù)代碼】MainActivity代碼:publicclassMainActivityextendsActivityimplementsOnClickListener{protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initWidget();}privatevoidinitWidget(){ButtonbtnTrans=(Button)findViewById(R.id.btn_translate);//獲取對(duì)應(yīng)的4個(gè)按鈕

ButtonbtnScale=(Button)findViewById(R.id.btn_scale);ButtonbtnRotate=(Button)findViewById(R.id.btn_rotate);ButtonbtnAlpha=(Button)findViewById(R.id.btn_alpha);btnTrans.setOnClickListener(this);//設(shè)置監(jiān)聽(tīng)事件

btnScale.setOnClickListener(this);btnRotate.setOnClickListener(this);btnAlpha.setOnClickListener(this);}8.2.3補(bǔ)間動(dòng)畫(huà)publicvoidonClick(Viewv){ImageViewimgView=(ImageView)findViewById(R.id.img_pic);switch(v.getId()){caseR.id.btn_translate:{//平移動(dòng)畫(huà)

TranslateAnimationtanim=newTranslateAnimation(0,100,0,0);tanim.setDuration(500);//設(shè)置動(dòng)畫(huà)執(zhí)行的時(shí)間

tanim.setFillAfter(true);//設(shè)置動(dòng)畫(huà)執(zhí)行后保持變化后的狀態(tài)

imgView.startAnimation(tanim);break;}caseR.id.btn_scale:{//縮放動(dòng)畫(huà)

ScaleAnimationsanim=newScaleAnimation(0.0f,1.2f,0.0f,1.2f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);sanim.setDuration(500);sanim.setFillAfter(true);imgView.startAnimation(sanim);break;}8.2.3補(bǔ)間動(dòng)畫(huà)caseR.id.btn_rotate:{//旋轉(zhuǎn)動(dòng)畫(huà)

RotateAnimationranim=newRotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);ranim.setDuration(500);ranim.setFillAfter(true);imgView.startAnimation(ranim);break;}caseR.id.btn_alpha:{//透明度變換

AlphaAnimationanim=newAlphaAnimation(1.0f,0.0f);anim.setDuration(500);anim.setFillAfter(true);imgView.startAnimation(anim);break;}default:break;}}}8.2.4屬性動(dòng)畫(huà)屬性動(dòng)畫(huà)是在API11之后加入的功能,它幾乎可以作用在任何對(duì)象上,而且不同于補(bǔ)間動(dòng)畫(huà)只能支持4種變換,屬性動(dòng)畫(huà)可以在一定時(shí)間內(nèi)將對(duì)象的屬性從一個(gè)初始值改變到另一個(gè)值,因此,只要是對(duì)象存在的屬性,無(wú)論是可見(jiàn)的還是不可見(jiàn)的,都可以實(shí)現(xiàn)動(dòng)畫(huà)效果。屬性動(dòng)畫(huà)可以通過(guò)ObjectAnimator實(shí)現(xiàn)。8.2.4屬性動(dòng)畫(huà)任務(wù)8.5使用屬性動(dòng)畫(huà)【任務(wù)代碼】MainActivity代碼:publicclassMainActivityextendsActivityimplementsOnClickListener{protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initWidget();}privatevoidinitWidget(){ButtonbtnTrans=(Button)findViewById(R.id.btn_translation);//獲取按鈕

ButtonbtnAlpha=(Button)findViewById(R.id.btn_alpha);btnTrans.setOnClickListener(this);//設(shè)置監(jiān)聽(tīng)事件

btnAlpha.setOnClickListener(this);}@SuppressLint("NewApi")publicvoidonClick(Viewv){ImageViewimgView=(ImageView)findViewById(R.id.img_pic);switch(v.getId()){8.2.4屬性動(dòng)畫(huà)caseR.id.btn_translation:{//平移

ObjectAnimatoranim=ObjectAnimator.ofFloat(imgView,"translationX",0,100);anim.setDuration(500);anim.start();break;}caseR.id.btn_alpha:{//透明度變換

ObjectAnimatoranim=ObjectAnimator.ofFloat(imgView,"alpha",1.0f,0.0f);anim.setDuration(500);anim.start();break;}default:break;}}}8.3多媒體應(yīng)用開(kāi)發(fā)【知識(shí)描述】在Android應(yīng)用中,經(jīng)常需要播放媒體資源,如播放音樂(lè)、播放視頻等。Android提供了MediaPlayer類(lèi),使用該類(lèi)可以很簡(jiǎn)單地實(shí)現(xiàn)播放本地或者網(wǎng)絡(luò)上的音/視頻的功能。8.3.1MediaPlayer類(lèi)介紹MediaPlayer類(lèi)提供了大量的方法用以控制音/視頻的播放、暫停、定位等,常見(jiàn)的方法如表8.7所示。表8.7MediaPlayer類(lèi)常見(jiàn)的方法方法說(shuō)明intgetCurrentPosition()獲取當(dāng)前播放的位置intgetDuration()獲取音/視頻文件的總長(zhǎng)intgetVideoHeight()獲取視頻的高度intgetVideoWidth()獲取視頻的寬度booleanisPlaying()判斷當(dāng)前是否正在播放voidpause()暫停播放voidprepare()MediaPlayer開(kāi)始準(zhǔn)備(同步方法)voidprepareAsync()MediaPlayer開(kāi)始準(zhǔn)備(異步方法)voidrelease()釋放MediaPlayer占用的資源voidreset()重置MediaPlayer的狀態(tài)8.3.1MediaPlayer類(lèi)介紹方法說(shuō)明voidseekTo(intmsec)定位到音/視頻的指定位置,可用于實(shí)現(xiàn)快進(jìn)、快退voidsetDataSource(Stringpath)設(shè)置視頻源setDataSource(Contextcontext,Uriuri)設(shè)置視頻源setDisplay(SurfaceHoldersh)用于顯示播放畫(huà)面setOnCompletionListener(MediaPlayer.OnCompletionListenerlistener)設(shè)置視頻播放完成時(shí)的監(jiān)聽(tīng)事件setOnErrorListener(MediaPlayer.OnErrorListenerlistener)設(shè)置播放出現(xiàn)錯(cuò)誤時(shí)的監(jiān)聽(tīng)事件setOnPreparedListener(MediaPlayer.OnPreparedListenerlistener)設(shè)置MediaPlayer準(zhǔn)備工作完成時(shí)的監(jiān)聽(tīng)事件setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListenerlistener)設(shè)置定位完成時(shí)的監(jiān)聽(tīng)事件voidstart()開(kāi)始播放voidstop()停止播放8.3.2使用MediaPlayer和SurfaceView播放視頻播放的視頻必須顯示在View上,而且由于視頻的畫(huà)面一直在改變,所以View需要一直重繪。對(duì)于這種需要不斷更新View內(nèi)容的場(chǎng)景,Android提供了SurfaceView類(lèi)。SurfaceView關(guān)聯(lián)了一個(gè)SurfaceHolder對(duì)象,該對(duì)象專門(mén)用于繪制SurfaceView的內(nèi)容。SurfaceHolder可以使用3個(gè)回調(diào)方法反饋SurfaceView的狀態(tài)表8.2Bitmap常見(jiàn)的方法方法說(shuō)明surfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight)SurfaceView的大小發(fā)生改變surfaceCreated(SurfaceHolderholder)SurfaceView第一次被創(chuàng)建完成surfaceDestroyed(SurfaceHolderholder)SurfaceView被銷(xiāo)毀8.3.2使用MediaPlayer和SurfaceView播放視頻任務(wù)8.6使用MediaPlayer和SurfaceView播放視頻【任務(wù)代碼】MainActivity代碼:publicclassMainActivityextendsActivityimplementsOnClickListener{privateSurfaceViewmSurface;privateButtonmBtnPlay;privateButtonmBtnPause;privateMediaPlayermPlayer=null;protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initWidget();initPlayer();}privatevoidinitWidget(){mSurface=(SurfaceView)findViewById(R.id.surfaceView);//獲取SurfaceView控件8.3.2使用MediaPlayer和SurfaceView播放視頻mBtnPlay=(Button)findViewById(R.id.btn_play);mBtnPause=(Button)findViewById(R.id.btn_pause);mBtnPlay.setOnClickListener(this);mBtnPause.setOnClickListener(this);}publicvoidonClick(Viewv){switch(v.getId()){caseR.id.btn_play:{//單擊“播放”按鈕

if(null!=mPlayer&&!mPlayer.isPlaying())//判斷當(dāng)前是否已經(jīng)處于播放狀態(tài)

{mPlayer.start();//播放

}break;}caseR.id.btn_pause:{//單擊“暫停”按鈕

if(null!=mPlayer&&mPlayer.isPlaying())//判斷當(dāng)前是否已經(jīng)處于播放狀態(tài)

{mPlayer.pause();//暫停

}break;}8.3.2使用MediaPlayer和SurfaceView播放視頻default:break;}}privatevoidinitPlayer(){mPlayer=newMediaPlayer();//定義一個(gè)MediaPlayer對(duì)象

//獲取SurfaceView關(guān)聯(lián)的SurfaceHolderSurfaceHolderholder=mSurface.getHolder();holder.addCallback(surfaceCallBack);//為SurfaceHolder添加回調(diào)函數(shù)

try{mPlayer.setOnPreparedListener(onPreparedListener);//設(shè)置監(jiān)聽(tīng)事件

mPlayer.setDataSource("mnt/sdcard/demo.avi");//設(shè)置視頻源

mPlayer.prepareAsync();//調(diào)用異步準(zhǔn)備方法

}catch(Exceptione){e.printStackTrace();}}8.3.2使用MediaPlayer和SurfaceView播放視頻privateOnPreparedListeneronPreparedListener=newOnPreparedListener(){publicvoidonPrepared(MediaPlayermp){//MediaPlayer準(zhǔn)備完畢,開(kāi)始播放

mp.start();}};privateSurfaceHolder.CallbacksurfaceCallBack=newSurfaceHolder.Callback(){publicvoidsurfaceDestroyed(SurfaceHolderholder){//TODO自動(dòng)生成方法存根

}publicvoidsurfaceCreated(SurfaceHolderholder){//SurfaceView創(chuàng)建成功

mPlayer.setDisplay(holder);//為MediaPlayer設(shè)置SurfaceHolder}8.3.2使用MediaPlayer和SurfaceView播放視頻@OverridepublicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){//TODO自動(dòng)生成方法存根

}};protectedvoidonDestroy(){//頁(yè)面銷(xiāo)毀時(shí)釋放MediaPlayer占用的資源

if(null!=mPlayer){mPlayer.stop();mPlayer.release();mPlayer=null;}super.onDestroy();}}8.3.2使用MediaPlayer和SurfaceView播放視頻act_main.xml布局文件:<LinearLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center"android:orientation="vertical">//定義一個(gè)SurfaceView布局

<SurfaceViewandroid:id="@+id/surfaceView"android:layout_width="match_parent"android:layout_height="400dp"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:orientation="horizontal"><Button8.3.2使用MediaPlayer和SurfaceView播放視頻android:id="@+id/btn_play"android:layout_width="100dp"android:layout_height="100dp"android:gravity="center"android:textSize="18sp"android:text="play"/><Buttonandroid:id="@+id/btn_pause"android:layout_width="100dp"android:layout_height="100dp"android:gravity="center"android:textSize="18sp"android:text="pause"/></LinearLayout></LinearLayout>8.4線程開(kāi)發(fā)【知識(shí)描述】線程在程序開(kāi)發(fā)中是一個(gè)很重要的概念。在Android中,線程分為主線程和子線程。主線程又叫作UI線程,主要處理和界面有關(guān)的事情,用于界面的繪制和交互。用戶隨時(shí)都有可能操作界面,而且對(duì)其響應(yīng)速度要求較高,因此,主線程中不能做太耗時(shí)的操作,否則會(huì)讓用戶視覺(jué)上感覺(jué)到卡頓,甚至有可能會(huì)因?yàn)閳?zhí)行阻塞產(chǎn)生ANR而導(dǎo)致應(yīng)用異常退出。8.4.1AsyncTask介紹AsyncTask是一個(gè)執(zhí)行異步操作的類(lèi),它在主線程中創(chuàng)建和觸發(fā),但是在子線程中執(zhí)行后臺(tái)任務(wù),然后將執(zhí)行的進(jìn)度和最終結(jié)果傳遞給主線程并在主線程中更新UI。例如有一種很常見(jiàn)的操作:應(yīng)用中如果要在ImageView控件中顯示一張網(wǎng)絡(luò)圖片,首先需要從網(wǎng)絡(luò)上下載圖片,然后將其顯示到控件上。表8.7MediaPlayer類(lèi)常見(jiàn)的方法方法說(shuō)明doInBackground()在后臺(tái)執(zhí)行任務(wù)onProgressUpdate()回調(diào)當(dāng)前執(zhí)行的進(jìn)度onPostExecute()任務(wù)執(zhí)行完成8.4.1AsyncTask介紹它們的具體使用方法如下所示:publicvoidonClick(Viewv){newDownloadImageTask().execute("/image.png");//執(zhí)行異步任務(wù)}privateclassDownloadImageTaskextendsAsyncTask<String,Void,Bitmap>{protectedBitmapdoInBackground(String...arg0){//在后臺(tái)執(zhí)行任務(wù)

Stringurl=args[0];//獲取參數(shù)

Bitmapbitmap=downloadImgByUrl(url);//執(zhí)行下載任務(wù)

returnbitmap;//返回執(zhí)行結(jié)果

}protectedvoidonPostExecute(Bitmapresult){//下載完成之后回調(diào)該方法

mImageView.setImageBitmap(result);//對(duì)返回結(jié)果進(jìn)行處理

}protectedvoidonProgressUpdate(Void...values){//回調(diào)下載進(jìn)度

super.onProgressUpdate(values);}}8.4.2ThreadPoolExecutor介紹當(dāng)一個(gè)應(yīng)用中需要?jiǎng)?chuàng)建多個(gè)線程時(shí),可以將該應(yīng)用放入線程池中進(jìn)行管理,Java中使用Executor實(shí)現(xiàn)線程池的管理和線程的調(diào)度。Executor是一個(gè)接口,它的實(shí)現(xiàn)類(lèi)為T(mén)hreadPoolExecutor。創(chuàng)建ThreadPoolExecutor對(duì)象時(shí),可以向構(gòu)造函數(shù)傳入一系列的參數(shù)來(lái)配置線程池。8.4.2ThreadPoolExecutor介紹corePoolSize線程池的核心線程數(shù)Part01maximumPoolSize線程池可以容納的最多的線程數(shù)Part02keepAliveTime非核心線程在空閑時(shí)可以存活的時(shí)間Part03unit參數(shù)keepAliveTime的單位Part04workQueue線程隊(duì)列Part05threadFactory線程工廠,用于在線程池中創(chuàng)建線程Part068.4.2ThreadPoolExecutor介紹當(dāng)調(diào)用ThreadPoolExecutor的execute()方法要求執(zhí)行一個(gè)任務(wù)時(shí),線程池會(huì)判斷當(dāng)前的線程數(shù)是否超過(guò)核心線程數(shù),如果沒(méi)有超過(guò),則啟動(dòng)一個(gè)核心線程來(lái)執(zhí)行任務(wù)如果線程池有線程處于空閑狀態(tài),則在指定keepAliveTime后回收線程,當(dāng)線程數(shù)等于核心線程數(shù)時(shí),停止回收線程如果線程的總數(shù)已經(jīng)達(dá)到了線程池可以容納的最多的線程數(shù),則拒絕接收任務(wù)如果當(dāng)前的線程數(shù)超過(guò)了核心線程數(shù),則將任務(wù)放到線程隊(duì)列中排隊(duì)等候15423如果線程隊(duì)列已滿,則啟動(dòng)一個(gè)非核心線程來(lái)執(zhí)行任務(wù)8.4.2ThreadPoolExecutor介紹線程池的創(chuàng)建代碼:publicclassMain{publicstaticvoidmain(String[]args){ThreadPoolExecutorexecutor=newThreadPoolExecutor(1,3,1,TimeUnit.MINUTES,newArrayBlockingQueue(4));//創(chuàng)建一個(gè)線程池對(duì)象

executor.execute(newTask());//執(zhí)行一個(gè)任務(wù)

}}需要執(zhí)行的任務(wù):publicclassTaskextendsThread{//繼承Thread類(lèi)

publicvoidrun(){//重寫(xiě)父類(lèi)的run()方法

super.run();System.out.println("thisisataskinthread");//執(zhí)行自己的操作

}}8.5Fragment【知識(shí)描述】為了更加動(dòng)態(tài)和靈活地支持UI設(shè)計(jì),Android在API11之后引入了Fragment,它可以將UI碎片化,也可以被復(fù)用。Fragment必須顯示在Activity中,可以被動(dòng)態(tài)地添加、移除、替換,但是每個(gè)Fragment都具有自己的生命周期方法,并且可以單獨(dú)處理用戶的輸入事件。8.5Fragment常見(jiàn)的微信界面(見(jiàn)圖8.3)就可以使用Fragment來(lái)實(shí)現(xiàn)。單擊界面下方的“微信”,界面中間內(nèi)容區(qū)域就會(huì)對(duì)應(yīng)顯示聊天記錄;單擊“通訊錄”,界面中間內(nèi)容區(qū)域就會(huì)顯示聯(lián)系人列表。這些功能用Activity實(shí)現(xiàn)比較麻煩,但是用Fragment實(shí)現(xiàn)就比較簡(jiǎn)單。將界面的整體定義為一個(gè)Activity,界面中間內(nèi)容區(qū)域設(shè)計(jì)為一個(gè)Fragment,實(shí)現(xiàn)根據(jù)用戶單擊的Item動(dòng)態(tài)地更換顯示區(qū)域的Fragment。圖8.3微信界面8.5.1Fragment的創(chuàng)建和Activity類(lèi)似,創(chuàng)建自定義的Fragment需要繼承基類(lèi)Fragment,并實(shí)現(xiàn)基類(lèi)的若干個(gè)方法。其中比較常見(jiàn)的是onCreate()、onCreateView()、onPause()方法。onPause()方法在用戶離開(kāi)Fragment時(shí)會(huì)回調(diào)onCreateView()在繪制Fragment視圖的時(shí)候會(huì)回調(diào),開(kāi)發(fā)者需要在該方法中加載Fragment需要顯示的布局文件onCreate()方法在創(chuàng)建Fragment時(shí)會(huì)回調(diào)8.5.1Fragment的創(chuàng)建FragmentTransaction類(lèi)支持的常見(jiàn)方法如表8.10所示。方法說(shuō)明add(intcontainerViewId,Fragmentfragment)在Activity指定的位置添加一個(gè)Fragmentcommit()提交事務(wù)hide(Fragmentfragment)隱藏當(dāng)前的Fragmentremove(Fragmentfragment)從Activity中移除一個(gè)Fragmentreplace(intcontainerViewId,Fragmentfragment)在指定位置處替換一個(gè)Fragmentshow(Fragmentfragment)顯示之前隱藏的Fragment表8.10FragmentTransaction類(lèi)支持的常見(jiàn)方法8.5.1Fragment的創(chuàng)建任務(wù)8.7單擊底部按鈕,中間內(nèi)容區(qū)域動(dòng)態(tài)改變本任務(wù)運(yùn)行結(jié)果如圖8.4所示,單擊底部按鈕,中間內(nèi)容區(qū)域動(dòng)態(tài)改變。圖8.4Fragment實(shí)現(xiàn)效果8.5.1Fragment的創(chuàng)建【任務(wù)代碼】FragmentFriend代碼:publicclassFragmentFriendextendsFragment{//定義一個(gè)類(lèi)繼承FragmentpublicvoidonCreate(BundlesavedInstanceState){//重寫(xiě)onCreate()方法

super.onCreate(savedInstanceState);}//重寫(xiě)onCreateView()方法,在其中加載布局文件

publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){Viewview=inflater.inflate(R.layout.view_fragment,container,false);//加載布局文件

TextViewtxtView=(TextView)view.findViewById(R.id.txt_title);txtView.setText("ThisisFriendUI");//設(shè)置布局中的文字

returnview;}}8.5.1Fragment的創(chuàng)建FragmentContact代碼:publicclassFragmentContactextendsFragment{//和FragmentFriend代碼類(lèi)似

publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);}publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,BundlesavedInstanceState){Viewview=inflater.inflate(R.layout.view_fragment,container,false);TextViewtxtView=(TextView)view.findViewById(R.id.txt_title);txtView.setText("ThisisContactUI");returnview;}}8.5.1Fragment的創(chuàng)建view_fragment.xml代碼:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/txt_title"android:layout_width="300dp"android:layout_height="100dp"android:textSize="36sp"android:text="ThisisFriendUI"/></LinearLayout>8.5.1Fragment的創(chuàng)建MainActivity代碼:publicclassMainActivityextendsActivityimplementsOnClickListener{privateFragmentmFriendFrag=null;//定義Fragment變量

privateFragmentmContactFrag=null;privateFragmentmFindFrag=null;privateFragmentmSettingFrag=null;

protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initWidget();}privatevoidinitWidget(){mFriendFrag=newFragmentFriend();//創(chuàng)建一個(gè)FragmentFriend對(duì)象

FragmentTransactionft=getFragmentManager().beginTransaction();//開(kāi)啟一個(gè)事務(wù)8.5.1Fragment的創(chuàng)建ft.replace(R.id.lly_content,mFriendFrag);//初始顯示聊天記錄界面

mit();//事務(wù)提交

ButtonbtnFriend=(Button)findViewById(R.id.btn_friend);//獲取按鈕

ButtonbtnContact=(Button)findViewById(R.id.btn_contact);ButtonbtnFind=(Button)findViewById(R.id.btn_find);ButtonbtnSetting=(Button)findViewById(R.id.btn_setting);btnFriend.setOnClickListener(this);//為按鈕添加單擊事件監(jiān)聽(tīng)器

btnContact.setOnClickListener(this);btnFind.setOnClickListener(this);btnSetting.setOnClickListener(this);}@OverridepublicvoidonClick(Viewview){FragmentTransactionft=getFragmentManager().beginTransaction();//開(kāi)啟一個(gè)事務(wù)

switch(view.getId()){caseR.id.btn_friend://聊天記錄

{if(null==mFriendFrag)8.5.1Fragment的創(chuàng)建{mFriendFrag=newFragmentFriend();//創(chuàng)建對(duì)應(yīng)的Fragment對(duì)象

}ft.replace(R.id.lly_content,mFriendFrag);//調(diào)用replace()方法替換當(dāng)前Fragmentbreak;}caseR.id.btn_contact://通訊錄

{if(null==mContactFrag){mContactFrag=newFragmentContact();}ft.replace(R.id.lly_content,mContactFrag);break;}caseR.id.btn_find://發(fā)現(xiàn)

{if(null==mFindFrag){mFindFrag=newFragmentFind();}8.5.1Fragment的創(chuàng)建ft.replace(R.id.lly_content,mFindFrag);break;}caseR.id.btn_setting://設(shè)置

{if(null==mSettingFrag){mSettingFrag=newFragmentSetting();}ft.replace(R.id.lly_content,mSettingFrag);break;}default:break;}mit();}}8.5.1Fragment的創(chuàng)建activity_main.xml代碼:<LinearLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><FrameLayout//定義一個(gè)組件,該組件用于占用該位置,并顯示Fragmentandroid:id="@+id/lly_content"android:layout_width="match_parent"android:layout_height="400dp"/><LinearLayoutandroid:layout_width="match_par

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論