列表视图内存泄漏

2023-12-03

我有一个带有适配器的简单列表视图。 我动态创建了 10 多个列表视图项目。然后我一次又一次地上下滚动...... 我可以看到可用内存不断减少......

我需要在哪里免费以及什么? 注意 - 有一个图像视图 - 但在我的测试中我没有使用任何图像,所以它是 View.GONE。

另外 - 使用哪个工具可以分析 android 上的内存使用情况。我找到了 yourKit,但是如何为 android 配置它(我在设备上运行应用程序)/

活动类

package org.BJ.Food4All.Activities.NewRecipe;


import org.BJ.Food4All.R;
import org.BJ.Food4All.Recipe;
import org.BJ.Food4All.Recipe.Instruction;
import org.BJ.Food4All.Activities.RecipeBook.RecipeInstructionsListViewAdapter;
import org.BJ.Food4All.Activities.RecipeBook.SharedData;
import org.BJ.Food4All.utils.CameraUtil;
import org.BJ.Food4All.utils.ImageUploadItem;

import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.EditText;

public class Instructions extends ListActivity implements OnClickListener
{
    private final static String mTAG = "Instructions";
    private EditText mInstructionEditText = null;
    private RecipeInstructionsListViewAdapter mListViewAdapter = null;
    private Recipe mEditRecipe = PrivateResources.GetRecipe();

    private CameraUtil  mCameraUtil = new CameraUtil(this);

    private int mSelectedEntryIndex = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.new_recipe_instruction_tab);

        mInstructionEditText = (EditText)findViewById(R.id.newRecipeInstructionEditTextId);
        View addInstructionButton = findViewById(R.id.naddInstructionButtonId);

        // Sanity check
        if(mInstructionEditText == null || addInstructionButton == null)
        {
            Log.e(mTAG, "NULL pointers");
            // secure exit
            finish();
        }

        // Set up click listeners for all the buttons
        addInstructionButton.setOnClickListener(this);

        mListViewAdapter = new RecipeInstructionsListViewAdapter(this, R.layout.recipes_instruction_list_single_view_entry, mEditRecipe.GetInstructions());

        setListAdapter(mListViewAdapter);

        registerForContextMenu(getListView());
    }

    public void onClick(View v)
    {
        switch(v.getId())
        {
            case R.id.naddInstructionButtonId:
                AddInstructionToRecipe(v);
                break;

            default:
                Log.e(mTAG, "Invalid ID:" + v.getId());
                // secure exit
                finish();

        }
    }

    private void AddInstructionToRecipe(View v)
    {
        String instructionText = mInstructionEditText.getText().toString();

        if(instructionText == null)
        {
            return;
        }

        Instruction newInstruction = new Instruction(   mEditRecipe.GetInstructions().size() + 1,   // Index
                                                        instructionText,                            // The instruction
                                                        null,
                                                        true);

        if( mEditRecipe.AddInstruction(newInstruction) != true)
        {
            // TODO - ERROR
        }
        else
        {
            mListViewAdapter.notifyDataSetChanged();
        }
    }

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo)
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, 
                                    View v,
                                    ContextMenuInfo menuInfo) 
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.instructions_ctx_menu, menu);

        super.onCreateContextMenu(menu, v, menuInfo);
    }

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) 
    {
        super.onContextItemSelected(item);

        AdapterView.AdapterContextMenuInfo menuInfo;
        menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
        mSelectedEntryIndex = menuInfo.position;

        switch(item.getItemId()) 
        {
            case R.id.deleteId:
                mEditRecipe.RemoveInstruction(mSelectedEntryIndex);
                mListViewAdapter.notifyDataSetChanged();
                return true;

            case R.id.takePictureId:
                mCameraUtil.TakePicture();
                return true;
        }

        return false;
    }

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
     */
    @Override
    protected void onActivityResult(int requestCode, 
                                    int resultCode, 
                                    Intent data) 
    {
//      String imageLocation = mCameraUtil.onActivityResult(requestCode, resultCode, data);
        Bitmap imageBitmap = mCameraUtil.onActivityResult(requestCode, resultCode, data);
        // TODO - switch to parameter passed in the intent!!!! like TakePicture(index);
//      mEditRecipe.GetInstructions().get( mSelectedEntryIndex ).SetBitmap( imageBitmap ); //SetInstructionImageLocation(imageLocation);
        mSelectedEntryIndex = -1;

        // Update the listviewitem with the picture
        mListViewAdapter.notifyDataSetChanged();
    }
}

适配器类

package org.BJ.Food4All.Activities.RecipeBook;

import java.util.ArrayList;

import org.BJ.Food4All.R;
import org.BJ.Food4All.Recipe.Instruction;
import org.BJ.Food4All.utils.GlobalDefs;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class RecipeInstructionsListViewAdapter extends ArrayAdapter<Instruction> 
{
    private Context mContext;
    private ArrayList<Instruction> mItems;
    private LayoutInflater mInflater;

    public RecipeInstructionsListViewAdapter(Context context, int textViewResourceId, ArrayList<Instruction>items) 
    {
        super(context, textViewResourceId, items);

        mContext = context;
        mItems  = items;

        mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, 
                        View convertView, 
                        ViewGroup parent) 
    {
          ViewHolder holder = new ViewHolder();

          if (convertView == null) 
          {
              convertView = mInflater.inflate(R.layout.recipes_instruction_list_single_view_entry, null);
          }

          if(super.getItem(position) != null)
          {
              holder.instructionIndex = (TextView) convertView.findViewById( R.id.listUp_RecipeInstructionNumberTextBoxId);
              holder.instructionText = (TextView) convertView.findViewById( R.id.listUp_RecipeInstructionTextTextBoxId);
              holder.instructionImage = (ImageView)convertView.findViewById( R.id.listUp_RecipeInstructionImageViewId);

              Typeface tf = Typeface.createFromAsset(mContext.getAssets(), "Eras_Bold.ttf");
              holder.instructionIndex.setTypeface(tf);
              holder.instructionIndex.setTextSize(30);
              holder.instructionIndex.setTextColor(GlobalDefs.GetHeadlineColor());
              holder.instructionIndex.setText( Integer.toString(mItems.get(position).getIndex()));

              tf = Typeface.createFromAsset(mContext.getAssets(), "Arial.ttf");
              holder.instructionText.setTypeface(tf);
              holder.instructionText.setTextSize(14);
              holder.instructionText.setTextColor(Color.BLACK);
              holder.instructionText.setText(mItems.get(position).getText());

              Bitmap imageBitmap = mItems.get(position).GetBitmap();
//              String imageLocation = mItems.get(position).GetInstructionImageLocation();
              if(imageBitmap != null)
              {
                  holder.instructionImage.setImageBitmap(imageBitmap);// setImageURI( Uri.parse(imageLocation ));
                  holder.instructionImage.setVisibility(View.VISIBLE);
              }
              else
              {
                  holder.instructionImage.setVisibility(View.GONE);
              }

              convertView.setTag(holder);
              convertView.setLayoutParams(new ListView.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
          } 
          else 
          {
          }

          return convertView;
    }

    @Override
    public boolean isEnabled(int position) 
    {
        return true;
    }

    static class ViewHolder 
    {
          TextView  instructionIndex;
          TextView  instructionText;
          ImageView instructionImage;
    }
}

我不确定将其归类为错误是否正确,但每次使用 Typeface.createFromAsset 时,如果创建一个新的字体资源并且不释放它。看this.

您可以做的是在加载应用程序时加载字体并静态引用它们。我把我的字体放在应用程序中。

public class YourApp extends android.app.Application {
    public void onCreate() {
        super.onCreate();

        // typeface caching
        initializeTypefaces();
    }

    public static class Fonts {
        public static Typeface THEOREM;
    }

    private void initializeTypefaces(){
        Fonts.THEOREM   = Typeface.createFromAsset(getAssets(), "fonts/theorem.otf");
    }
}

然后我在我的适配器中执行此操作:

textView.setTypeface(YourApp.Fonts.THEOREM);

你可以走了here查看如何在 Android 中使用应用程序。

最后,看起来您仍然每次都创建 ViewHolder,而不是仅在 ConvertView 为 null 时创建。我会回顾这段视频以了解全貌。http://www.google.com/events/io/2010/sessions/world-of-listview-android.html

以下是我如何使用 ViewHolder 方法的示例:

@Override
public View getView(int pos, View convertView, ViewGroup parent) {
    ViewHolder holder;

    if(convertView == null || convertView.getTag() == null){
        convertView = inflater.inflate(R.layout.list_item, parent, false);
        holder = new ViewHolder();

        holder.text1  = (TextView)convertView.findViewById(R.id.list_item_text1);
        holder.text2  = (TextView)convertView.findViewById(R.id.list_item_text2);
        holder.text1.setTypeface(YourApp.Fonts.THEOREM); // only happens once when recycling!

        convertView.setTag(holder);
    }else{
        holder = (ViewHolder) convertView.getTag();
    }

    holder.text1.setText("someText");
    holder.text2.setText("someText");
    return convertView;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

列表视图内存泄漏 的相关文章

  • 覆盖乔达一周的第一天?

    是否有可能覆盖乔达弱的第一天sunday 因为 Joda 使用Monday作为一周的第一天 如果有办法的话 谁能解释一下 我在 SOF 中提到了以下主题 乔达时间 一周的第一天 https stackoverflow com questio
  • 使用 ACTION_VIEW Intent Action 启动文件

    我有以下代码来启动文件 try path fileJsonObject getString filePath if path indexOf 0 path path substring 1 path length path root pat
  • Android:调用超类的原因?

    我正在查看 Android 开发人员网站上的记事本教程 我有一个关于调用活动超类的重写函数的问题 例如 public class Notepadv3 extends ListActivity Override public boolean
  • java多线程中“私有最终对象”锁定有什么用?

    java多线程中 私有最终对象 锁定有什么用 据我的理解 我认为要使一个类成为线程安全的 我们应该使用内部锁定 将所有方法标记为同步并使用 this 将它们锁定在对象的监视器上 或者我们可以用方法中的私有最终对象锁替换类的 this 上标记
  • 到底什么是“位填充”或“填充位”?

    我只是在互联网上找不到任何关于 位填充 真正含义的详细解释 并且在 Stack Overflow 上也没有找到与位填充相关的线程的任何答案 我还搜索了 ISO 9899 1990 其中提到了 位填充 但没有根据我的需要进行解释 我在网上找到
  • String.intern() 线程安全吗

    我想在Java中使用 String intern 来节省内存 对具有相同内容的字符串使用内部池 我从不同的线程调用这个方法 这是个问题吗 对你的问题的简短回答是肯定的 它是线程安全的 但是 您可能需要重新考虑使用此工具来减少内存消耗 原因是
  • 将 glReadPixels 替换为 EGL_KHR_image_base 以加快像素复制速度

    我试图在 Android 本机进程中使用 EGL KHR image base 来替换 glReadPixels 因为它很慢 1280x800 RGBA 为 220ms 这是我到目前为止所拥有的 但我的它产生一个空缓冲区 只有零 uint8
  • 在 Cordova / PhoneGap 中生成 iOS 和 Android 图标

    我有一个新创建的 Cordova 项目 其中包含以下内容config xml设置 使用来自http docs phonegap com en edge config ref images md html http docs phonegap
  • 如何在没有片段的情况下使用导航抽屉?

    我正在尝试遵循这个tutorial https developer android com training implementing navigation nav drawer html关于如何创建导航抽屉 但我不想在用户从抽屉列表中选择
  • jasper 报告文件中出现错误

    首先 我在 iReport 5 1 0 中创建一个 R D1 jrxml 文件 我执行该报告的 Java 代码如下所示 import java sql Connection import java sql DriverManager imp
  • Android 中应用程序在后台运行时如何显示闪屏?

    我的应用程序有一个启动屏幕 无法避免它 因为这是出于品牌原因 我想屏蔽用户界面并在后台显示启动屏幕 就像银行应用程序那样 我应该覆盖 MainActivity 中视图的 onPause 和 onResume 吗 显现
  • 使用 Ant 构建 Android 库项目

    我在使用 ant 构建 Android 库项目时遇到问题 当我尝试跑步时ant release 它说Target release does not exist in the project MyProject 然后我假设库可能无法通过发布
  • 我可以像 justify 这样设置 Textview 的属性吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想设置 TextView 属性 如右对齐 左对齐 对齐 不 你不能设置像重力这样的属性 但您仍然可以通过采用 web 视图而不是文本视图
  • 为什么找不到 getservletcontext?

    我正在尝试使用getServletContext getRealPath 但我不断收到此错误 cannot find symbol symbol method getServletContext location interface jav
  • 优雅地避免 Java 中的 NullPointerException

    考虑这一行 if object getAttribute someAttr equals true 显然这一行是一个潜在的错误 属性可能是null我们会得到一个NullPointerException 因此我们需要将其重构为以下两个选择之一
  • 如何在Android手机上而不是模拟器上运行或调试?

    Android 模拟器速度太慢 无法测试运行的应用程序 有没有办法使用 IDE 而不是模拟器在真实手机上调试 运行应用程序 通常 您可以在手机上打开 USB 调试 然后通过 USB 将其连接到 PC 然后 手机将以与模拟器相同的方式出现在
  • 如何将字符串解析为map

    有一个像A B C D E F这样的字符串 如何将其解析为map 我会使用拆分 String text A B C D E F Map
  • SWT StyledText 有高度限制吗?

    我正在尝试创建一个应用程序 其中包含在 ScrolledComposite 中显示的 StyledText 框 我在 StyledText 框中显示大量行时遇到困难 超过 2 550 行似乎会导致问题 StyledText 框本身不能有滚动
  • 保留选项卡视图页面之间的状态

    issue 我有两个ListViews渲染内部TabBarView用一个TabController 我如何在每个之间保留状态 由于缺乏更好的词 ListView这样 1 小部件不会重建 2 ListView选项卡之间的位置会被记住 相关代码
  • Spring Boot 2 中的 401 代替 403

    With 春季启动 https projects spring io spring boot 1 5 6 发布我能够发送 HTTP 状态代码401代替403如中所述如果请求未经身份验证的uri 如何让Spring Security响应未经授

随机推荐

  • 我如何将这些更改为 NuSMV 模型中的 CTL SPEC?

    我需要帮助编写这些 CTL 我还不太明白如何以 NuSMV 格式编写 希望我的代码对您有意义 因为它是不完整的 atm 2 如果一个进程正在等待 它最终会到达其临界区 3 两个进程必须 轮流 进入临界区 4 一个进程有可能连续两次进入临界区
  • kubectl apply 与 kubectl create?

    我对文档的理解是 kubectl create 在集群中创建新的k8s资源 kubectl replace 更新实时集群中的资源 kubectl apply 如果我想做创建 替换 参考 我的问题是 为什么在集群中需要三个操作来执行相同的任务
  • 如何在操作栏溢出菜单中对齐菜单项文本

    我正在使用 ActionBarSherlock 在我的 Android 应用程序中实现操作栏 不适合此操作栏的菜单选项会自动添加到溢出菜单中 我面临的问题是这些菜单选项具有中心对齐 如何确保溢出菜单中的菜单项右对齐 例如在 Gmail 应用
  • 通过引用抛出非常量临时值

    通过非常量引用抛出在 try 块中在堆栈上构造的对象 捕获它并修改它 然后通过引用另一个 catch 块将其抛出 是否有任何问题 下面是我所指内容的一个简短示例 struct EC EC string msg what msg string
  • 删除字符串中空格后的所有内容

    我想删除字符串中空格后的所有内容 例如 my string is sad 应该返回 my 我一直试图弄清楚如何使用 sub gsub 来做到这一点 但到目前为止还没有成功 您可以使用正则表达式 例如 sub x See the 正则表达式演
  • 在 Bash 中 ssh 和运行多个命令的最简洁方法是什么?

    我已经设置了 ssh 代理 并且我可以在 Bash 脚本中的外部服务器上运行命令 执行以下操作 ssh blah server ls pwd 现在 我真正想做的是在外部服务器上运行大量长命令 将所有这些内容括在引号之间会非常难看 而且我真的
  • 如何使用 Red Hat Linux 上的标准工具随机化文件中的行?

    如何使用 Red Hat Linux 上的标准工具随机化文件中的行 我没有shuf命令 所以我正在寻找类似的东西perl or awk完成相同任务的单行 嗯 我们不要忘记 sort random sort
  • 如何使容器在 HTML/CSS 中居中?

    作为我任务的一部分 我开发了一个网站 由于我是 html css 新手 我无法从代码中找出一些问题 分配规范规定屏幕尺寸应在一定尺寸内 以便大多数浏览器都可以打开它 并且用户不应体验到任何滚动活动 所以我用div来划分整个页面以适应大小 但
  • 如何使用 Chrome 扩展程序在页面加载之前隐藏所有内容

    我尝试使用内容脚本 manifest content scripts matches js js content script js content script js ini function ini document body styl
  • SSL 性能影响[重复]

    这个问题在这里已经有答案了 可能的重复 SSL 会产生多少开销 最近 我与一位开发人员进行了交谈 他告诉我 在站点范围内实施 SSL 会使服务器负载增加 300 倍 这真的可信吗 我目前在所有页面上都使用 SSL 每天有数千名用户访问系统
  • 使 HTML 表格单元格中的文本与其他单元格重叠

    我希望单元格中的一些较长文本重叠在下一个单元格中 而不是换行 但又不会使第一列变大 如果我给细胞 white space nowrap position absolute 它将位于正确的位置 但其他文本将在其下方流动 感谢您的快速答复 您可
  • JS 四舍五入到小数点后两位 [重复]

    这个问题在这里已经有答案了 我试图将返回的数字限制为小数点后两位 但此代码对我不起作用 function myFunction var x document getElementById mySelect value document ge
  • 尝试使用 MATLAB 绘制 z = x + y 时出现错误的图形

    我正在尝试在 MATLAB 中绘制 3D 曲面 并且我利用了meshgrid 类似于 MATLAB 教程中所说的 http www mathworks com help matlab ref meshgrid html 我编写了一个非常简单
  • php 正则表达式用目录分隔符替换路径中的“任何”斜杠

    我正在尝试采取这样的路径 一些 路径 这里 一些 其他 路径 并将路径中的每个斜杠替换为 PHP 的 DIRECTORY SEPARATOR 内置常量 我有这个 subject asdf var preg replace DS subjec
  • Firebase 在 Swift 中检索自动 ID 下面的数据

    我在从 Firebase 检索数据时遇到麻烦 我想读取 auto ID 下 JSON 中的所有 contactName 数据 然后附加到 UIPickerView Here is my JSON tree used childByAutoI
  • 接口指定的属性的多态性

    为什么这不起作用 public class ClassOptions public interface Inode ClassOptions Options get public class MyClass Inode public Cla
  • VBScript - 复制过去 24 小时内修改的文件

    我正在尝试从上次修改日期在当前日期 24 小时内的目录中复制文件 我在文件路径中使用通配符 因为它每天都在变化 option explicit dim fileSystem folder file dim path path d x log
  • UIImage 的宝丽来滤镜

    我正在尝试在 iPhone 中实现一些图像滤镜 例如宝丽来 我搜索了如何过滤现有的 UIImage 将其转换为polaroid风格和遇到this堆栈溢出链接 以那里的答案为起点 我循环遍历图像的每个像素 获取 RGB 值 并将它们转换为 H
  • 如何使用 easymock 模拟类中的静态方法?

    假设我有一个像这样的课程 public class StaticDude public static Object getGroove some complex logic which returns an object 如何使用简单模拟来
  • 列表视图内存泄漏

    我有一个带有适配器的简单列表视图 我动态创建了 10 多个列表视图项目 然后我一次又一次地上下滚动 我可以看到可用内存不断减少 我需要在哪里免费以及什么 注意 有一个图像视图 但在我的测试中我没有使用任何图像 所以它是 View GONE