1
votes

I have an iOS application in Titanium and now I want to create the Android version.

My problem is that in Android I have a lot of memory problems and performance problems.

The application consists on a Tabgroup with three tabs. In each Tab there are buttons (and also images and information) that allow you to go to another subwindow. I could be even 3 or 4 levels of subwindows. It also has four databases with a lot of data.

On iOS I use: self.containingTab.open(new AddWindow); every time I want to go to another level and it allows you to navigate backward to the previous window. On Android I can also go back to previous window when hardware back button is pressed but I have a lot of out of memory errors.

Could it be because I open new windows and old windows are still there consuming memory? What's the best way to manage a tabgroup with several tabs and where each tab allow you to go to different subwindows?

I've tried instead of creating a window, create a view and add to the old window, but then I can't go backward to previous view although I manage it by myself.

Is there a better way to do it?

Thank you very much!

UPDATE

Here are the errors I received:

First I have some:

Unable to load bitmap. Not enough memory: Failed to allocate a
10731532 byte allocation with 9611988 free bytes and 9MB until OOM

Then, some:

Throwing OutOfMemoryError "Failed to allocate a 10731532 byte
allocation with 5437592 free bytes and 5MB until OOM"

But application still works.

Until I received:

03-16 13:56:19.951: E/art(18624): Throwing OutOfMemoryError "Failed to allocate a 344 byte allocation with 300 free bytes and 300B until OOM" (recursive case)
03-16 13:56:19.983: E/art(18624): "main" prio=5 tid=1 Runnable
03-16 13:56:19.983: E/art(18624):   | group="main" sCount=0 dsCount=0 obj=0x740d0000 self=0xb8d93800
03-16 13:56:19.983: E/art(18624):   | sysTid=18624 nice=0 cgrp=apps sched=0/0 handle=0xb6efcbec
03-16 13:56:19.983: E/art(18624):   | state=R schedstat=( 0 0 0 ) utm=6018 stm=7836 core=1 HZ=100
03-16 13:56:19.983: E/art(18624):   | stack=0xbe750000-0xbe752000 stackSize=8MB
03-16 13:56:19.983: E/art(18624):   | held mutexes= "mutator lock"(shared held)
03-16 13:56:19.983: E/art(18624):   native: #00 pc 00004f60  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
03-16 13:56:19.983: E/art(18624):   native: #01 pc 00003665  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
03-16 13:56:19.983: E/art(18624):   native: #02 pc 00256ad1  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
03-16 13:56:19.983: E/art(18624):   native: #03 pc 00238123  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+150)
03-16 13:56:19.983: E/art(18624):   native: #04 pc 0023b55b  /system/lib/libart.so (art::Thread::ThrowOutOfMemoryError(char const*)+274)
03-16 13:56:19.983: E/art(18624):   native: #05 pc 00145a49  /system/lib/libart.so (art::gc::Heap::ThrowOutOfMemoryError(art::Thread*, unsigned int, art::gc::AllocatorType)+832)
03-16 13:56:19.983: E/art(18624):   native: #06 pc 00147a09  /system/lib/libart.so (art::gc::Heap::AllocateInternalWithGc(art::Thread*, art::gc::AllocatorType, unsigned int, unsigned int*, unsigned int*, art::mirror::Class**)+668)
03-16 13:56:19.983: E/art(18624):   native: #07 pc 0023b9c3  /system/lib/libart.so (art::mirror::Array* art::mirror::Array::Alloc<true>(art::Thread*, art::mirror::Class*, int, unsigned int, art::gc::AllocatorType, bool) (.constprop.210)+898)
03-16 13:56:19.983: E/art(18624):   native: #08 pc 0023bf07  /system/lib/libart.so (_jobject* art::Thread::CreateInternalStackTrace<false>(art::ScopedObjectAccessAlreadyRunnable const&) const+230)
03-16 13:56:19.983: E/art(18624):   native: #09 pc 0020c7cf  /system/lib/libart.so (art::Throwable_nativeFillInStackTrace(_JNIEnv*, _jclass*)+22)
03-16 13:56:19.983: E/art(18624):   native: #10 pc 00000c15  /system/framework/arm/boot.oat (Java_java_lang_Throwable_nativeFillInStackTrace__+80)
03-16 13:56:19.983: E/art(18624):   at java.lang.Throwable.nativeFillInStackTrace!(Native method)
03-16 13:56:19.983: E/art(18624):   at java.lang.Throwable.fillInStackTrace(Throwable.java:166)
03-16 13:56:19.983: E/art(18624):   at java.lang.Throwable.<init>(Throwable.java:95)
03-16 13:56:19.983: E/art(18624):   at java.lang.Error.<init>(Error.java:48)
03-16 13:56:19.983: E/art(18624):   at java.lang.VirtualMachineError.<init>(VirtualMachineError.java:46)
03-16 13:56:19.983: E/art(18624):   at java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:44)
03-16 13:56:19.983: E/art(18624):   at dalvik.system.VMRuntime.newNonMovableArray!(Native method)
03-16 13:56:19.983: E/art(18624):   at android.graphics.Bitmap.nativeCreate(Native method)
03-16 13:56:19.983: E/art(18624):   at android.graphics.Bitmap.createBitmap(Bitmap.java:838)
03-16 13:56:19.983: E/art(18624):   at android.graphics.Bitmap.createBitmap(Bitmap.java:798)
03-16 13:56:19.983: E/art(18624):   at android.view.View.buildDrawingCacheImpl(View.java:14425)
03-16 13:56:19.983: E/art(18624):   at android.view.View.buildDrawingCache(View.java:14357)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14949)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:15252)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:15158)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:15252)
03-16 13:56:19.983: E/art(18624):   at android.widget.FrameLayout.draw(FrameLayout.java:598)
03-16 13:56:19.983: E/art(18624):   at android.view.View.buildDrawingCacheImpl(View.java:14495)
03-16 13:56:19.983: E/art(18624):   at android.view.View.buildDrawingCache(View.java:14357)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14166)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:15252)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14185)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.983: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.983: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.983: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.983: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14180)
03-16 13:56:19.984: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.984: E/art(18624):   at android.view.View.draw(View.java:14977)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewGroup.drawChild(ViewGroup.java:3407)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3200)
03-16 13:56:19.984: E/art(18624):   at android.view.View.draw(View.java:15252)
03-16 13:56:19.984: E/art(18624):   at android.widget.FrameLayout.draw(FrameLayout.java:598)
03-16 13:56:19.984: E/art(18624):   at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2650)
03-16 13:56:19.984: E/art(18624):   at android.view.View.updateDisplayListIfDirty(View.java:14185)
03-16 13:56:19.984: E/art(18624):   at android.view.View.getDisplayList(View.java:14207)
03-16 13:56:19.984: E/art(18624):   at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
03-16 13:56:19.984: E/art(18624):   at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
03-16 13:56:19.984: E/art(18624):   at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewRootImpl.draw(ViewRootImpl.java:2560)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2382)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2012)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1084)
03-16 13:56:19.984: E/art(18624):   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5990)
03-16 13:56:19.984: E/art(18624):   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
03-16 13:56:19.984: E/art(18624):   at android.view.Choreographer.doCallbacks(Choreographer.java:580)
03-16 13:56:19.984: E/art(18624):   at android.view.Choreographer.doFrame(Choreographer.java:550)
03-16 13:56:19.984: E/art(18624):   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
03-16 13:56:19.984: E/art(18624):   at android.os.Handler.handleCallback(Handler.java:739)
03-16 13:56:19.984: E/art(18624):   at android.os.Handler.dispatchMessage(Handler.java:95)
03-16 13:56:19.984: E/art(18624):   at android.os.Looper.loop(Looper.java:135)
03-16 13:56:19.984: E/art(18624):   at android.app.ActivityThread.main(ActivityThread.java:5343)
03-16 13:56:19.984: E/art(18624):   at java.lang.reflect.Method.invoke!(Native method)
03-16 13:56:19.984: E/art(18624):   at java.lang.reflect.Method.invoke(Method.java:372)
03-16 13:56:19.984: E/art(18624):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
03-16 13:56:19.984: E/art(18624):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

And application crash.

UPDATE

As the application is based on previous iOS application. It's really big and it's complex to try to put some code here. But I'm going to try to explain in which it consists:

First, it opens a tabgroup where I create four different tabs. It takes a long time until the application creates every tab.

  • 1 tab: It's a home tab and it contains links to the other tabs. Each link it's an image. I create the link as an ImageView. This window also contains a backgroundImage. (Is it better to put images inside ImageView or as backgroundImage? It affects to memory and performance?)

  • 2, 3 and 4 tabs: contains more links and many sub-levels. I'm going to explain the process I've followed to crash the application (each link consist in a view with backgroundcolor, a label and a button with brackgroundGradient) :

    1. Go to tab 2, it appears a new window with 3 different link
    2. Go to link 1: it appears another window with 6 links
    3. Go to link 1: it appears another window with two tablesView. One left (with 5 rows) and one right with around 20 rows. On right table each row has an image and two labels added to tableviewrow.
1
What you describe is perfectly fine, so in order to determine what is causing the memory and performance issues, you'll need to provide a bit more context (code, nature of the issues).Fokke Zandbergen
Thank you for your response. I've updated the question with the errors I receive. Is it possible to know where is the issue with these errors? It works OK on simulator, but it crash on a device. About the code, it's a little difficult because I have the iOS application as base and I try to modify it to make the Android app. Is it better to start a new project and add things step by step? And also, instead of creating so many Windows, is it better to create views and manage the back button by myself? Creating or destroying the view? Thanks again!A.Vila

1 Answers

3
votes

The issue seems to be with images, given the error:

Unable to load bitmap.

Please check the dimensions of the images you are using. Do you provide dpi specific variations so that on smaller devices you don't load too big images? And do you use nine-patch images where possible? Also be aware that in a TabGroup all primary level Windows are open at all times. If all of them have big images, you should use the (un)selected event of each tab to (un)load the images.