i want start saying it's first time have deal performance, because it's first time develop android app.
the app
the app source code editor, can open files, modify them , save them back. app consist of 4 parts:
- the navigator view: contains listview open files , treeview open folders.
- the code views container: hold views containing actual code.
- the code container: little view containing text view , custom edittext (created me extending edittext class, not implements yet, behave edittext). textview showing lines of code.
- the open , save fragments: there 2 fragments use dialogfragment: save fragment let navigate local file system dropbox file system of linked accounts , save current file. open fragment let navigate same file systems , open file.
the problem
after finished base code editor, moved syntax highlighting. now, want mke clear leaks generated without syntax highlighting, not problem.
anyway, testing syntax highlithing, opening "large" files (1200 lines of code) , noticed app becomes extremly slow, obvious because i'm regexing whole text (i avoid highlight visible text). push me test app without syntax highlithing large files , found app become still bit slow , noticed memory leaks happened.
in particular, when open large file (1200 lines of code) app take 1 second display lines of code in textview , when type drawing of character slow. in addition whenever type of remove character memory leak happen.
the inspection
i tried inspect heap (with mat), said don't have experience in , i'm not sure investigate problem. i'm sorry cannot upload screenshots (don't have permission stackoverflow that), can report numbers:
system before opening large file
system overview
leaks suspects
problem 1
details:
problem 2
problem 3
biggest top-level dominator packages
biggest objects
system after opening large file
system overview
leaks suspects:
problem 1: details:
problem 2:
problem 3 problem 4
biggest top-level dominator packages
biggest objects
from android device monitor:
system before opening large file
system after opening large file
some parts of allocations:
thank in advance
edit:
<?xml version="1.0" encoding="utf-8"?> <scrollview xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/codescrollview" android:fillviewport="true"> <linearlayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <textview android:layout_width="wrap_content" android:layout_height="fill_parent" android:background="@drawable/lines_stroke" android:textcolor="@android:color/white" android:text="@string/first_line" android:textsize="15dp" android:gravity="right" android:paddingleft="15dp" android:paddingright="5dp" android:id="@+id/edit_code_lines_view"/> <com.example.green.bachelorproject.customviews.codeeditview.touchedittext android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/code_stroke" android:gravity="top" android:textcolor="@android:color/white" android:textsize="15dp" android:paddingleft="3dp" android:paddingright="3dp" android:textcursordrawable="@color/white" android:id="@+id/edit_code_content_view"/> </linearlayout> </scrollview>
edit
ok guys found problem. if see, every time type something, update lines edittext and, since text long (1200 lines), take while recompute it. did event though that! have find faster way show lines of code. 1 option use 1 textview each line, in way update textview need changed. don't know if having 1200 textview objects nice.
package com.example.green.bachelorproject.customviews.codeeditview; import android.content.context; import android.graphics.color; import android.graphics.typeface; import android.text.editable; import android.text.spannable; import android.text.spannablestringbuilder; import android.text.textwatcher; import android.text.style.foregroundcolorspan; import android.util.attributeset; import android.util.log; import android.view.layoutinflater; import android.widget.edittext; import android.widget.linearlayout; import android.widget.textview; import utils.colorizer; import utils.lexer; import com.example.green.bachelorproject.events.updatecachefileevent; import com.example.green.bachelorproject.r; import de.greenrobot.event.eventbus; import com.example.green.bachelorproject.internalfilesystem.internalfile; import java.util.arraylist; /** * created green on 26/02/15. */ public class codeeditview extends linearlayout { private context context; private textview lines; private edittext code; private typeface currenttypeface; private internalfile internalfile; private lexer lexer; private colorizer colorizer; public codeeditview(context context) { super(context); this.context = context; init(null); } public codeeditview(context context, attributeset attrs) { super(context, attrs); this.context = context; init(attrs); } private void init(attributeset attrs) { //check layoutinflater layoutinflater = (layoutinflater) this.context.getsystemservice(context.layout_inflater_service); layoutinflater.inflate(r.layout.edit_code_layout, this); // this.colorizer = new colorizer(); // this.colorizer.setcolor("string", color.rgb(218, 220, 95)); // this.colorizer.setcolor("number", color.rgb(173, 125, 255)); // this.colorizer.setcolor("character", color.rgb(218, 220, 95)); // this.colorizer.setcolor("operator", color.rgb(234, 38, 116)); // this.colorizer.setcolor("keyword", color.rgb(234, 38, 116)); // this.colorizer.setcolor("identifier", color.white); // this.colorizer.setcolor("type", color.rgb(105, 216, 238)); // this.colorizer.setcolor("comment", color.rgb(117, 113, 91)); this.lexer = new lexer(); this.lines = (textview) findviewbyid(r.id.edit_code_lines_view); //this.lines.settypeface(currenttypeface); this.code = (edittext) findviewbyid(r.id.edit_code_content_view); //this.code.settypeface(currenttypeface); this.code.addtextchangedlistener(new textwatcher() { @override public void beforetextchanged(charsequence s, int start, int count, int after) { } @override public void ontextchanged(charsequence s, int start, int before, int count) { } @override public void aftertextchanged(editable s) { // writetofile(); //eventbus.getdefault().post(new updatecachefileevent(code.gettext().tostring(), internalfile)); //setlines(); } }); } private void setlines() { int usedlines = code.getlinecount(); string text = "1" + system.lineseparator(); for(int = 2; tokens = lexer.tokenize(content); // spannablestringbuilder text = new spannablestringbuilder(content); // // for(lexer.token t: tokens) { // text.setspan(new foregroundcolorspan(colorizer.getcolor(t)), t.start, t.end, spannable.span_inclusive_inclusive); // } // code.settext(text); // code.post(new runnable() { // @override // public void run() { // setlines(); // } // }); } public void setfont(typeface typeface) { this.lines.settypeface(typeface); this.code.settypeface(typeface); } }
edit: beside recent discover, whithout syntax highlighting typing fast, still encounter lag when enabling syntax highlighting. when open file, highlight quick, typing still slow , memory leak messages
04-28 04:49:58.119: d/dalvikvm(2437): gc_explicit freed 185k, 17% free 6027k/7244k, paused 1ms+1ms, total 5ms
appear. anyway, i'm wondering object 1-byte array (byte[], boolean[]) is, because it's using 2 mb. suggestions?
edit:
definitely found problem. since file big , lot of spans created, when change on top of file, editext has recalculate position of spans.
many others faced same problem. here couple of hints:
from codeninja:
so what’s actual solution? avoid using edittext inside relativelayout, use linearlayout instead. according james, if @ ddms, lot of redraws , recalculations occur while entering text related relativelayout. gives clue the problem indeed relativelayoutupdate: forgot mention setting fixed of edittext lot performance. prevents re-calculation , re-drawing of layout. giorgos kylafas pointing out in comments section below! included links can useful when comes android performance tips suggest reading comment.
in first case, edittext's width "wrap_content". everytime change text, i.e. edittext's content, view needs re-measure , re-layout, slow. being contained insided relativelayout makes things worse, because relativelayout multi-pass.
in second case, edittext's width fixed "220 dip". measuring , layout pass simple , quick. plus use no "layout_weight", parent linearlayout single-pass. http://developer.android.com/guide/topics/ui/how-android-draws.html
from stackoverflow question:
avoid using edittext inside relativelayout, use linearlayout instead.
from stackoverflow question:
i having similar issue using edittext inside listview, fixed changing edittext width 0dp using weighted widths match/fill parent.
i don't know sure why occurring, believe because when width of edittext set wrap content adjust/redraw fits, , listview attempt redraw fits. making edittext have fixed width, redraw no longer required.
in conclusion: sure not set width of edittext wrap-content!