在一个Android项目中,我有一个非常混乱的继承情况,我无法完全理解。
这是我得到的错误:
proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:4458:51: error: cannot allocate an object of abstract type 'android::MediaRecorder'
m_MediaRecorderClient = new MediaRecorder();
^
In file included from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.h:101:0,
from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:199:
frameworks/av/include/media/mediarecorder.h:245:7: note: because the following virtual functions are pure within 'android::MediaRecorder':
class MediaRecorder : public BnMediaRecorderClient,
^
In file included from frameworks/av/include/media/mediarecorder.h:30:0,
from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.h:101,
from proprietary/external/audioATCmdHandlerServer/AudioCmdHandler.cpp:199:
frameworks/av/include/media/IMediaRecorderClient.h:32:18: note: virtual void android::IMediaRecorderClient::readAudio()
virtual void readAudio() = 0;
这是来自mediarecorder.h的MediaRecorder类
............
.......
#include <media/IMediaRecorderClient.h>
.......
...........
class MediaRecorder : public BnMediaRecorderClient,
public virtual IMediaDeathNotifier
{
public:
MediaRecorder();
~MediaRecorder();
void died();
status_t initCheck();
status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy);
status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
status_t setVideoSource(int vs);
status_t setAudioSource(int as);
status_t setOutputFormat(int of);
status_t setVideoEncoder(int ve);
status_t setAudioEncoder(int ae);
status_t setOutputFile(const char* path);
status_t setOutputFile(int fd, int64_t offset, int64_t length);
status_t setVideoSize(int width, int height);
status_t setVideoFrameRate(int frames_per_second);
status_t setParameters(const String8& params);
status_t setListener(const sp<MediaRecorderListener>& listener);
status_t setClientName(const String16& clientName);
status_t prepare();
status_t getMaxAmplitude(int* max);
status_t start();
status_t stop();
status_t reset();
status_t init();
status_t close();
status_t release();
void notify(int msg, int ext1, int ext2);
sp<IGraphicBufferProducer> querySurfaceMediaSourceFromMediaServer();
#ifdef MTK_AOSP_ENHANCEMENT
status_t setParametersExtra(const String8& params);
#endif
private:
void doCleanUp();
status_t doReset();
sp<IMediaRecorder> mMediaRecorder;
sp<MediaRecorderListener> mListener;
// Reference to IGraphicBufferProducer
// for encoding GL Frames. That is useful only when the
// video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
sp<IGraphicBufferProducer> mSurfaceMediaSource;
media_recorder_states mCurrentState;
bool mIsAudioSourceSet;
bool mIsVideoSourceSet;
bool mIsAudioEncoderSet;
bool mIsVideoEncoderSet;
bool mIsOutputFileSet;
Mutex mLock;
Mutex mNotifyLock;
};
这是IMediaRecorderClient.h
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
namespace android {
class IMediaRecorderClient: public IInterface
{
public:
DECLARE_META_INTERFACE(MediaRecorderClient);
virtual void notify(int msg, int ext1, int ext2) = 0;
virtual void readAudio() = 0;
};
// ----------------------------------------------------------------------------
class BnMediaRecorderClient: public BnInterface<IMediaRecorderClient>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
};
这是从IMediaRecorderClient.cpp中摘录的,对我来说似乎实现了抽象方法virtual void readAudio()
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <media/IMediaRecorderClient.h>
namespace android {
enum {
NOTIFY = IBinder::FIRST_CALL_TRANSACTION,
READ_AUDIO,
};
class BpMediaRecorderClient: public BpInterface<IMediaRecorderClient>
{
public:
BpMediaRecorderClient(const sp<IBinder>& impl)
: BpInterface<IMediaRecorderClient>(impl)
{
}
virtual void notify(int msg, int ext1, int ext2)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorderClient::getInterfaceDescriptor());
data.writeInt32(msg);
data.writeInt32(ext1);
data.writeInt32(ext2);
remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual void readAudio()
{
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorderClient::getInterfaceDescriptor());
remote()->transact(READ_AUDIO, data, &reply, IBinder::FLAG_ONEWAY);
}
};
我哪里错了?
最佳答案
编译器在AudioCmdHandler.cpp
的以下语句中告诉您:
m_MediaRecorderClient = new MediaRecorder();
试图实例化作为抽象类的类
MediaRecorder
。抽象类意味着它具有至少一个根本没有定义的虚函数,在您的情况下为readAudio()
。怎么来的 ?
您显示的
MediaRecorder
的类定义不提供readAudio()
。但是该类继承自BnMediaRecorderClient
。这个也不提供readAudio()
,并且从模板BnInterface<IMediaRecorderClient>
继承。我不知道模板类
BnInterface<...>
是如何定义的,但是我想它是CRTP扩展了作为参数提供的接口,因此最终MediaRecorder
将间接继承自IMediaRecorderClient
。而这个定义了这个纯虚函数:
virtual void readAudio() = 0;
怎么解决呢?
您必须在
MediaRecorder
中提供提供并实现此功能,才能实例化此类的对象。