首先我想说,这是我第一次处理性能问题,因为这是我第一次开发安卓应用程序。
应用程序
该应用程序是一个源代码编辑器,您可以在其中打开文件,修改它们并将其保存回来。该应用程序由4部分组成:
- 导航视图:包含ListView用于打开文件和TreeView用于打开文件夹。
- 代码视图容器:这个视图包含实际代码的视图。
- 代码容器:这是一个小视图,包含一个文本视图和一个自定义EditText(由我扩展EditText类创建,但尚未实现,因此它的行为与EditText完全相同)。 TextView只显示代码行。
- 打开和保存片段:有两个我用作DialogFragment的片段:保存片段让您浏览本地文件系统以及链接帐户的Dropbox文件系统,并保存当前文件。打开片段让您浏览相同的文件系统并打开文件。
问题
在完成了基本代码编辑器之后,我开始进行语法高亮。现在,我想澄清,即使没有语法高亮,也会生成泄漏,因此这不是问题。
无论如何,通过测试语法高亮,我打开了“大”文件(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;
/** * 代码编辑视图 */ 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); }
/** * 初始化方法 * @param 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 <= usedLines; i++) { text += i + System.lineSeparator(); }
lines.setText(text); }
/** * 设置字体 * @param typeFace 字体 */ public void setFont(Typeface typeFace) { this.lines.setTypeface(typeFace); this.code.setTypeface(typeFace); } }
编辑: 除了最近发现的,没有语法高亮时打字速度很快之外,启用语法高亮后我仍然遇到了卡顿。当我打开文件时,高亮非常快,但打字仍然很慢,而且会出现内存泄漏的消息。
04-28 04:49:58.119: D/dalvikvm(2437): GC_EXPLICIT freed 185K, 17% free 6027K/7244K, paused 1ms+1ms, total 5ms
出现了垃圾回收。其中,“GC_EXPLICIT”表示手动启动的垃圾回收,“freed 185K”表示释放了185KB的内存,“17% free 6027K/7244K”表示总共有7244KB的内存,其中6027KB是可用的。
不过我想知道这个1字节数组(byte[],boolean[])是什么东西,因为它实际上使用了2MB的内存。你有什么建议吗?
编辑:
终于找到问题所在。由于文件很大并且创建了很多段落,当我在文件顶部进行更改时,编辑框必须重新计算所有段落的位置。