欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

閱讀android源碼,源碼閱讀app

如何閱讀android framework源碼

首先看MediaRecorder.java內(nèi)的setVideoEncoder方法:

網(wǎng)站制作、網(wǎng)站建設(shè)中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷成為有效果、有回報(bào)的無錫營(yíng)銷推廣。成都創(chuàng)新互聯(lián)專業(yè)成都網(wǎng)站建設(shè)10多年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。

/**

* Sets the video encoder to be used for recording. If this method is not

* called, the output file will not contain an video track. Call this after

* setOutputFormat() and before prepare().

*

* @param video_encoder the video encoder to use.

* @throws IllegalStateException if it is called before

* setOutputFormat() or after prepare()

* @see android.media.MediaRecorder.VideoEncoder

*/

public native void setVideoEncoder(int video_encoder)

throws IllegalStateException;123456789101112

這是一個(gè)native方法,根據(jù)JNI的規(guī)則,我們應(yīng)該去android_media_MediaRecorder.cpp里看這個(gè)方法的實(shí)現(xiàn):

static void

android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve)

{

ALOGV("setVideoEncoder(%d)", ve);

if (ve VIDEO_ENCODER_DEFAULT || ve = VIDEO_ENCODER_LIST_END) {

jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder");

return;

}

spMediaRecorder mr = getMediaRecorder(env, thiz);

process_media_recorder_call(env, mr-setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed.");

}1234567891011

關(guān)鍵是最后的兩句,sp是Android 里的一個(gè)指針,就當(dāng)沒看見~ 所以最后兩句的意思是調(diào)用Native層的MediaRecorder的setVideoEncoder方法。

繼續(xù)去MediaRecorder.cpp里看setVideoEncoder方法:

status_t MediaRecorder::setVideoEncoder(int ve)

{

ALOGV("setVideoEncoder(%d)", ve);

if (mMediaRecorder == NULL) {

ALOGE("media recorder is not initialized yet");

return INVALID_OPERATION;

}

if (!mIsVideoSourceSet) {

ALOGE("try to set the video encoder without setting the video source first");

return INVALID_OPERATION;

}

if (mIsVideoEncoderSet) {

ALOGE("video encoder has already been set");

return INVALID_OPERATION;

}

if (!(mCurrentState MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {

ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);

return INVALID_OPERATION;

}

status_t ret = mMediaRecorder-setVideoEncoder(ve);

if (OK != ret) {

ALOGV("setVideoEncoder failed: %d", ret);

mCurrentState = MEDIA_RECORDER_ERROR;

return ret;

}

mIsVideoEncoderSet = true;

return ret;

}1234567891011121314151617181920212223242526272829

這里的mMediaReocorder定義在MediaRecorder.h里:

spIMediaRecorder mMediaRecorder;1

可見其是一個(gè)IMediaRecorder類型的變量,這是一個(gè)接口類型,看一下其接口定義,在IMediaRecorder.h中:

class IMediaRecorder: public IInterface

{

public:

DECLARE_META_INTERFACE(MediaRecorder);

virtual status_t setCamera(const sphardware::ICamera camera,

const spICameraRecordingProxy proxy) = 0;

virtual status_t setPreviewSurface(const spIGraphicBufferProducer surface) = 0;

virtual status_t setVideoSource(int vs) = 0;

virtual status_t setAudioSource(int as) = 0;

virtual status_t setOutputFormat(int of) = 0;

virtual status_t setVideoEncoder(int ve) = 0;

virtual status_t setAudioEncoder(int ae) = 0;

virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;

virtual status_t setVideoSize(int width, int height) = 0;

virtual status_t setVideoFrameRate(int frames_per_second) = 0;

virtual status_t setParameters(const String8 params) = 0;

virtual status_t setListener(const spIMediaRecorderClient listener) = 0;

virtual status_t setClientName(const String16 clientName) = 0;

virtual status_t prepare() = 0;

virtual status_t getMaxAmplitude(int* max) = 0;

virtual status_t start() = 0;

virtual status_t stop() = 0;

virtual status_t reset() = 0;

virtual status_t pause() = 0;

virtual status_t resume() = 0;

virtual status_t init() = 0;

virtual status_t close() = 0;

virtual status_t release() = 0;

virtual status_t setInputSurface(const spIGraphicBufferConsumer surface) = 0;

virtual spIGraphicBufferProducer querySurfaceMediaSource() = 0;

};

// ----------------------------------------------------------------------------

class BnMediaRecorder: public BnInterfaceIMediaRecorder

{

public:

virtual status_t onTransact( uint32_t code,

const Parcel data,

Parcel* reply,

uint32_t flags = 0);

};12345678910111213141516171819202122232425262728293031323334353637383940414243

吶~關(guān)鍵的步驟來了,在以前我基本就追到這,就算完蛋了,不知道怎么繼續(xù)往下追了,后來看Binder相關(guān)的內(nèi)容,知道了BnInterface的作用,這是Binder中關(guān)鍵的一環(huán),我們這就不展開講了,只要記得,接下來我們要追的是BnMediaRecorder這個(gè)類。

全局搜索一下“: public BnMediaRecorder”,也就是去找它的實(shí)現(xiàn)類,發(fā)現(xiàn)在MediaRecorderClient.h當(dāng)中有如下的定義:

class MediaRecorderClient : public BnMediaRecorder

{

class ServiceDeathNotifier: public IBinder::DeathRecipient

{

public:

ServiceDeathNotifier(

const spIBinder service,

const spIMediaRecorderClient listener,

int which);

virtual ~ServiceDeathNotifier();

virtual void binderDied(const wpIBinder who);

private:

int mWhich;

spIBinder mService;

wpIMediaRecorderClient mListener;

};

public:

virtual status_t setCamera(const sphardware::ICamera camera,

const spICameraRecordingProxy proxy);

virtual status_t setPreviewSurface(const spIGraphicBufferProducer surface);

virtual status_t setVideoSource(int vs);

virtual status_t setAudioSource(int as);

virtual status_t setOutputFormat(int of);

virtual status_t setVideoEncoder(int ve);

virtual status_t setAudioEncoder(int ae);

virtual status_t setOutputFile(int fd, int64_t offset,

int64_t length);

virtual status_t setVideoSize(int width, int height);

virtual status_t setVideoFrameRate(int frames_per_second);

virtual status_t setParameters(const String8 params);

virtual status_t setListener(

const spIMediaRecorderClient listener);

virtual status_t setClientName(const String16 clientName);

virtual status_t prepare();

virtual status_t getMaxAmplitude(int* max);

virtual status_t start();

virtual status_t stop();

virtual status_t reset();

virtual status_t pause();

virtual status_t resume();

virtual status_t init();

virtual status_t close();

virtual status_t release();

virtual status_t dump(int fd, const VectorString16 args);

virtual status_t setInputSurface(const spIGraphicBufferConsumer surface);

virtual spIGraphicBufferProducer querySurfaceMediaSource();

private:

friend class MediaPlayerService; // for accessing private constructor

MediaRecorderClient(

const spMediaPlayerService service,

pid_t pid,

const String16 opPackageName);

virtual ~MediaRecorderClient();

spIBinder::DeathRecipient mCameraDeathListener;

spIBinder::DeathRecipient mCodecDeathListener;

pid_t mPid;

Mutex mLock;

MediaRecorderBase *mRecorder;

spMediaPlayerService mMediaPlayerService;

};123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566

那么我們?nèi)ediaRecorderClient.cpp里看看:

status_t MediaRecorderClient::setVideoEncoder(int ve)

{

ALOGV("setVideoEncoder(%d)", ve);

Mutex::Autolock lock(mLock);

if (mRecorder == NULL) {

ALOGE("recorder is not initialized");

return NO_INIT;

}

return mRecorder-setVideoEncoder((video_encoder)ve);

}12345678910

這里的mRecorder 定義在MediaRecorderClient.h當(dāng)中:

MediaRecorderBase *mRecorder;1

來,我們繼續(xù)搜索“: public MediaRecorderBase”,在StagefrightRecorder.h中找到了,那么我們?nèi)tagefrightRecorder.cpp當(dāng)中看看~

status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {

ALOGV("setVideoEncoder: %d", ve);

if (ve VIDEO_ENCODER_DEFAULT ||

ve = VIDEO_ENCODER_LIST_END) {

ALOGE("Invalid video encoder: %d", ve);

return BAD_VALUE;

}

mVideoEncoder = ve;

return OK;

}123456789101112

吶,這就算完了~最后我們會(huì)發(fā)現(xiàn)MediaRecorder中的接口實(shí)現(xiàn)基本到最后都會(huì)落在這個(gè)StagefrightRecorder.cpp當(dāng)中。

如何閱讀Android應(yīng)用層源代碼

當(dāng)閱讀Android原生的應(yīng)用層源代碼時(shí),當(dāng)遇到不理解的API時(shí),如果僅憑將API函數(shù)放到google的官方API網(wǎng)頁(yè)中去搜索的話,不一定合適,可以用eclipse先搜到該函數(shù)的定義處,看屬于哪個(gè)類,然后再在google的官方API網(wǎng)頁(yè)中搜該類,然后找到這個(gè)方法,如果該方法還是沒在該類中,那么可以用eclipse找找該方法是不是繼承與其子類,再?gòu)淖宇愔兴阉选?/p>

構(gòu)建開發(fā)環(huán)境

1、 構(gòu)建Android編譯環(huán)境:

Ubuntu11.10-64bit系統(tǒng)、一系列編譯庫(kù)、JDK、Android SDK、Eclipse +ADT。

2、 Android官方原生Android代碼。

3、 源代碼根目錄下:

source build/envsetup.sh

lunch full-eng

make –j4

1、2、3相關(guān)內(nèi)容在都有相關(guān)說明。

4、 編譯Android源碼的同時(shí),可以建立Android源代碼Java工程

(1)將源碼目錄\development\ide\eclipse 中的.classpath復(fù)制到源碼根目錄下。

(2)更改eclipse緩存設(shè)置

在eclipse安裝根目錄下修改eclipse.ini

-Xms128m

-Xmx512m

-XX:MaxPermSize=256m

(3)將 源碼目錄\development\ide\eclipse 中的android-formatting.xml和android.importorder導(dǎo)入eclipse。

android-formatting.xml用來配置eclipse編輯器的代碼風(fēng)格;android.importorder用來配置eclipse的import的順序和結(jié)構(gòu)。

如何用adroid studio 如何閱讀android源碼

在android源碼中有一個(gè)目錄idegen,是生成ide的project文件,主要是生成intellij的project文件,用source insight閱讀Android源碼,效果非常好。

過程:

效果圖;

在開始編譯idegen模塊前,需要知道需要先全局編譯出out目錄及相關(guān)文件;

在根目錄生成對(duì)應(yīng)的android.ipr、android.iml IEDA工程配置文件;

導(dǎo)入到android studio,打開Android studio,點(diǎn)擊File Open,選擇剛剛生成的android.ipr就好了;

備注:

可以結(jié)合android studio,界面,智能提示都比source insight要好。

如何查看Android源碼

當(dāng)我們?cè)趀clipse中開發(fā)android程序的時(shí)候,往往需要看源代碼(可能是出于好奇,可能是讀源碼習(xí)慣),那么如何查看Android源代碼呢? 比如下面這種情況假設(shè)我們想?yún)⒖碅ctivity類的源代碼,按著Ctrl鍵,左擊它,現(xiàn)實(shí)的結(jié)果卻看不到代碼的,提示的信息便是“找不到Activity.class文件”。此時(shí)點(diǎn)擊下面的按鈕,“Change Attached Source…”,選擇android源代碼所在位置,便彈出圖三的對(duì)話框。 第一種是選擇工作目錄,即已經(jīng)存在的android應(yīng)用程序源代碼。 第二種分兩種方式 (1)選擇External File…按鈕,添加Jar格式文件或者zip格式文件路徑; (2)選擇External Floder…按鈕,添加文件夾所在路徑。 下面問題就來了,源代碼在哪里?不能憑空產(chǎn)生阿。 可以通過Android SDK Manager進(jìn)行源代碼下載;(推薦該種方法)

大牛們是怎么閱讀 Android 系統(tǒng)源碼的

由于工作需要大量修改framework代碼, 在AOSP(Android Open Source Project)源碼上花費(fèi)了不少功夫, Application端和Services端都看和改了不少.

如果只是想看看一些常用類的實(shí)現(xiàn), 在Android包管理器里把源碼下載下來, 隨便一個(gè)IDE配好Source Code的path看就行.

但如果想深入的了解Android系統(tǒng), 那么可以看下我的一些簡(jiǎn)單的總結(jié).

知識(shí)

Java

Java是AOSP的主要語言之一. 沒得說, 必需熟練掌握.

熟練的Android App開發(fā)

Linux

Android基于Linux的, 并且AOSP的推薦編譯環(huán)境是Ubuntu 12.04. 所以熟練的使用并了解Linux這個(gè)系統(tǒng)是必不可少的. 如果你想了解偏底層的代碼, 那么必需了解基本的Linux環(huán)境下的程序開發(fā). 如果再深入到驅(qū)動(dòng)層, 那么Kernel相關(guān)的知識(shí)也要具備.

Make

AOSP使用Make系統(tǒng)進(jìn)行編譯. 了解基本的Makefile編寫會(huì)讓你更清晰了解AOSP這個(gè)龐大的項(xiàng)目是如何構(gòu)建起來的.

Git

AOSP使用git+repo進(jìn)行源碼管理. 這應(yīng)該是程序員必備技能吧.

C++

Android系統(tǒng)的一些性能敏感模塊及第三方庫(kù)是用C++實(shí)現(xiàn)的, 比如: Input系統(tǒng), Chromium項(xiàng)目(WebView的底層實(shí)現(xiàn)).

硬件

流暢的國(guó)際網(wǎng)絡(luò)

AOSP代碼下載需要你擁有一個(gè)流暢的國(guó)際網(wǎng)絡(luò). 如果在下載代碼這一步就失去耐心的話, 那你肯定沒有耐心去看那亂糟糟的AOSP代碼. 另外, 好程序員應(yīng)該都會(huì)需要一個(gè)流暢的Google.

一臺(tái)運(yùn)行Ubuntu 12.04的PC.

如果只是閱讀源碼而不做太多修改的話, 其實(shí)不需要太高的配置.

一臺(tái)Nexus設(shè)備

AOSP項(xiàng)目默認(rèn)只支持Nexus系列設(shè)備. 沒有也沒關(guān)系, 你依然可以讀代碼. 但如果你想在大牛之路走的更遠(yuǎn), 還是改改代碼, 然后刷機(jī)調(diào)試看看吧.

高品質(zhì)USB線

要刷機(jī)時(shí)線壞了, 沒有更窩心的事兒了.

軟件

Ubuntu 12.04

官方推薦, 沒得選.

Oracle Java 1.6

注意不要用OpenJDK. 這是個(gè)坑, 官方文檔雖然有寫, 但還是單獨(dú)提一下.

安裝:

sudo apt-get install python-software-properties

sudo add-apt-repository ppa:webupd8team/java

sudo apt-get update

sudo apt-get install oracle-java6-installer

sudo apt-get install oracle-java6-set-default

Eclipse

估計(jì)會(huì)有不少人吐槽, 為什么要用這個(gè)老古董. 其實(shí)原因很簡(jiǎn)單, 合適. 剛開始搞AOSP時(shí), 為了找到效率最優(yōu)的工具, 我嘗試過Eclipse, IntelliJ IDEA, Vim+Ctags, Sublime Text+Ctags. 最終結(jié)果還是Eclipse. 主要優(yōu)點(diǎn)有:

有語法分析 (快速準(zhǔn)確的類, 方法跳轉(zhuǎn)).

支持C++ (IntelliJ的C++支持做的太慢了).

嵌入了DDMS, View Hierarchy等調(diào)試工具.

為了提高效率, 花5分鐘背下常用快捷鍵非常非常值得.

調(diào)整好你的classpath, 不要導(dǎo)入無用的代碼. 因?yàn)锳OSP項(xiàng)目代碼實(shí)在是太多了. 當(dāng)你還不需要看C++代碼時(shí), 不要為項(xiàng)目添加C++支持, 建索引過程會(huì)讓你崩潰.

Intellij IDEA

開發(fā)App必備. 當(dāng)你要調(diào)試系統(tǒng)的某個(gè)功能是, 常常需要迅速寫出一個(gè)調(diào)試用App, 這個(gè)時(shí)候老舊的Eclipse就不好用了. Itellij IDEA的xml自動(dòng)補(bǔ)全非常給力.

巨人的肩膀

這個(gè)一定要先讀. 項(xiàng)目介紹, 代碼下載, 環(huán)境搭建, 刷機(jī)方法, Eclipse配置都在這里. 這是一切的基礎(chǔ).

這個(gè)其實(shí)是給App開發(fā)者看的. 但是里面也有不少關(guān)于系統(tǒng)機(jī)制的介紹, 值得細(xì)讀.

此老羅非彼老羅. 羅升陽老師的博客非常有營(yíng)養(yǎng), 基本可以作為指引你開始閱讀AOSP源碼的教程. 你可以按照博客的時(shí)間順序一篇篇挑需要的看.但這個(gè)系列的博客有些問題:

早期的博客是基于舊版本的Android;

大量的代碼流程追蹤. 讀文章時(shí)你一定要清楚你在看的東西在整個(gè)系統(tǒng)處于什么樣的位置.

鄧凡平老師也是為Android大牛, 博客同樣很有營(yíng)養(yǎng). 但是不像羅升陽老師的那么系統(tǒng). 更多的是一些技術(shù)點(diǎn)的深入探討.

Android官方Issue列表. 我在開發(fā)過程中發(fā)現(xiàn)過一些奇怪的bug, 最后發(fā)現(xiàn)這里基本都有記錄. 當(dāng)然你可以提一些新的, 有沒有人改就是另外一回事了.

一定要能流暢的使用這個(gè)工具. 大量的相關(guān)知識(shí)是沒有人系統(tǒng)的總結(jié)的, 你需要自己搞定.

其它

代碼組織

AOSP的編譯單元不是和git項(xiàng)目一一對(duì)應(yīng)的, 而是和Android.mk文件一一對(duì)應(yīng)的. 善用mmm命令進(jìn)行模塊編譯將節(jié)省你大量的時(shí)間.

Binder

這是Android最基礎(chǔ)的進(jìn)程間通訊. 在Application和System services之間大量使用. 你不僅要知道AIDL如何使用, 也要知道如何手寫B(tài)inder接口. 這對(duì)你理解Android的Application和System services如何交互有非常重要的作用. Binder如何實(shí)現(xiàn)的倒不必著急看.

HAL

除非你對(duì)硬件特別感興趣或者想去方案公司上班, 否則別花太多時(shí)間在這一層.

CyanogenMod

這是一個(gè)基于AOSP的第三方Rom. 從這個(gè)項(xiàng)目的wiki里你能學(xué)到很多AOSP官方?jīng)]有告訴你的東西. 比如如何支持Nexus以外的設(shè)備.

DIA

這是一個(gè)Linux下畫UML的工具, 能夠幫你梳理看過的代碼.

XDA

這里有最新資訊和最有趣的論壇.

想到了再補(bǔ)充.

文章名稱:閱讀android源碼,源碼閱讀app
地址分享:http://chinadenli.net/article28/dsgpdcp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航網(wǎng)站收錄全網(wǎng)營(yíng)銷推廣服務(wù)器托管標(biāo)簽優(yōu)化做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)