找到加载的so库
public class MediaRecorder implements AudioRouting,
AudioRecordingMonitor,
AudioRecordingMonitorClient,
MicrophoneDirection
{
static {
System.loadLibrary("media_jni");
native_init();
}
定位到media_jni源码
media_jni的目录:告诉你个规律吧!java文件的包名来找到它的JNI文件名。 比如mediaplayer.java 属于android.media.mediaplayer 包 那么JNI 文件就是android_media_mediaplayer.cpp 注意看包名和JNI文件名的对应关系 路径是framework\media\base\jni\
/frameworks/base/media/jni/android_media_MediaRecorder.cpp
然后上面这个类主要是调用/frameworks/av/media/libmedia/mediarecorder.cpp
需要注意一个问题,就是java的native方法名不一定和cpp文件里的一致
源码跟踪
- 我们要查找的是prepare方法,按照上面的规律是在android_media_MediaRecorder.cpp。找到定位到该方法
static void
android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz)
{
ALOGV("prepare");
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
if (mr == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
const sp<Surface> native_surface = get_surface(env, surface);
// The application may misbehave and
// the preview surface becomes unavailable
if (native_surface.get() == 0) {
ALOGE("Application lost the surface");
jniThrowException(env, "java/io/IOException", "invalid preview surface");
return;
}
ALOGI("prepare: surface=%p", native_surface.get());
if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface->getIGraphicBufferProducer()), "java/lang/RuntimeException", "setPreviewSurface failed.")) {
return;
}
}
process_media_recorder_call(env, mr->prepare(), "java/io/IOException", "prepare failed.");
}
可以知道,这里调用到了MediaRecorder
- 搜索并打开MediaRecorder.cpp
status_t MediaRecorder::prepare()
{
ALOGV("prepare");
if (mMediaRecorder == NULL) {
ALOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
ALOGE("prepare called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
if (mIsAudioSourceSet != mIsAudioEncoderSet) {
if (mIsAudioSourceSet) {
ALOGE("audio source is set, but audio encoder is not set");
} else { // must not happen, since setAudioEncoder checks this already
ALOGE("audio encoder is set, but audio source is not set");
}
return INVALID_OPERATION;
}
if (mIsVideoSourceSet != mIsVideoEncoderSet) {
if (mIsVideoSourceSet) {
ALOGE("video source is set, but video encoder is not set");
} else { // must not happen, since setVideoEncoder checks this already
ALOGE("video encoder is set, but video source is not set");
}
return INVALID_OPERATION;
}
status_t ret = mMediaRecorder->prepare();
if (OK != ret) {
ALOGE("prepare failed: %d", ret);
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
mCurrentState = MEDIA_RECORDER_PREPARED;
return ret;
}
里面定位到了mMediaRecorder
变量
- 通过头文件定位到
mediarecorder.h
#include <media/mediarecorder.h>
- 在framew下搜索并打开该文件,找到该变量
- 明显是去到了IMediaRecorder,依旧在framework下搜索IMediaRecorder
明显源码就在IMediaRecorder.cpp中
感谢参考:https://blog.51cto.com/u_4259297/2161337
感谢参考:https://blog.csdn.net/tq501501/article/details/117444705
转载注明:https://blog.csdn.net/u014614038/article/details/117731557