我目前正在开发一个 Android 应用程序,但由于“内存不足”等问题而无法结束它,我认为我的代码中有两部分可能导致泄漏。
首先:应用程序必须同时播放 12 个音调(10 个不同的频率)。我在 Stack Overflow 上找到了一段代码,它允许我同时播放频率列表:(我认为这是由 AudioTrack 引起的,但我不知道如何解决)
public static void runList(final List<Double> freq) { if(audioTrack!=null){ audioTrack.release(); audioTrack=null; } final List<AudioTrack> audioTrackList = new ArrayList(); final AudioTrack audioTrack0; final AudioTrack audioTrack1; genTone(freq.get(0)); audioTrack0 = new AudioTrack(AudioManager.STREAM_MUSIC, (int) sampleRate, AudioFormat.CHANNEL_OUT_DEFAULT,AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STREAM); audioTrack0.play(); audioTrack0.write(generatedSnd, 0, generatedSnd.length); genTone(freq.get(1)); audioTrack1 = new AudioTrack(AudioManager.STREAM_MUSIC, (int) sampleRate, AudioFormat.CHANNEL_OUT_DEFAULT,AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STREAM); audioTrack1.play(); audioTrack1.write(generatedSnd, 0, generatedSnd.length); handler.postDelayed(new Runnable() { @Override public void run() { //compteur : not more than 2 AudioTrack audioTrack0.release(); audioTrack1.release(); } }, 1000); }
(有了这个我只能同时播放2个音调)
然后:在同一个 Activity 中,应用程序必须在屏幕上显示 10 个 ImageView ,每个 View 都以不同的方式移动。所有这些 ImageView 之前都已从位图解码。我认为泄漏是从这里开始的。我尝试在使用位图后释放它,但无能为力,我只能在崩溃(内存不足)之前显示在屏幕上移动的 3 或 4 个图像。也许有一种更好、更轻松的方法来对图像进行动画处理,例如,对图像进行动画处理并使其遵循三角形方式,我使用这个:
private void triangleAnim(final ImageView patternImage, final int bpm, final int i, final double frequency) { resetN(); int randomLeft = (int)(Math.random() * (maxRandomLeft-minRandomLeft)) + minRandomLeft; int randomTop = (int)(Math.random() * (maxRandomTop-minRandomTop)) + minRandomTop; final Animation anim = new TranslateAnimation(randomLeft, randomLeft + 300,randomTop,randomTop + 300 ); anim.setDuration(60000/bpm); final Animation anim2 = new TranslateAnimation(randomLeft +300, randomLeft-300, randomTop+300, randomTop+300 ); anim2.setDuration(60000/bpm); final Animation anim3 = new TranslateAnimation(randomLeft-300, randomLeft, randomTop+300, randomTop ); anim3.setDuration(60000/bpm); su = new SoundUtils(); su.setDuration(60000/bpm); patternImage.startAnimation(anim); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationEnd(Animation animation) { patternImage.startAnimation(anim2); ; } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } }); anim2.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationEnd(Animation animation) { patternImage.startAnimation(anim3); ; incrementN(); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } }); anim3.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationEnd(Animation animation) { if(n <= i){ patternImage.startAnimation(anim); } } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } }); }
最后,是否有任何软件或代码或其他任何东西可以帮助我找到我的应用程序内存泄漏的位置?如果需要,我可以将 LogCat 中的错误链接给您。
抱歉我的英语不好,希望没有太多错误。
更新:
这是我的日志猫:
07-31 17:54:03.931: E/AndroidRuntime(15181): java.lang.OutOfMemoryError
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.graphics.Bitmap.nativeCreate(Native Method)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.graphics.Bitmap.createBitmap(Bitmap.java:903)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.graphics.Bitmap.createBitmap(Bitmap.java:880)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.graphics.Bitmap.createBitmap(Bitmap.java:847)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.CameraBridgeViewBase.AllocateCache(CameraBridgeViewBase.java:451)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.JavaCameraView.initializeCamera(JavaCameraView.java:184)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.JavaCameraView.connectCamera(JavaCameraView.java:239)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.CameraBridgeViewBase.onEnterStartedState(CameraBridgeViewBase.java:355)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.CameraBridgeViewBase.processEnterState(CameraBridgeViewBase.java:318)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.CameraBridgeViewBase.checkCurrentState(CameraBridgeViewBase.java:311)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.CameraBridgeViewBase.enableView(CameraBridgeViewBase.java:228)
07-31 17:54:03.931: E/AndroidRuntime(15181): at ui.fragment.TakePictureFragment$1.onManagerConnected(TakePictureFragment.java:71)
07-31 17:54:03.931: E/AndroidRuntime(15181): at org.opencv.android.AsyncServiceHelper$1.onServiceConnected(AsyncServiceHelper.java:318)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1119)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1136)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.os.Handler.handleCallback(Handler.java:733)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.os.Handler.dispatchMessage(Handler.java:95)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.os.Looper.loop(Looper.java:157)
07-31 17:54:03.931: E/AndroidRuntime(15181): at android.app.ActivityThread.main(ActivityThread.java:5356)
07-31 17:54:03.931: E/AndroidRuntime(15181): at java.lang.reflect.Method.invokeNative(Native Method)
07-31 17:54:03.931: E/AndroidRuntime(15181): at java.lang.reflect.Method.invoke(Method.java:515)
07-31 17:54:03.931: E/AndroidRuntime(15181): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-31 17:54:03.931: E/AndroidRuntime(15181): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-31 17:54:03.931: E/AndroidRuntime(15181): at dalvik.system.NativeStart.main(Native Method)
为了解码位图,我使用这个:
private Bitmap decodeFile(File f){
try {
//decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE=70;
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
scale++;
}
//decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
最佳答案
只是一个简单的想法:确保关闭您的InputStream,BitmapFactory.decodeStream();
在源代码中似乎没有这样做
关于java - 内存泄漏与优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25063053/