我想首先说这是我第一次处理性能,因为这是我第一次开发Android应用程序。
该应用程序是一个源代码编辑器,您可以在其中打开文件,修改它们并将其保存回来。该应用程序由4部分组成:
完成基本代码编辑器后,我转向语法高亮显示。现在,我想明确表示即使没有语法突出显示也会产生泄漏,所以这不是问题所在。
无论如何,通过测试语法highlithing,我打开“大”文件(1200行代码),我注意到应用程序变得非常慢,这是显而易见的,因为我正在整理整个文本(我会避免这个通过仅突出显示可见文本)。这促使我测试应用程序没有语法高度大文件,我发现应用程序变得有点慢,我发现一些内存泄漏发生。
特别是,当我打开一个大文件(1200行代码)时,应用程序需要1秒钟才能在textview中显示代码行,当我输入字符的图形时速度很慢。另外,每当我键入删除字符时,就会发生内存泄漏。
我试图检查堆(使用MAT),但正如我所说,我没有任何经验,我不知道如何调查这个问题。对不起,我无法上传截图(没有stackoverflow的权限),但我可以报告一些数字:
问题1
详细说明:
问题2
问题3
问题1 : 细节:
问题2 :
问题3问题4
从Android设备监视器:
分配的某些部分:
提前谢谢
编辑:
<?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>
修改
好的,我发现了这个问题。如果你看到,每次输入内容时,我都会更新EditText行,因为文本很长(1200行),所以需要一段时间来重新计算它。事情虽然关于那个!我必须找到一种更快的方式来显示代码行。一种选择是为每一行使用一个TextView,这样我只更新需要更改的TextView。但我不知道1200个TextView对象是不是很好。
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 by 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 THIS 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 i = 2; i 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); } }
编辑: 除了最近的发现之外,没有语法突出显示输入很快,但是在启用语法高亮时我仍然遇到延迟。当我打开文件时,突出显示非常快,但输入仍然很慢并且内存泄漏消息
04-28 04:49:58.119:D / dalvikvm(2437):GC_EXPLICIT释放185K,17%免费6027K / 7244K,暂停1ms + 1ms,总计5ms
出现。无论如何,我想知道对象1字节数组(byte [],boolean [])是什么,因为它实际上使用2 MB。有什么建议吗?
编辑:
绝对找到了问题所在。由于文件很大并且创建了很多跨度,当我在文件顶部更改某些内容时,editext必须重新计算所有跨度的位置。
答案 0 :(得分:3)
许多其他人面临同样的问题。以下是一些提示:
来自codeninja:
那么实际的解决方案是什么?避免在里面使用EditText RelativeLayout,改为使用LinearLayout。据詹姆斯说,如果你 看看DDMS,会发生很多重绘和重新计算 输入与RelativeLayout相关的文本。以便 给我们一个线索,问题确实是RelativeLayoutUpdate:I 忘了提一下用EditText设置一个固定的东西会有帮助 很多表现。它可以防止重新计算和重新绘制 布局。感谢Giorgos Kylafas在评论中指出了这一点 以下部分!他还包括可能对您有用的链接 它涉及Android性能提示,所以我建议阅读他的评论。
在第一种情况下,EditText的宽度为&#34; wrap_content&#34;。每次你 更改文本,即EditText的内容,视图需要重新测量 并重新布局,这很慢。被包含在内 RelativeLayout让事情变得更糟,因为RelativeLayout是 总是多次通过。
在第二种情况下,EditText的宽度固定为&#34; 220 dip&#34;。它的 测量和布局通过简单快捷。另外,你没有使用 &#34; layout_weight&#34;,所以它的父LinearLayout是单遍的。 http://developer.android.com/guide/topics/ui/how-android-draws.html
来自另一个stackoverflow question:
避免在RelativeLayout中使用EditText,请使用LinearLayout 代替。
来自另一个stackoverflow question:
我在ListView中使用EditText时遇到了类似的问题 通过使用加权宽度将EditText宽度更改为0dp来修复 匹配/填充父母。
我不确定为什么会这样,但我相信它是 因为当EditText的宽度设置为包装内容时,它将 调整/重绘自身,以便一切都适合,ListView将 也试图重绘自己所以一切都适合。所以通过制作 EditText具有固定的宽度,不再需要重绘。
总之:务必不要将EditText的宽度设置为wrap-content!