如何閱讀Android framework層原始碼
閱讀Android Framework層的原始碼可能是Android 開發者深入學習的必經之路。但在我學習的過程中看到最多的是各路大神的原始碼分析,而很少有展示如何一步一步找到相關程式碼的。直到前不久看到老羅的視訊《Android原始碼情景分析法》,很有啟發。但是老羅也只是講到Java層的分析追蹤,在我的日常工作中,經常涉及從Java 層到JNI 層,再到Native層,經常追著追著就丟了。
之後我仿照老羅的方法,嘗試追蹤MediaRecorder的setVideoEncoder方法是怎麼實現的,現在總結如下。
準備:
Source Insight 3
Android Framework層原始碼
分析開始
首先看MediaRecorder.java內的setVideoEncoder方法:
/**
* 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;
這是一個native方法,根據JNI的規則,我們應該去android_media_MediaRecorder.cpp裡看這個方法的實現:
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;
}
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
process_media_recorder_call(env, mr->setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed.");
}
關鍵是最後的兩句,sp是Android 裡的一個指標,就當沒看見~ 所以最後兩句的意思是呼叫Native層的MediaRecorder的setVideoEncoder方法。
繼續去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;
}
這裡的mMediaReocorder定義在MediaRecorder.h裡:
sp<IMediaRecorder> mMediaRecorder;
可見其是一個IMediaRecorder型別的變數,這是一個介面型別,看一下其介面定義,在IMediaRecorder.h中:
class IMediaRecorder: public IInterface
{
public:
DECLARE_META_INTERFACE(MediaRecorder);
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy) = 0;
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& 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 sp<IMediaRecorderClient>& 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 sp<IGraphicBufferConsumer>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
};
// ----------------------------------------------------------------------------
class BnMediaRecorder: public BnInterface<IMediaRecorder>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
吶~關鍵的步驟來了,在以前我基本就追到這,就算完蛋了,不知道怎麼繼續往下追了,後來看Binder相關的內容,知道了BnInterface的作用,這是Binder中關鍵的一環,我們這就不展開講了,只要記得,接下來我們要追的是BnMediaRecorder這個類。
全域性搜尋一下“: public BnMediaRecorder”,也就是去找它的實現類,發現在MediaRecorderClient.h當中有如下的定義:
class MediaRecorderClient : public BnMediaRecorder
{
class ServiceDeathNotifier: public IBinder::DeathRecipient
{
public:
ServiceDeathNotifier(
const sp<IBinder>& service,
const sp<IMediaRecorderClient>& listener,
int which);
virtual ~ServiceDeathNotifier();
virtual void binderDied(const wp<IBinder>& who);
private:
int mWhich;
sp<IBinder> mService;
wp<IMediaRecorderClient> mListener;
};
public:
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy);
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& 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 sp<IMediaRecorderClient>& 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 Vector<String16>& args);
virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface);
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource();
private:
friend class MediaPlayerService; // for accessing private constructor
MediaRecorderClient(
const sp<MediaPlayerService>& service,
pid_t pid,
const String16& opPackageName);
virtual ~MediaRecorderClient();
sp<IBinder::DeathRecipient> mCameraDeathListener;
sp<IBinder::DeathRecipient> mCodecDeathListener;
pid_t mPid;
Mutex mLock;
MediaRecorderBase *mRecorder;
sp<MediaPlayerService> mMediaPlayerService;
};
那麼我們去MediaRecorderClient.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);
}
這裡的mRecorder 定義在MediaRecorderClient.h當中:
MediaRecorderBase *mRecorder;
來,我們繼續搜尋“: public MediaRecorderBase”,在StagefrightRecorder.h中找到了,那麼我們去StagefrightRecorder.cpp當中看看~
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;
}
吶,這就算完了~最後我們會發現MediaRecorder中的介面實現基本到最後都會落在這個StagefrightRecorder.cpp當中。
總結
在Android原始碼閱讀當中,由於大多數人都沒接觸過大型的C++工程,所以在Native層的追蹤上一開始會有較大困難,但只要靜下心來,會發現其實只要記住C++的繼承、實現、介面的相關概念,和一般的讀程式碼沒啥區別。