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) :
- Go to tab 2, it appears a new window with 3 different link
- Go to link 1: it appears another window with 6 links
- 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.