android的介面
『壹』 Android原生編解碼介面 MediaCodec 之——完全解析
MediaCodec 是Android 4.1(api 16)版本引入的編解碼介面, Developer 官網 上描述的已經很清楚了。可以配合 中文翻譯 一起看。理解更深刻。
MediaCodec的工作流程:
從上圖可以看出 MediaCodec 架構上採用了2個緩沖區隊列,非同步處理數據,並且使用了一組輸入輸出緩存。
你請求或接收到一個空的輸入緩存(input buffer),向其中填充滿數據並將它傳遞給編解碼器處理。編解碼器處理完這些數據並將處理結果輸出至一個空的輸出緩存(output buffer)中。最終,你請求或接收到一個填充了結果數據的輸出緩存(output buffer),使用完其中的數據,並將其釋放給編解碼器再次使用。
具體工作如下:
MediaCodec的基本調用流程是:
1.初始化MediaCodec,方法有兩種,分別是通過名稱和類型來創建,對應的方法為:
2.配置編碼器,設置各種編碼器參數(MediaFormat),這個類包含了比特率、幀率、關鍵幀間隔時間等。然後再調用 mMediaCodec .configure,對於 API 19 以上的系統,我們可以選擇 Surface 輸入:mMediaCodec .createInputSurface,
3.打開編碼器,獲取輸入輸出緩沖區
獲取輸入輸出緩沖區在api19 上是以上方式獲取,api21以後 可以使用直接獲取ByteBuffer
4.輸入數據,有2種方式,一種是普通輸入,一種是Surface 輸入
普通輸入又可區分為兩種情況,一種是配合MediaExtractor ,一種是取原數據;
返回一個填充了有效數據的input buffer的索引,如果沒有可用的buffer則返回-1,參數為超時時間(TIMES_OUT),單位是微秒,當timeoutUs==0時,該方法立即返回;當timeoutUs<0時,無限期地等待一個可用的input buffer,當timeoutUs>0時,
等待時間為傳入的微秒值。
上面輸入緩存的index,通過getInputBuffers()得到的是輸入緩存數組,通過index和輸入緩存數組可以得到當前請求的輸入緩存,在使用之前要clear一下,避免之前的緩存數據影響當前數據,接著就是把數據添加到輸入緩存中,並調用queueInputBuffer(...)把緩存數據入隊;
5.輸出數據
通常編碼傳輸時每個關鍵幀頭部都需要帶上編碼配置數據(PPS,SPS),但 MediaCodec 會在首次輸出時專門輸出編碼配置數據,後面的關鍵幀里是不攜帶這些數據的,所以需要我們手動做一個拼接;
6.使用完MediaCodec後釋放資源
要告知編碼器我們要結束編碼,Surface 輸入的話調用 mMediaCodec .signalEndOfInputStream,普通輸入則可以為在 queueInputBuffer 時指定 MediaCodec.BUFFER_FLAG_END_OF_STREAM 這個 flag;告知編碼器後我們就可以等到編碼器輸出的 buffer 帶著 MediaCodec.BUFFER_FLAG_END_OF_STREAM 這個 flag 了,等到之後我們調用 mMediaCodec .release 銷毀編碼器
流控就是流量控制。 為什麼要控制,就是為了在一定的限制條件下,收益最大化!
涉及到了 TCP 和視頻編碼:
對 TCP 來說就是控制單位時間內發送數據包的數據量,對編碼來說就是控制單位時間內輸出數據的數據量。
TCP 的限制條件是網路帶寬,流控就是在避免造成或者加劇網路擁塞的前提下,盡可能利用網路帶寬。帶寬夠、網路好,我們就加快速度發送數據包,出現了延遲增大、丟包之後,就放慢發包的速度(因為繼續高速發包,可能會加劇網路擁塞,反而發得更慢)。
視頻編碼的限制條件最初是解碼器的能力,碼率太高就會無法解碼,後來隨著 codec 的發展,解碼能力不再是瓶頸,限制條件變成了傳輸帶寬/文件大小,我們希望在控制數據量的前提下,畫面質量盡可能高。
一般編碼器都可以設置一個目標碼率,但編碼器的實際輸出碼率不會完全符合設置,因為在編碼過程中實際可以控制的並不是最終輸出的碼率,而是編碼過程中的一個量化參數(Quantization Parameter,QP),它和碼率並沒有固定的關系,而是取決於圖像內容。 這一點不在這里展開,感興趣的朋友可以閱讀視頻壓縮編碼和音頻壓縮編碼的基本原理。
無論是要發送的 TCP 數據包,還是要編碼的圖像,都可能出現「尖峰」,也就是短時間內出現較大的數據量。TCP 面對尖峰,可以選擇不為所動(尤其是網路已經擁塞的時候),這沒有太大的問題,但如果視頻編碼也對尖峰不為所動,那圖像質量就會大打折扣了。如果有幾幀數據量特別大,但仍要把碼率控制在原來的水平,那勢必要損失更多的信息,因此圖像失真就會更嚴重。 這種情況通常的表現是畫面出現很多小方塊,看上去像是打了馬賽克一樣,導致畫面的局部或者整體看不清楚的情況
配置時指定目標碼率和碼率控制模式:
碼率控制模式有三種:
碼率控制模式在 MediaCodecInfo.EncoderCapabilities 類中定義了三種,在 framework 層有另一套名字和它們的值一一對應:
動態調整目標碼率:
Android 流控策略選擇
下面展示使用MediaExtractor獲取數據後,用MediaMuxer重新寫成一個MP4文件的簡單栗子
『貳』 安卓手機的數據線,它的介面的類型是什麼
安卓手機的數據線的介面類型有五種,分別是MBUS、FBUS、DKU-5、FLASH和USB數據線,
現在大多數用到的都是USB數據線。關於這五種介面的具體分析如下:
MBUS數據線:
傳輸速率低(9.6kbp/s),硬體比較簡單,主要適用於維修、解鎖類軟體;
FBUS數據線:
傳輸率較高(115.2kbp/s),主要用於無線上網、鈴聲、圖片、游戲等傳輸;
DKU-5數據線:
高速數據傳輸功能(230kbp/s),數據線構造復雜,製造成本高,但只支持相應功能強大的配套軟體和無線高速上網;
FLASH數據線:
除了具備FBUS功能外,還可以用於維修升級等方面;
USB數據線:
手機需要有內置MODEM功能,內置U盤功能,視頻攝相頭功能,這種數據線上傳下載文件速度非常快。
『叄』 安卓手機數據線介面類型有哪些
1、安卓micro(麥克) usb數據線,現在使用最普遍的一款數據線,基本適用於除蘋果手機外的所有安卓手機,充電+數據傳輸功能。
2、安卓雙面micro usb介面數據線,適用於所有的安卓手機,雙面可插,即插即用不分正反。
3、安卓type(泰普)-c介面數據線,數據線界的新星,具有快速充電,高速數據傳輸,不分正反。
(3)android的介面擴展閱讀:
合理選購數據線:
一般認為選購數據線最大的關鍵就是價格,實際上這是最大的誤區。剛才就提到了,數據線根據廠家來分就分國產品牌和國產無牌的,國產無牌裡面有雜牌的,雜牌的質量差,3根裡面就有1根是壞的,弄得客戶不停懷疑自己的電腦水平太差,所以說分清楚產品的質量和尋找良好的銷售商是關鍵因素。
比較有實力的銷售商一般就是產品質量的保證,他們不想賣出去的數據線都被退貨和換貨,就算時間精力也要消耗不少。因此金牌銷售商都會和有名有信譽的廠家合作,這些廠家一般的故障率為1%,而一些不良廠家的故障率為30%。這就是為何同樣型號功能的數據線價格要差2倍的原因了。
『肆』 安卓手機充電介面叫什麼
一般在上海的手機專賣店就可以買到,看你用的是安卓手機還是蘋果手機,介面都是不一樣的,有以下幾種介面參考,看你的手機是什麼類型的介面。
1、Mini USB介面
早期手機最常見的一種介面,這種介面由於防誤插性能出眾被廣泛的應用於當年的手機、MP3、MP4數碼相機。
『伍』 安卓手機充電介面叫什麼
安卓手機充電介面分兩種。
一、Micro USB 介面。
這種借口為新興介面,在最新款的手機上應用較多,華為就是其中之一。
(5)android的介面擴展閱讀:
Micro-USB介面優點:
1、Micro-USB連接器比標准USB和Mini-USB連接器更小,節省空間,具有高達10000次的插拔壽命和強度,盲插結構設計。
2、Micro-USB標准支持目前USB的OTG功能,即在沒有主機(例如個人電腦)的情況下,便攜設備之間可直接實現數據傳輸,兼容USB1.1 (低速:1.5Mb/s,全速:12Mb/s) 和USB 2.0(高速:60Mb/s),同時提供數據傳輸和充電,特別適用於高速(HS)或更高速率的數據傳輸,是連接小型設備(如手機,PDA,數碼相機,數碼攝像機和便攜數字播放器等等)的最佳選擇。
3、MICRO USB通用性廣,使用方便。
Type-C主要優點:
1、更薄的機身需要更薄的埠,這也是USB-C橫空出世的原因之一。USB-C埠長0.83厘米、寬0.26厘米。老式USB埠長1.4厘米、寬0.65厘米已經顯得過時。這也意味著USB-C數據線的末端將是標准USB-A型數據線插頭尺寸的三分之一。
2、像蘋果的Lightning介面一樣,USB-C埠正面和反面是相同的。也就是說無論你怎麼插入這一埠都是正確的。用戶不必擔心傳統USB埠所帶來的正反問題。
參考資料來源:搜狗網路-micro usb
參考資料來源:搜狗網路-USB Type-C介面
『陸』 安卓手機充電介面排針名稱是什麼
名稱是:Micro-USB。
『柒』 安卓的充電器介面叫什麼
安卓手機充電介面叫做Micro USB介面。
全球就曾大規模推動手機充電器標准統一,多國頒布了非強制性法令,手機廠商因此做出改進。
而中國也力推「USB連接線與充電插頭分離」,這已被絕大多數廠商接受。數據線與插頭分離式的設計已取代傳統一體式設計。
雖然使用標准USB介面連接插座和數據線基本得到了廣泛認同,但在數據線的另一端,通過何種介面與手機連接,還存在較大分歧。
政協委員提案:希望手機充電插口統一
2007年,全國政協委員、北京大學國際關系學院副院長賈慶國在政協會議上提出提案,希望能將手機充電器的連線插口統一、標准化。今年的兩會上,他又提出了這個提案。
他認為,手機充電器插口不一樣為用戶造成很大不便。一是增加消費者的成本;另一方面也耗費了大量資源,帶來環境污染。
蘋果充電器與安卓充電器最大的區別就是其介面不同。
1、蘋果充電器的充電介面是雙面插頭,安卓充電器的充電介面是單面插頭;
2、蘋果充電器只能為蘋果手機充電,安卓充電器可以為大部分安卓手機充電;
3、蘋果充電器與安卓充電器不能混用,當然安卓充電器最好也是使用本機所帶充電器;
『捌』 Android介面回調總結,以及運用到彈窗PopWindow的Demo實現
最近項目中接觸到介面回調,以及Android彈窗PopWindow組件的使用,現在利用學到的知識自己寫了一個簡單的Demo,練習下在Android下如何運用介面回調,來實現彈窗PopWindow的功能。
1. 定義一個介面:OnSelectItemListener。定義一個方法 void selectItem(String name, int type),作為點擊彈窗的每個Item的回調介面。
2. 自定義彈窗類:MyPopupWindow,其布局文件為popup_window.xml。當在MainActivity調用其構造函數創建對象時,同時執行initPopupWindow()函數,給每個Item設置監聽器,監聽點擊Item時,回調介面函數selectItem("Pop Window A", POP_WINDOW_ITEM_1),該函數在MainActivity中實現。
3. 主Activity: MainActivity。其布局文件為一個Button和一個TextView。監聽Button,每當點擊則彈出PopWindow,呈現三個Item。調用MyPopupWindow類中的方法setOnSelectItemListener(OnSelectItemListener listener),傳入OnSelectItemListener 對象作為參數,同時實現回調介面OnSelectItemListener的方法void selectItem(String name, int type)。
主Activity: MainActivity. java
[java] view plain
packagecom.lambdroid.callbacktest2;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importandroid.widget.Toast;
//聯系介面的回調以及PopWindow彈窗的簡單使用
{
privateMyPopupWindow myPopupWindow;
privateButton btn_pop_window;
privateTextView tv_display;
protectedContext context;
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context =this;
btn_pop_window = (Button) findViewById(R.id.btn_pop_window);
tv_display = (TextView) findViewById(R.id.tv_display);
//給Button設置事件監聽:彈出彈窗
btn_pop_window.setOnClickListener(newView.OnClickListener() {
@Override
publicvoidonClick(View v) {
myPopupWindow.show(btn_pop_window);
}
});
myPopupWindow =newMyPopupWindow(context);
//實現OnSelectItemListener介面的selectItem方法:對於彈窗三個Item的事件監聽
myPopupWindow.setOnSelectItemListener(newOnSelectItemListener() {
@Override
publicvoidselectItem(String name,inttype) {
//點擊電站列表,彈出彈框
if(myPopupWindow !=null&& myPopupWindow.isShowing()) {
myPopupWindow.dismiss();
}
tv_display.setText(name);
switch(type){
caseMyPopupWindow.POP_WINDOW_ITEM_1:
Toast.makeText(context,"我是彈窗A, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
caseMyPopupWindow.POP_WINDOW_ITEM_2:
Toast.makeText(context,"我是彈窗B, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
caseMyPopupWindow.POP_WINDOW_ITEM_3:
Toast.makeText(context,"我是彈窗C, 我的英文名是"+ name, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
});
}
}
activity_main.xml
[html] view plain
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/btn_pop_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="20dp"
android:padding="20dp"
android:text="Pop Window"
android:textSize="20sp"/>
android:id="@+id/tv_display"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="Hello World!"
android:textSize="30sp"/>
自定義彈窗類:MyPopupWindow.java
[java] view plain
packagecom.lambdroid.callbacktest2;
importandroid.app.ActionBar;
importandroid.content.Context;
importandroid.graphics.drawable.ColorDrawable;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.widget.LinearLayout;
importandroid.widget.PopupWindow;
.OnClickListener{
privatePopupWindow mPopWindow;
privateContext mContext;
privateLinearLayout llPop1;
privateLinearLayout llPop2;
privateLinearLayout llPop3;
privateintpw_height;
publicstaticfinalintPOP_WINDOW_ITEM_1 =1;
publicstaticfinalintPOP_WINDOW_ITEM_2 =2;
publicstaticfinalintPOP_WINDOW_ITEM_3 =3;
privateOnSelectItemListener listener;
(OnSelectItemListener listener){
this.listener = listener;
}
publicMyPopupWindow(Context context){
mContext = context;
initPopupWindow();//初始化彈窗
}
publicvoidinitPopupWindow(){
View view = LayoutInflater.from(mContext).inflate(R.layout.popup_window,null);
mPopWindow =newPopupWindow(view, ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT,true);
mPopWindow.setOutsideTouchable(true);
/** 為其設置背景,使得其內外焦點都可以獲得 */
mPopWindow.setBackgroundDrawable(newColorDrawable());
mPopWindow.setFocusable(true);
pw_height = view.getHeight();
llPop1 = (LinearLayout) view.findViewById(R.id.ll_pop_1);
llPop1.setOnClickListener(this);
llPop2 = (LinearLayout) view.findViewById(R.id.ll_pop_2);
llPop2.setOnClickListener(this);
llPop3 = (LinearLayout) view.findViewById(R.id.ll_pop_3);
llPop3.setOnClickListener(this);
}
//監聽三個彈窗的點擊事件
@Override
publicvoidonClick(View v) {
switch(v.getId()){
caseR.id.ll_pop_1:
if(listener !=null) {
listener.selectItem("Pop Window A", POP_WINDOW_ITEM_1);//回調介面
}
break;
caseR.id.ll_pop_2:
if(listener !=null) {
listener.selectItem("Pop Window B", POP_WINDOW_ITEM_2);
}
break;
caseR.id.ll_pop_3:
if(listener !=null) {
listener.selectItem("Pop Window C", POP_WINDOW_ITEM_1);
}
break;
default:
break;
}
}
//顯示彈窗,並設置彈窗基於標題欄的顯示位置
publicvoidshow(View view) {
//popupwindow相對view位置x軸偏移量
View viewTemp = mPopWindow.getContentView();
viewTemp.measure(0,0);
intwidth = viewTemp.getMeasuredWidth();
intxOffset = (view.getWidth() - width) /2;
mPopWindow.showAsDropDown(view, xOffset,0);
}
/**
* 退出popupwindow
*/
publicvoiddismiss() {
if(mPopWindow !=null&& mPopWindow.isShowing()) {
mPopWindow.dismiss();
}
}
/**
* popupwindow是否正在顯示
*/
publicbooleanisShowing() {
if(mPopWindow !=null) {
returnmPopWindow.isShowing();
}
returnfalse;
}
}
popup_window.xml
[html] view plain
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
android:id="@+id/ll_alarm_type"
android:layout_width="120dp"
android:layout_height="130dp"
android:orientation="vertical"
android:background="@drawable/popupwindow"
android:paddingBottom="16dp"
android:paddingTop="16dp">
android:id="@+id/ll_pop_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 A"
android:textSize="15sp"
android:textColor="#ffffff"/>
android:id="@+id/ll_pop_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 B"
android:textSize="15sp"
android:textColor="#ffffff"/>
android:id="@+id/ll_pop_3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="窗口 C"
android:textSize="15sp"
android:textColor="#FFFFFF"/>
回調介面:OnSelectItemListener
[java] view plain
packagecom.lambdroid.callbacktest2;
{
voidselectItem(String name,inttype);
}
點擊Button,彈出彈窗,顯示三個Item
點擊第二個Item,通過回調函數,來實現TextView內容的修改,以及彈出Toast
總結
Java回調情形涉及很多,本文屬於介面的非同步回調:當不知道何時會執行介面的回調函數,(通過介面回調來對獲取到的資源的操作)。除此還有線程間的非同步回調(子線程進行耗時操作,操作完畢通知主線程或將數據傳給主線程處理),以及利用介面回調來實現線程間的數據通信等等(Android可以利用Handler來實現)。等下次再舉例說明Java回調函數的其它情形。
『玖』 安卓手機數據線插孔叫什麼名字
目前安卓的數據線分為兩種
一、早期的MicroUSB,插入手機有正反面區別
如下圖所示:
這兩種借口都是目前安卓手機常用的介面方式,也是目前魅族手機配備的數據線。