gpt4 book ai didi

java - Android:EditText导致内存泄漏

转载 作者:行者123 更新时间:2023-12-01 19:16:31 24 4
gpt4 key购买 nike

我首先要说的是,这是我第一次要处理性能问题,因为这是我第一次开发android应用程序。
该应用程序
该应用程序是一个源代码编辑器,您可以在其中打开文件,对其进行修改并将其保存回去。该应用程序包含4个部分:

  • 导航器 View :包含一个用于打开文件的ListView和一个用于打开文件夹的TreeView。
  • 代码 View 容器:该容器包含包含实际代码的 View 。
  • 代码容器:这是一个包含文本 View 和自定义EditText的小 View (由我扩展EditText类创建,但尚未实现,因此其行为完全类似于EditText)。 TextView只是显示代码行。
  • 打开和保存片段:我有2个片段用作DialogFragment:save片段可让您浏览链接帐户的本地文件系统以及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对象是否不错。
    包com.example.green.bachelorproject.customViews.codeEditView;

    导入android.content.Context;
    导入android.graphics.Color;
    导入android.graphics.Typeface;
    导入android.text.Editable;
    导入android.text.Spannable;
    导入android.text.SpannableStringBuilder;
    导入android.text.TextWatcher;
    导入android.text.style.ForegroundColorSpan;
    导入android.util.AttributeSet;
    导入android.util.Log;
    导入android.view.LayoutInflater;
    导入android.widget.EditText;
    导入android.widget.LinearLayout;
    导入android.widget.TextView;

    导入utils.Colorizer;
    导入utils.Lexer;
    导入com.example.green.bachelorproject.events.UpdateCacheFileEvent;
    导入com.example.green.bachelorproject.R;

    导入de.greenrobot.event.EventBus;
    导入com.example.green.bachelorproject.internalFileSystem.InternalFile;

    导入java.util.ArrayList;

    /**
    *由格林于2015年2月26日创建。
    */
    公共(public)类CodeEditView扩展LinearLayout {

    私有(private)上下文上下文;
    专用的TextView行;
    私有(private)EditText代码;
    专用字型currentTypeface;
    私有(private)InternalFile internalFile;
    私有(private)Lexer词法分析器;
    专用Colorizer着色剂;

    公共(public)CodeEditView(上下文上下文){
    super (上下文);
    this.context =上下文;
    init(null);
    }

    public CodeEditView(Context context,AttributeSet attrs){
    super (上下文,attrs);
    this.context =上下文;
    init(attrs);
    }

    私有(private)无效init(AttributeSet attrs){
    //检查此
    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)无效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)无效setLines(){
    int usedLines = code.getLineCount();

    字符串文本=“1” + System.lineSeparator();

    for(int i = 2; i token = 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)无效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必须重新计算所有跨度的位置。

    最佳答案

    许多其他人也面临着同样的问题。这里有一些提示:

    来自codeninja:

    So what’s the actual solution? Avoid using EditText inside a RelativeLayout, use LinearLayout instead. According to James, If you look at the DDMS, a lot of redraws and recalculations occur while entering the text which is related to the RelativeLayout. So that gives us a clue the the problem is indeed the RelativeLayoutUpdate: I forgot to mention that setting a fixed with of an EditText will help a lot with the performance. It prevents re-calculation and re-drawing of layout. Thanks to Giorgos Kylafas for pointing it out in the comments section below! He also included links that can be useful for you when it comes to Android performance tips so I suggest reading his comment.

    In the first case, EditText's width is "wrap_content". Everytime you change the text, i.e. EditText's content, the view needs to re-measure and re-layout, which is slow. Being contained insided a RelativeLayout makes things even worse, because RelativeLayout is always multi-pass.

    In the second case, EditText's width is fixed to "220 dip". Its measuring and layout pass is simple and quick. Plus you use no "layout_weight", so its parent LinearLayout is single-pass. http://developer.android.com/guide/topics/ui/how-android-draws.html



    从另一个stackoverflow question:

    Avoid using EditText inside a RelativeLayout, use LinearLayout instead.



    从另一个stackoverflow question:

    I was having a similar issue using EditText inside a ListView, that was fixed by changing the EditText width to 0dp using weighted widths to match/fill the parent.

    I don't know for sure why this was occurring, however I believe it is because when the width of the EditText is set to wrap content it will adjust/redraw itself so that everything fits, and the ListView will also attempt to redraw itself so everything fits. So by making the EditText have a fixed width, this redraw is no longer required.



    结论:请确保不要将EditText的宽度设置为wrap-content!

    关于java - Android:EditText导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29905861/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com