美文网首页
UI界面的图片需要主动回收

UI界面的图片需要主动回收

作者: 牙叔教程 | 来源:发表于2021-11-22 16:51 被阅读0次

牙叔教程 简单易懂

这种setImageBitmap必须主动回收图片,
bitmap已经赋值给了你定义的变量, 既然你给图片添加了新的引用,
那么这张图片就归你管, 系统就不管了

"ui";
ui.layout(
  <vertical>
    <img id="img"></img>
  </vertical>
);
let img = images.read(imgPath);
let bitmap = img.bitmap;
ui.img.setImageBitmap(bitmap);
events.on("exit", function () {
  img.recycle();
});

这种就不用自己主动回收图片,
因为你没有对图片进行引用, 引用是系统自己搞的, 系统可以处理

"ui";
ui.layout(
  <vertical>
    <img id="img" src="file://{{imgPath}}"></img>
  </vertical>
);

这种也不用自己主动回收图片, 原因同上

ui.layout(
  <vertical>
    <img id="img"></img>
  </vertical>
);
ui.img.attr("src", "file://" + imgPath);

下面来看看RecyclerView中使用图片的情况
这是使用 img.attr("src", "file://" + data.imgPath);
不需要主动回收, 但是滑动rv的时候, 有点卡,
因为每次加载数据, 都去读取一遍图片

ui.layout(
  <vertical>
    <text text="牙叔教程 简单易懂" textSize="28sp" textColor="#fbfbfe" bg="#00afff" w="*" gravity="center"></text>
    <androidx.recyclerview.widget.RecyclerView id="recyclerView"></androidx.recyclerview.widget.RecyclerView>
  </vertical>
);

let imgPath = "/storage/emulated/0/脚本/ui界面图片回收/" + "road.jpg";
let dataList = [];
var len = 33;
for (var i = 0; i < len; i++) {
  dataList.push({
    imgPath: imgPath,
  });
}

let recyclerView = ui.recyclerView;
let layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
let recycleAdapter = createRecyclerViewAdapter(dataList);
recyclerView.setAdapter(recycleAdapter);
/* ---------------------------自定义函数----------------------------------------------- */
function createRecyclerViewAdapter(dataList) {
  let boxXml = (
    <horizontal id="horizontalParent">
      <text id="num"></text>
      <img id="img"></img>
    </horizontal>
  );
  return RecyclerView.Adapter({
    onCreateViewHolder: function (parent, viewType) {
      log("onCreateViewHolder");
      // 视图创建
      let view;
      let holder;
      view = ui.inflate(boxXml, parent, false);
      holder = JavaAdapter(RecyclerView.ViewHolder, {}, view);
      return holder;
    },
    onBindViewHolder: function (holder, position) {
      // log("onBindViewHolder");
      // 数据绑定
      let data = dataList[position];
      holder.itemView.num.setText(position + "");
      holder.itemView.img.attr("src", "file://" + data.imgPath);
    },
    getItemCount: function () {
      return dataList.length;
    },
  });
}

我们把onBindViewHolder改写一下, 如果已经加载过一次图片, 就不用执行 img.attr("src"这个命令了,
这属于最简单的缓存吧

onBindViewHolder: function (holder, position) {
  let data = dataList[position];
  holder.itemView.num.setText(position + "");
  if ("file://" + imgPath !== holder.itemView.img.attr("src")) {
    log("需要读取图片");
    holder.itemView.img.attr("src", "file://" + data.imgPath);
  } else {
    log("不需要读取图片");
  }
},

修改之后, 除了一开始加载的前几张图片有点卡之外, 其他的一点都不卡, 丝滑的很,

那么问题还是有的, 如何让前几张图片, 滑动的时候, 也不要卡呢?
我们提前读取图片试试, 也就是用setImageBitmap

let imgPath = "/storage/emulated/0/脚本/ui界面图片回收/" + "road.jpg";
let dataList = [];
var len = 33;
let img = images.read(imgPath);
let bitmap = img.bitmap;
for (var i = 0; i < len; i++) {
  dataList.push({
    imgPath: imgPath,
    img: img,
    bitmap: bitmap,
  });
}
events.on("exit", function () {
  img.recycle();
});
ui.layout(
  <vertical>
    <text text="牙叔教程 简单易懂" textSize="28sp" textColor="#fbfbfe" bg="#00afff" w="*" gravity="center"></text>
    <androidx.recyclerview.widget.RecyclerView id="recyclerView"></androidx.recyclerview.widget.RecyclerView>
  </vertical>
);

let recyclerView = ui.recyclerView;
let layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
let recycleAdapter = createRecyclerViewAdapter(dataList);
recyclerView.setAdapter(recycleAdapter);
/* ---------------------------自定义函数----------------------------------------------- */
function createRecyclerViewAdapter(dataList) {
  let boxXml = (
    <horizontal id="horizontalParent">
      <text id="num"></text>
      <img id="img"></img>
    </horizontal>
  );
  return RecyclerView.Adapter({
    onCreateViewHolder: function (parent, viewType) {
      log("onCreateViewHolder");
      // 视图创建
      let view;
      let holder;
      view = ui.inflate(boxXml, parent, false);
      holder = JavaAdapter(RecyclerView.ViewHolder, {}, view);
      return holder;
    },
    onBindViewHolder: function (holder, position) {
      let data = dataList[position];
      holder.itemView.num.setText(position + "");
      holder.itemView.img.setImageBitmap(data.bitmap);
    },
    getItemCount: function () {
      return dataList.length;
    },
  });
}

试了一下bitmap, 真的很丝滑呢, 起码小米11pro是丝滑的,

我们的dataList有33条数据, 每条数据使用的都是同一张图片的bitmap,
我们来试试33张不同的图片, 看会不会卡顿

修改dataList即可, 注意, bitmap是需要自己主动回收的

let img = images.read(imgPath);
for (var i = 0; i < len; i++) {
  let newImg = img.clone();
  let bitmap = newImg.bitmap;
  dataList.push({
    imgPath: imgPath,
    img: newImg,
    bitmap: bitmap,
  });
}
events.on("exit", function () {
  img.recycle();
  dataList.map(function (item) {
    item.img.recycle();
  });
});

基本和使用同一张图片的bitmap效果一样, 感觉不到卡顿.

这就表明, 读取图片是最消耗资源的, 我们尽量少的去读取图片, 尽量早的读取图片,
尤其要在ui中, 减少此类耗时操作, 不然, 卡顿是避免不了的.

现在加载33张图片, 还算可以吧.
如果我们加载3333张图片呢? 我觉得光是提前读取图片就会非常卡了, 非常耗时,
说不定就OOM了(Out Of Memory),
所以在数量级上去之后, 我们是不会提前读取全部图片的,

我们只会读取一小部分图片, 应该叫预加载吧,

手机是支撑不了同一时刻, 加载那么多图片数据的, 一会就卡爆了,
那么我们设定一个阈值, 只在同一时刻保存阈值以内数量的图片数据,

如果有新的图片需要显示, 那么就删掉以前的旧图片, 这个叫

LruCache(Least Recently Used Cache) 全称最近最少使用算法,其主要思想是使用SoftReference(或者WeakReference),因为我们的缓存容量是有限的,它会面临一个问题:当有新的内容需要加入我们的缓存,但我们的缓存空闲的空间不足以放进新的内容时,我们就需要舍弃原有的部分内容从而腾出空间用来放新的内容。

当然了, 写脚本估计用不到几张图片, 这个LurCache了解即可.

环境

手机: Mi 11 Pro
Android版本: 11
Autojs版本: 9.0.11

名人名言

思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程

声明

部分内容来自网络
本教程仅用于学习, 禁止用于其他用途

相关文章

  • UI界面的图片需要主动回收

    牙叔教程 简单易懂 这种setImageBitmap必须主动回收图片,bitmap已经赋值给了你定义的变量, 既然...

  • 获取上传图片的大小和尺寸

    element UI 上传图片的需要判断图片的尺寸和大小

  • 两张照片修改透明度后混合为一张(实现图片切换效果)

    背景 最近公司的ui帅哥提了一个需求,需要在滑动banner的时候,平滑修改banner后面的图片背景。先上效果(...

  • iOS 富文本实现直播聊天页面

    开发视频直播app,遇到了这么一个问题,需要实现下面的UI 刚开始看到这图片的时候,感觉没什么,一个图片,两个la...

  • UITableView多图下载

    UITableViewCell加载图片的问题: UI不流畅 ---------> 在主线程下载图片,导致卡顿,需要...

  • Unity不规则图片点击

    在使用unity3d制作界面的时候需要用到UI图片作为按钮使用,会经常用到不规则图片,接下来我就讲解如何自定义不规...

  • 2019-03-22

    iOS 开发之修改图片image颜色 吐槽:平时开发中可能因为 UI妹子懒给到图片中没有需要的颜色,或者嫌弃UI...

  • 达牛:如何设计出一个高大上的APP?

    要设计出一个高大上的APP需要掌握视觉设计,网站设计,建站,图片处理,UI设计,素材等方面的技巧。今天,小达就着重...

  • Java垃圾回收

    垃圾回收包含的内容不少,但顺着下面的顺序捋清知识也并不难。首先要 搞清垃圾回收的范围(栈需要GC去回收吗?),然后...

  • JVM核心知识-GC知识

    Java开发相对于C语言最方便的点,就是代码上不需要主动去管理内存的回收,而由JVM负责分配回收。 GC算法 标记...

网友评论

      本文标题:UI界面的图片需要主动回收

      本文链接:https://www.haomeiwen.com/subject/ztpbtrtx.html