如何阅读Android framework层源代码

阅读Android Framework层的源码可能是Android 开发者深入学习的必经之路。但在我学习的过程中看到最多的是各路大神的源码分析,而很少有展示如何一步一步找到相关代码的。直到前不久看到老罗的视频《Android源代码情景分析法》,很有启发。但是老罗也只是讲到Java层的分析追踪,在我的日常工作中,经常涉及从Java 层到JNI 层,再到Native层,经常追着追着就丢了。

之后我仿照老罗的方法,尝试追踪MediaRecorder的setOutputFormat方法是怎么实现的,现在总结如下。

准备:

  • Source Insight 3

  • Android Framework层源码

分析开始

首先看MediaRecorder.java内的setOutputFormat方法:

    /**
     * Sets the format of the output file produced during recording. Call this
     * after setAudioSource()/setVideoSource() but before prepare().
     *
     * 

It is recommended to always use 3GP format when using the H.263 * video encoder and AMR audio encoder. Using an MPEG-4 container format * may confuse some desktop players.

* * @param output_format the output format to use. The output format * needs to be specified before setting recording-parameters or encoders. * @throws IllegalStateException if it is called after prepare() or before * setAudioSource()/setVideoSource(). * @see android.media.MediaRecorder.OutputFormat */ public native void setOutputFormat(int output_format) 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 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          mMediaRecorder;

可见其是一个IMediaRecorder类型的变量,这是一个接口类型,看一下其接口定义,在IMediaRecorder.h中:

class IMediaRecorder: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaRecorder);

    virtual status_t setCamera(const sp& camera,
                               const sp& proxy) = 0;
    virtual status_t setPreviewSurface(const sp& 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& 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& surface) = 0;
    virtual sp querySurfaceMediaSource() = 0;
};

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

class BnMediaRecorder: public BnInterface
{
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& service,
                const sp& listener,
                int which);
        virtual ~ServiceDeathNotifier();
        virtual void binderDied(const wp& who);

    private:
        int mWhich;
        sp mService;
        wp mListener;
    };

public:
    virtual     status_t   setCamera(const sp& camera,
                                    const sp& proxy);
    virtual     status_t   setPreviewSurface(const sp& 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& 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& args);
    virtual     status_t   setInputSurface(const sp& surface);
    virtual     sp querySurfaceMediaSource();

private:
    friend class           MediaPlayerService;  // for accessing private constructor

                           MediaRecorderClient(
                                   const sp& service,
                                                               pid_t pid,
                                                               const String16& opPackageName);
    virtual                ~MediaRecorderClient();

    sp mCameraDeathListener;
    sp mCodecDeathListener;

    pid_t                  mPid;
    Mutex                  mLock;
    MediaRecorderBase      *mRecorder;
    sp 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++的继承、实现、接口的相关概念,和一般的读代码没啥区别。

你可能感兴趣的:(如何阅读Android framework层源代码)