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

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


这种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文档, 最后才是群里问问
--- 牙叔教程


声明


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


相关文章
|
14天前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
随着移动应用市场的蓬勃发展,用户对界面设计的要求日益提高。为此,掌握由Google推出的Material Design设计语言成为提升应用颜值和用户体验的关键。本文将带你深入了解Material Design的核心原则,如真实感、统一性和创新性,并通过丰富的组件库及示例代码,助你轻松打造美观且一致的应用界面。无论是色彩搭配还是动画效果,Material Design都能为你的Android应用增添无限魅力。
31 1
|
2月前
|
编解码 前端开发 vr&ar
从零开始的PICO教程(4)--- UI界面绘制与响应事件
这篇文章是PICO开发系列教程的第四部分,主要介绍了如何在PICO 4 VR环境中创建UI界面,包括Canvas和Panel的配置、UI元素的绘制、以及Button和Slider的事件响应绑定,并通过示例展示了数字增减和滑块功能的具体实现。
从零开始的PICO教程(4)--- UI界面绘制与响应事件
|
2月前
|
容器 iOS开发 Linux
震惊!Uno Platform 响应式 UI 构建秘籍大公开!从布局容器到自适应设计,带你轻松打造跨平台完美界面
【8月更文挑战第31天】Uno Platform 是一款强大的跨平台应用开发框架,支持 Web、桌面(Windows、macOS、Linux)及移动(iOS、Android)等平台,仅需单一代码库。本文分享了四个构建响应式用户界面的最佳实践:利用布局容器(如 Grid)适配不同屏幕尺寸;采用自适应布局调整 UI;使用媒体查询定制样式;遵循响应式设计原则确保 UI 元素自适应调整。通过这些方法,开发者可以为用户提供一致且优秀的多设备体验。
47 0
|
3月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
【7月更文挑战第28天】随着移动应用市场的发展,用户对界面设计的要求不断提高。Material Design是由Google推出的设计语言,强调真实感、统一性和创新性,通过模拟纸张和墨水的物理属性创造沉浸式体验。它注重色彩、排版、图标和布局的一致性,确保跨设备的统一视觉风格。Android Studio提供了丰富的Material Design组件库,如按钮、卡片等,易于使用且美观。
96 1
|
3月前
|
异构计算 Python
30行代码实现一个带UI界面的图片背景移除工具:并附带web网页
人工智能技术正处于蓬勃发展中,移除图片背景的方法众多,涵盖了各式各样的实现途径和模型。然而,这些方法往往在安装和配置环境方面稍显复杂。今天,介绍一种极其简便的方法——大约30行代码,就能实现这一功能。虽然相比之下可能稍显简单,但对于不太苛刻的需求来说,这种方法颇为方便实用。
Pycharm主题切换(禁用)导致UI界面显示异常解决
问题记录 UI显示异常 安装多个主题时,当禁用某些主题,切换回one dark theme时,发现代码编辑窗口背景变成白色,菜单栏其他地方背景为黑色 问题原因 查看Settings>Editor>Color Scheme>General,发现方案被改为-Classic Light
|
4月前
|
XML Android开发 数据格式
【Android UI】使用RelativeLayout与TableLayout实现登录界面
【Android UI】使用RelativeLayout与TableLayout实现登录界面
48 5
|
4月前
|
机器学习/深度学习 算法 数据可视化
【深度学习实战】基于深度学习的图片风格快速迁移软件(Python源码+UI界面)
【深度学习实战】基于深度学习的图片风格快速迁移软件(Python源码+UI界面)
|
4月前
|
机器学习/深度学习 算法 数据可视化
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
|
5月前
|
前端开发 搜索推荐 开发者
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
下一篇
无影云桌面