In einem Android-Projekt habe ich eine ziemlich chaotische Vererbungssituation, die ich nicht vollständig verstehe. Dies ist der Fehler, den ich Kompilieren erhalten:C++ - Implementierung der abstrakten Methode nicht erfüllt
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;
Dies ist die Klasse MediaRecorder von mediarecorder.h
............
.......
#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;
};
Diese IMediaRecorderClient.h ist
#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);
};
};
Und dies ist ein Auszug aus IMediaRecorderClient.cpp, das scheint mir die abstrakte Methode virtual void readAudio()
zu implementieren#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);
}
};
Wo liege ich falsch?
TLDR: Der Compiler sagt Ihnen genau, was das Problem ist. –
Was @ DieterLücking sagt, die Fehlermeldung ist 100% klar. Aber falls es Ihnen nicht klar ist, wird der BpMediaRecorderClient durch den fehlerhaften Code nicht instanziiert. Es instanziiert einen 'MediaRecorder'. –
Danke Jungs, genau das habe ich befürchtet. Ich hatte gehofft, dass ein Mechanismus, den ich nicht bekommen konnte, das Problem lösen würde. Also, wenn ich MediaRecorder instantiieren würde, sollte ich readAudio definieren, richtig? – 4javier