I recreate mediaplayer each track with release and new. But how recreate visualizer? When i call release and creating new visualizer then i have new thread visualizer because old thread don't finalized automatically. If i don't recreating visualizer then his have wrong AudioSessionId. How use visualizer??? With mediaplayer if mediaplayer do recreate each track??
Some code for example (from my big app):
public class VisualizerView extends View {
private static final String TAG = "VisualizerView";
private byte[] mBytes;
private byte[] mFFTBytes;
private Rect mRect = new Rect();
private static Visualizer mVisualizer;
private static Set<Renderer> mRenderers;
private Paint mFlashPaint = new Paint();
private Paint mFadePaint = new Paint();
public VisualizerView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs);
init();
}
public void link(MediaPlayer player)
{
if(player == null)
{
throw new NullPointerException("Cannot link to null MediaPlayer");
}
// Pass through Visualizer data to VisualizerView
Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
{
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizer(bytes);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizerFFT(bytes);
}
};
// Create the Visualizer object and attach it to our media player.
if (mVisualizer==null) {
mVisualizer = new Visualizer(player.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
mVisualizer.setDataCaptureListener(captureListener, Visualizer.getMaxCaptureRate() / 2, true, true);
// Enabled Visualizer and disable when we're done with the stream
mVisualizer.setEnabled(true);
addBarGraphRenderers();
} else {
mVisualizer.setDataCaptureListener(captureListener,
Visualizer.getMaxCaptureRate() , true, true);
mVisualizer.setEnabled(true);
}}
Upd1: I'am rewrite visualizer for call finalize, but this not help me:
public class visualizer1 extends Visualizer {
public visualizer1(int audioSession) throws UnsupportedOperationException,
RuntimeException {
super(audioSession);
}
@Override
public void finalize() {
super.finalize();
}
}
public void release() {
if (mVisualizer!=null) {
mVisualizer.release();
mVisualizer.finalize();
mVisualizer=null;
}
}
And i have many visualizers:
solved this problem. When i set mVisualizer.setEnabled(false); before release visualizer finalize automatically:
public void release()
{
if (mVisualizer!=null) {
mVisualizer.setEnabled(false);
mVisualizer.release();
mVisualizer=null;
}
}
UPD: I tested my code for a very long time (about a year) and found out that if I did, then very rarely the application crashes with a fatal error on the line "mVisualizer.release ();". This can not be tracked using libraries, like crashlytics. So I removed "mVisualizer.setEnabled (false);". In Android 7.0, I have a maximum of 3-4 Visualizer threads and this does not cause a memory leak.
UPD2: I found the reason for the crash application. The problem is that the mVisualizer.release () command; Sometimes it was executed at the time of visualization rendering. I added a boolean variable to avoid this and now the crash is gone. Enjoy!
private boolean release = false;
public void release() {
if (mVisualizer != null) {
if (cameraLed == true) {
barGraphRendererBottom.stopCamera();
}
if (isShown())
release = true;
else {
release = false;
mVisualizer.setEnabled(false);
mVisualizer.release();
mVisualizer = null;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (release) {
release = false;
mVisualizer.setEnabled(false);
mVisualizer.release();
mVisualizer = null;
} else {
mRect.set(0, 0, getWidth(), getHeight());
if (mCanvasBitmap == null) {
mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(),
canvas.getHeight(), Config.RGB_565);
}
if (mCanvas == null) {
mCanvas = new Canvas(mCanvasBitmap);
}
canvas.drawBitmap(mCanvasBitmap, new Matrix(), null);
}
}