ShowCaseView 内存不足错误
ShowCaseView Out of Memory Error
我在使用 Galaxy S 系列时遇到一些问题,展示视图在任何其他设备上都可以正常工作,但我在 Galaxy S 设备上遇到以下错误。
java.lang.OutOfMemoryError: Failed to allocate a 5760012 byte allocation with 3573238 free bytes and 3MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java) at android.graphics.BitmapFactory.nativeDecodeAsset(BitmapFactory.java)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1014)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:3747)
at android.content.res.Resources.loadDrawable(Resources.java:3620) at android.content.res.Resources.getDrawable(Resources.java:1852) at android.support.v4.content.res.ResourcesCompatApi21.getDrawable(ResourcesCompatApi21.java)
at android.support.v4.content.res.ResourcesCompat.getDrawable(ResourcesCompat.java)
at com.github.amlcurran.showcaseview.StandardShowcaseDrawer.(StandardShowcaseDrawer.java)
at com.github.amlcurran.showcaseview.ShowcaseView.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView$Builder.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView$Builder.(ShowcaseView.java)
at br.com.mygas.myapplication.MainActivity.showcase(MainActivity.java)
at br.com.mygas.myapplication.MainActivity.access0(MainActivity.java)
at br.com.mygas.myapplication.MainActivity.onShowcaseViewDidHide(MainActivity.java)
at com.github.amlcurran.showcaseview.ShowcaseView.onAnimationEnd(ShowcaseView.java)
at com.github.amlcurran.showcaseview.AnimatorAnimationFactory.onAnimationEnd(AnimatorAnimationFactory.java)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1089)
at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:666)
at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
at android.view.Choreographer.doCallbacks(Choreographer.java:590) at
android.view.Choreographer.doFrame(Choreographer.java:559) at
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
at android.os.Handler.handleCallback(Handler.java:739) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:145) at
android.app.ActivityThread.main(ActivityThread.java:5942) at
java.lang.reflect.Method.invoke(Method.java) at
java.lang.reflect.Method.invoke(Method.java:372) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
这是产生上述错误的实现代码:
private void showcase() {
if (SaveSharedPreference.isMainActivity(this)) {
switch (counter) {
case 0:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setContentTitle("Esta é a tela inicial:")
.setStyle(R.style.CustomShowcaseThemeNext)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 1:
new ShowcaseView.Builder(this)
.setContentTitle("Selecione o tipo de combustível:")
.setTarget(new ViewTarget(R.id.spinner, this))
.setShowcaseDrawer(new CustomShowcaseView(this, findViewById(R.id.spinner).getWidth(), findViewById(R.id.spinner).getHeight()))
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 2:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setTarget(new ViewTarget(R.id.fab2, this))
.setContentTitle("Clique neste botão para procurar combustível ao redor:")
.setStyle(R.style.CustomShowcaseThemeNext)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 3:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setTarget(new ViewTarget(R.id.fab2, this))
.setContentTitle("Lembre-se:")
.setContentText("É necessário estar com o GPS ligado")
.setStyle(R.style.CustomShowcaseTheme2)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
SaveSharedPreference.mainActivityFirst(this);
break;
}
}
}
我不知道错误是从哪里来的,所以正在寻找任何建议。
OutOfMemoryError 是 android 中最常见的问题,尤其是在处理位图时。当由于内存不足 space 而无法分配对象时,Java 虚拟机 (JVM) 会抛出此错误,而且垃圾收集器无法释放一些 space.
磁盘上文件的大小不一定与内存中文件的大小一致。文件很可能是压缩的,解码时不会压缩。您需要在计算中考虑到这一点。
how to load bitmaps efficiently?
可以参考这篇文章
How to load large bitmaps efficiently?
虽然使用不是一个好主意android:largeHeap="true"
这里是google的摘录来解释它,
However, the ability to request a large heap is intended only for a
small set of apps that can justify the need to consume more RAM (such
as a large photo editing app). Never request a large heap simply
because you've run out of memory and you need a quick fix—you should
use it only when you know exactly where all your memory is being
allocated and why it must be retained. Yet, even when you're confident
your app can justify the large heap, you should avoid requesting it to
whatever extent possible. Using the extra memory will increasingly be
to the detriment of the overall user experience because garbage
collection will take longer and system performance may be slower when
task switching or performing other common operations.
这是完整的 link 文档
https://developer.android.com/training/articles/memory.html
但是,您可以尝试在 andriod 清单文件和 运行 中进行设置。
问题已解决,更改方法 hide from ShowcaseView.java
来自:
@Override
public void hide() {
// If the type is set to one-shot, store that it has shot
shotStateStore.storeShot();
mEventListener.onShowcaseViewHide(this);
fadeOutShowcase();
}
为此:
@Override
public void hide() {
// If the type is set to one-shot, store that it has shot
clearBitmap();
shotStateStore.storeShot();
mEventListener.onShowcaseViewHide(this);
fadeOutShowcase();
}
我在使用 Galaxy S 系列时遇到一些问题,展示视图在任何其他设备上都可以正常工作,但我在 Galaxy S 设备上遇到以下错误。
java.lang.OutOfMemoryError: Failed to allocate a 5760012 byte allocation with 3573238 free bytes and 3MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java) at android.graphics.BitmapFactory.nativeDecodeAsset(BitmapFactory.java)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:726)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:547)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1014)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:3747)
at android.content.res.Resources.loadDrawable(Resources.java:3620) at android.content.res.Resources.getDrawable(Resources.java:1852) at android.support.v4.content.res.ResourcesCompatApi21.getDrawable(ResourcesCompatApi21.java)
at android.support.v4.content.res.ResourcesCompat.getDrawable(ResourcesCompat.java)
at com.github.amlcurran.showcaseview.StandardShowcaseDrawer.(StandardShowcaseDrawer.java)
at com.github.amlcurran.showcaseview.ShowcaseView.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView$Builder.(ShowcaseView.java)
at com.github.amlcurran.showcaseview.ShowcaseView$Builder.(ShowcaseView.java)
at br.com.mygas.myapplication.MainActivity.showcase(MainActivity.java)
at br.com.mygas.myapplication.MainActivity.access0(MainActivity.java)
at br.com.mygas.myapplication.MainActivity.onShowcaseViewDidHide(MainActivity.java)
at com.github.amlcurran.showcaseview.ShowcaseView.onAnimationEnd(ShowcaseView.java)
at com.github.amlcurran.showcaseview.AnimatorAnimationFactory.onAnimationEnd(AnimatorAnimationFactory.java)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1089)
at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:666)
at android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
at android.view.Choreographer.doCallbacks(Choreographer.java:590) at
android.view.Choreographer.doFrame(Choreographer.java:559) at
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
at android.os.Handler.handleCallback(Handler.java:739) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:145) at
android.app.ActivityThread.main(ActivityThread.java:5942) at
java.lang.reflect.Method.invoke(Method.java) at
java.lang.reflect.Method.invoke(Method.java:372) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
这是产生上述错误的实现代码:
private void showcase() {
if (SaveSharedPreference.isMainActivity(this)) {
switch (counter) {
case 0:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setContentTitle("Esta é a tela inicial:")
.setStyle(R.style.CustomShowcaseThemeNext)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 1:
new ShowcaseView.Builder(this)
.setContentTitle("Selecione o tipo de combustível:")
.setTarget(new ViewTarget(R.id.spinner, this))
.setShowcaseDrawer(new CustomShowcaseView(this, findViewById(R.id.spinner).getWidth(), findViewById(R.id.spinner).getHeight()))
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 2:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setTarget(new ViewTarget(R.id.fab2, this))
.setContentTitle("Clique neste botão para procurar combustível ao redor:")
.setStyle(R.style.CustomShowcaseThemeNext)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
break;
case 3:
new ShowcaseView.Builder(this)
.withMaterialShowcase()
.setTarget(new ViewTarget(R.id.fab2, this))
.setContentTitle("Lembre-se:")
.setContentText("É necessário estar com o GPS ligado")
.setStyle(R.style.CustomShowcaseTheme2)
.setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
counter++;
showcase();
}
})
.build();
SaveSharedPreference.mainActivityFirst(this);
break;
}
}
}
我不知道错误是从哪里来的,所以正在寻找任何建议。
OutOfMemoryError 是 android 中最常见的问题,尤其是在处理位图时。当由于内存不足 space 而无法分配对象时,Java 虚拟机 (JVM) 会抛出此错误,而且垃圾收集器无法释放一些 space.
磁盘上文件的大小不一定与内存中文件的大小一致。文件很可能是压缩的,解码时不会压缩。您需要在计算中考虑到这一点。
how to load bitmaps efficiently?
可以参考这篇文章
How to load large bitmaps efficiently?
虽然使用不是一个好主意android:largeHeap="true"
这里是google的摘录来解释它,
However, the ability to request a large heap is intended only for a small set of apps that can justify the need to consume more RAM (such as a large photo editing app). Never request a large heap simply because you've run out of memory and you need a quick fix—you should use it only when you know exactly where all your memory is being allocated and why it must be retained. Yet, even when you're confident your app can justify the large heap, you should avoid requesting it to whatever extent possible. Using the extra memory will increasingly be to the detriment of the overall user experience because garbage collection will take longer and system performance may be slower when task switching or performing other common operations.
这是完整的 link 文档 https://developer.android.com/training/articles/memory.html
但是,您可以尝试在 andriod 清单文件和 运行 中进行设置。
问题已解决,更改方法 hide from ShowcaseView.java 来自:
@Override
public void hide() {
// If the type is set to one-shot, store that it has shot
shotStateStore.storeShot();
mEventListener.onShowcaseViewHide(this);
fadeOutShowcase();
}
为此:
@Override
public void hide() {
// If the type is set to one-shot, store that it has shot
clearBitmap();
shotStateStore.storeShot();
mEventListener.onShowcaseViewHide(this);
fadeOutShowcase();
}