美文网首页Android知识
如何阅读Android framework层源代码

如何阅读Android framework层源代码

作者: 布拉德利_蔡 | 来源:发表于2017-03-12 18:11 被阅读558次

    阅读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().
         *
         * <p>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.</p>
         *
         * @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<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++的继承、实现、接口的相关概念,和一般的读代码没啥区别。

    相关文章

      网友评论

        本文标题:如何阅读Android framework层源代码

        本文链接:https://www.haomeiwen.com/subject/thcxnttx.html