[Android开发]三级缓存初探索

android艺术开发探索pdf,android从入门到项目实践 今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。还有。 阅读详情

三级缓存:
内存缓存:优先加载,速度最快
本地内存:速度其次,内存没有,读本地
网络缓存:速度最慢,本地也没有,才访问网络

我们定义一个图片加载类:
MyBitmapUtils.java

/**
 * 自定义图片加载工具
 * @author dream
 *
 */
public class MyBitmapUtils {

    NetCacheUtils mNetCacheUtils;
    LocalCacheUtils mLocalCacheUtils;
    MemoryCacheUtils mMemoryCacheUtils;

    public MyBitmapUtils() {
        mMemoryCacheUtils = new MemoryCacheUtils();
        mLocalCacheUtils = new LocalCacheUtils();
        mNetCacheUtils = new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils);

    }

    public void display(ImageView ivPic, String url) {
        ivPic.setImageResource(R.drawable.news_pic_default);
        Bitmap bitmap = null;
        bitmap = mMemoryCacheUtils.getBitmapFromMemory(url);
        if(bitmap != null)
        {
            ivPic.setImageBitmap(bitmap);
            return;
        }
        //从本地读
        bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
        if(bitmap != null)
        {
            ivPic.setImageBitmap(bitmap);
            mMemoryCacheUtils.setBitmapToMemory(url, bitmap);   //将图片保存在内存
            return;
        }
        //从过网络读
        mNetCacheUtils.getBitmapFromNet(ivPic, url);
    }

}

从网络获取的类:
NetCacheUtils.java

/**
 * 网络缓存
 * @author dream
 *
 */
public class NetCacheUtils {

    private HttpURLConnection conn = null;
    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;
    public NetCacheUtils(LocalCacheUtils mLocalCacheUtils, MemoryCacheUtils mMemoryCacheUtils) {
        this.mLocalCacheUtils = mLocalCacheUtils;
        this.mMemoryCacheUtils = mMemoryCacheUtils;
    }

    /**
     * 从网络下载图片
     * @param ivPic
     * @param url
     */
    public void getBitmapFromNet(ImageView ivPic, String url) {
        new BitmapTask().execute(ivPic, url);  //启动 AsyncTask
    }

    class BitmapTask extends AsyncTask<Object, Void, Bitmap>
    {
        private ImageView ivPic;
        private String url;

        /**
         * 耗时方法在此形成,子线程
         */

        @Override
        protected Bitmap doInBackground(Object... params) {
            ivPic = (ImageView) params[0];
            url = (String) params[1];
            ivPic.setTag(url);
            return downloadBitmap(url);
        }

        /**
         * 更新进度,主线程
         */
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }

        /**
         * 耗时方法结束后,执行该方法,主线程
         */
        @Override
        protected void onPostExecute(Bitmap result) {
            if(result != null)
            {
                String bindUrl = (String) ivPic.getTag();
                if(url.equals(bindUrl))
                {
                    //确保图片设置了正确的ImageView
                    ivPic.setImageBitmap(result);
                    //将图片保存在本地
                    mLocalCacheUtils.setBitmapToLocal(url, result);
                    // 将图片保存在内存
                    mMemoryCacheUtils.setBitmapToMemory(url, result);
                }

            }

        }

    }

    /**
     * 下载图片
     * @param url
     * @return
     */
    private Bitmap downloadBitmap(String url)
    {
        try {
            conn  = (HttpURLConnection) new URL(url).openConnection();
            conn .setConnectTimeout(5000);
            conn .setReadTimeout(5000);
            conn .setRequestMethod("GET");
            conn .connect();

            int responseCode = conn .getResponseCode();
            if(responseCode == 200)
            {
                InputStream inputStream = conn .getInputStream();
                //图片压缩
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;//宽高都压缩为原来的1/2
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null, options);
                return bitmap;
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            conn.disconnect();
        }
        return null;
    }

}

从本地获取的类:
LocalCacheUtils.java

/**
 * 本地缓存
 * @author dream
 *
 */
public class LocalCacheUtils {

    public static final String CACHE_PATH = Environment.getExternalStorageDirectory().
            getAbsolutePath() + "/beijingwisdom";
    /**
     * 从本地sdcard读图片
     * @param url
     */
    public Bitmap getBitmapFromLocal(String url)
    {
        try {
            String fileName = MD5Encoder.encode(url);
            File file = new File(CACHE_PATH,fileName);
            if(file.exists())
            {
                Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
                return bitmap;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 向sdcard写图片
     */
    public void setBitmapToLocal(String url,Bitmap bitmap)
    {
        try {
            String fileName = MD5Encoder.encode(url);
            File file = new File(CACHE_PATH,fileName);
            File parentFile = file.getParentFile();
            if(!parentFile.exists())
            {
                parentFile.mkdirs();
            }

            //将图片保存在本地
            bitmap.compress(CompressFormat.JPEG
                    , 100, new FileOutputStream(parentFile) );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

从内存获取的类:
MemoryCacheUtils.java

/**
 * 内存缓存
 * 
 * @author dream
 *
 */
public class MemoryCacheUtils {

    // public HashMap<String, SoftReference<Bitmap>> mMemoryCache = new
    // HashMap<String, SoftReference<Bitmap>>();
    public LruCache<String, Bitmap> mMemoryCache;

    public MemoryCacheUtils() {
        long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模拟器默认16M
        mMemoryCache = new LruCache<String, Bitmap>((int) (maxMemory)) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                int byteCount = value.getRowBytes() * value.getHeight();
                return byteCount;
            }
        };
    }

    /**
     * 从内存读
     * 
     * @param url
     */
    public Bitmap getBitmapFromMemory(String url) {
        // SoftReference<Bitmap> softReference = mMemoryCache.get(url);
        // if(softReference != null)
        // {
        // Bitmap bitmap = softReference.get();
        // return bitmap;
        // }
        return mMemoryCache.get(url);


    }

    /**
     * 从设置内存读
     * 
     * @param url
     * @param bitmap
     */
    public void setBitmapToMemory(String url, Bitmap bitmap) {
        mMemoryCache.put(url, bitmap);
    }
}

内存溢出问题:
Android默认每个app只能分配16M的内存,所以经常在内存中加载图片会发生内存溢出,我们来熟悉一下Java中的引用:

强引用:垃圾回收器不会回收,Java默认引用都是强引用
软引用:SoftReference 在内存不够时,Java垃圾回收会考虑回收
弱引用:WeakReference 在内存不够时,Java垃圾回收会优先回收
虚引用:PhantomReference 在内存不够时,Java垃圾回收会最优先回收

在Android2.3+,系统会优先将SoftReference的对象提前回收,即使内存够用,所以不再使用,所以这个我们也不能用了。

接下来介绍LruCache:
least recentlly use 最近最少未使用
会将内存控制在一定的大小内,超出最大值时会自动回收,这个最大值开发者自己定。
对于界面中可以缩放的图片我们也可以进行图片压缩。

InputStream inputStream = conn .getInputStream();
                //图片压缩
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 2;//宽高都压缩为原来的1/2
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream,null, options);
                return bitmap;
深入探索Android中的缓存机制 本文深入探讨了Android中的缓存机制,并提供了相应的源代码示例,涵盖了服务器端缓存、客户端缓存、图像缓存和数据库缓存。在这个示例中,我们使用SharedPreferences类创建了一个名为"my_cache"的缓存文件,并使用Editor对象将数据存储在缓存中。通过上述示例,我们可以看到Android提供了多种方式来实现缓存机制,包括服务器端缓存、客户端缓存、图像缓存和数据库缓存。缓存是一种临时存储数据的技术,它将经常使用的数据保存在快速访问的位置,以便在需要时能够快速检索。 阅读详情

相关推荐

深入探索Gradle 5.1.1:安卓开发的核心构建工具

Kotlin DSL是Gradle逐渐引入的新特性,它允许开发者使用Kotlin语言编写构建脚本。Kotlin因其简洁、安全和能与Java无缝交互的特性,已经成为安卓开发中被推荐的语言之一。它在Gradle中的集成,为构建脚本带来了更严格的类型检查、更优雅的语法和更好的IDE支持。Kotlin DSL在Gradle中的实现,主要依赖于Groovy作为宿主语言进行扩展。Kotlin的类型安全特性使得构建脚本的编写更不容易出错。此外,Kotlin支持惯用的编程方式,可以大大简化代码并提升可读性。

weixin_32242475的博客 1047

Android自定义图片加载三级缓存

最近刚完成一个仿微信项目,刚闲下来,写篇文章,方便大家理解Android的图片加载模式。有人会问:为什么要自定义,三方库不是很完善吗?我说:是的,现在有Picasso,Glide等很多优秀的封装,可以完成。但重点是:1、通过自定义了解原理和本质才是最主要的。2、三方库少则十多个类,多则几十个甚至上百个类,方法更是不计其数,要是完全掌握恐怕至少也要一个月时间,这样对我们的学习效率影响很大,试想我们是

jambestwick的博客 659

RAG 赋能客服机器人:多轮对话与精准回复

在人工智能技术飞速发展的今天,客服机器人已成为企业提升服务效率的重要工具。然而,传统客服系统在多轮对话连贯性和精准回复能力上存在明显短板。检索增强生成(Retrieval-Augmented Generation, RAG)技术通过结合大语言模型(LLM)与外部知识库,为解决这一问题提供了创新路径。本文将深入探讨 RAG 在客服机器人中的应用,重点分析其如何实现多轮对话与精准回复,并结合实际案例与技术框架展开讨论。

shuizhudan223的博客 2141

Android开发艺术探索

Android开发艺术探索 去发现同类优质开源项目:https://gitcode.com/ 本书《Android开发艺术探索》是由任玉刚编写的一本深入探讨Android应用开发的进阶书籍。书中采用了理论、源码与实践相结合的方法,全面阐述了Android应用开发的高级要点。 内容概述 全书分为十五章,从不同角度深入解析了Android开发中的关键技术和性能优化策略: 第一章:Activity的生...

gitblog_06721的博客 693

Zephyr,设备树概述

Zephyr使用设备树(DTS)描述硬件配置,通过设备树源码和绑定文件生成C头文件供开发使用。设备树采用树状结构,节点对应硬件设备,属性描述硬件特性。示例展示了I2C总线及其外设的节点层级关系,包括单元地址、兼容性标识等关键属性。构建系统将设备树转换为devicetree.h中的宏,使开发者能通过DT_前缀宏访问硬件信息,同时保留Kconfig覆盖默认值的能力。

汽车电子软件领域知识分享 720

Windows 11安装 SQLServer 2008 R2 失败问题处理

Windows 11安装SQL Server 2008 R2失败解决方案 由于Windows 11移除了对PowerShell 2.0的支持,导致SQL Server 2008 R2安装失败。经过多次尝试,最终通过**方案六(修改注册表模拟PowerShell 2.0环境)**成功安装。其他可行方案包括: 使用SP3集成版安装包 通过命令行跳过检查(/SUPPRESSPOWERShellCHECK参数) 创建特殊配置文件 替代方案建议: 使用Docker容器运行 在虚拟机中安装 升级到新版SQL Serve

oDengWei的博客 7156

ImageLoader的使用(Android开发艺术探索),安卓客户端开发面试题目

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

2401_83974783的博客 508

C++控制台实现简单的注册登录

C++控制台实现简单的注册登录 #include<iostream> #include<string> #include <vector> #include <conio.h> void Display();//调用display显示switch()界面 void Register();//注册 void Enter();//登录 using nam...

乔路非 2万+

android bitmap 重复,Android Bitmap 的高效加载和三级缓存读书笔记

本文主要内容出自《Android 开发艺术探索》,作为记录的同时加入个人的理解和思考,同时搜索其它资料和自己动手翻源码来理解实现原理。问题:如何高效加载 Bitmap?解决这个问题的核心思路是根据图片需要显示的大小来缩放图片进行显示,缩放的方式为设置采样率。LruCache 的原理?下文有个人总结的答案,可以参考,建议大家自己总结答案。Android 三级缓存?内存缓存、本地缓存(磁盘缓存)、网络...

weixin_28858247的博客 349

基于matlab的CNN物体识别物体分类系统

主要对物体进行识别,搭建一个物体分类系统本次实验选择规模稍大的 CIFAR-10 数据集进行分类识别,对应图像的大小设计 VggNet、ResNet 进行网络训练。在实际操作过程中,受限于数据规模和硬件配置,对于大小放缩、批次参数、训练步数等进行了多次调试,这也对以后的图像分类任务具有较高的参考意义,并通过对 CIFAR-10 数据集进行训练和评测,采用网络修改的方式来得到新的 CNN 结构,适用于对网络进行配置、融合等相关研究。读者可以通过自行设计或选择其他网络、加载其他数据等方式进行实验的延伸。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2005

鱼鹰优化算法(OOA)详解:从猛禽捕食智能到优化算法实现

鱼鹰优化算法(Osprey Optimization Algorithm, OOA)是2023年提出的一种新型元启发式优化算法,灵感来源于鱼鹰(一种中型猛禽)高效的捕食策略。算法模拟了鱼鹰从空中识别水下鱼类位置并俯冲捕食,然后将捕获的鱼带至安全位置享用的全过程,以此抽象出全局探索和局部开发两个核心阶段。OOA算法具有参数少、结构简单、收敛速度快、全局寻优能力强等特点。自提出以来,已在函数优化、机器学习参数调优(如CatBoost模型)、路径规划等多个领域展现出良好性能,为解决复杂优化问题提供了新的有效工具。

qq_42212808的博客 273

深入探索 Android Gradle 插件的缓存配置

什么是配置缓存?配置缓存是一个提升 IDE 和命令行构建速度的基础构建块。这是 Gradle 6.6 版本提供的一个高度实验性功能,它可以使构建系统记录一次任务的图谱信息,并在接下来的构...

谷歌开发者 1423

快速傅里叶变换(FFT)的汇编实现在DSP开发中

在数字信号处理(Digital Signal Processing,DSP)开发中,使用汇编语言实现FFT可以进一步提高计算性能和优化系统资源的使用。FFT是一种分治算法,它通过将一个长度为N的离散时间域序列分解为多个长度为N/2的子序列,然后递归地进行计算。开发者可以根据实际需求,结合具体的硬件平台和编译器工具链,对FFT的汇编实现进行优化和定制化。需要注意的是,上述示例代码中只给出了FFT的基本框架,具体的合并操作及其他细节需要根据实际需求进行实现。上述示例代码演示了一个简单的FFT汇编实现。

QoTypescript的博客 683

探索DaVinci——一个安卓穿戴设备的图像下载与缓存库

探索DaVinci——一个安卓穿戴设备的图像下载与缓存库 DaVinciDaVinci is an image downloading and caching library for Android Wear项目地址:https://gitcode.com/gh_mirrors/davi/DaVinci 项目简介 在追求高效便捷的开发过程中,我们常常需要为我们的智能手表应用提供快速且稳定的图像加...

gitblog_00082的博客 500

[Godot][入门] 安装与版本选择:3.x 还是 4.x?(按项目类型一键决策)

摘要: Godot引擎版本选择需根据项目需求权衡3.x与4.x。Godot4.x(如4.2)适合3D开发和新项目,支持Vulkan和GDScript2.0,但生态尚不成熟;Godot3.x(如3.5.3)则更适合稳定2D开发、Web导出及依赖现有插件/教程的场景。安装方式极简,官网下载解压即可运行。新手建议:短期高效选3.x,长期探索选4.x,旧项目勿盲目迁移。附版本对比表及决策树,助开发者快速匹配需求。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 910

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

老旧安卓电视如何流畅播放高清直播?MyTV-Android原生应用终极方案

你是否曾因家中老旧安卓电视播放直播卡顿而烦恼?当主流应用纷纷抛弃安卓4.x系统时,一款名为MyTV-Android的开源电视直播应用却逆向而行,专门为这些"老古董"设备打造了一个流畅的解决方案。这款仅15MB的轻量级应用,让512MB内存的老旧电视也能流畅播放高清直播,重新焕发生机。 ## 从发现到惊喜:一次老旧设备的重生之旅 三年前,我家的安卓电视开始出现明显的卡顿问题。每次打开直播软件都要

gitblog_00409的博客 264

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

让老旧安卓电视重获新生:MyTV-Android轻量直播应用体验分享

你是否还记得家里那台反应迟钝的安卓电视?每次打开直播软件都要等待十几秒,切换频道时画面卡顿得让人抓狂。当主流应用纷纷抛弃安卓4.x系统时,MyTV-Android却逆向而行,专门为这些被遗忘的"老古董"设备打造了一个流畅的直播解决方案。 这款完全开源的电视直播软件就像给老电视安装了一个全新的"智能引擎",让512MB内存的设备也能流畅播放高清直播。安装包仅15MB,比同类应用节省60%存储空间,

gitblog_01136的博客 263

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

探索 AndroidGenericFramework:一个高效能的安卓开发框架

探索 AndroidGenericFramework:一个高效能的安卓开发框架 是一个由 TanJiaJunBeyond 开发并维护的开源项目,旨在提供一种更高效、可复用且易于维护的安卓应用开发解决方案。这个框架基于现代安卓开发最佳实践,将常见的设计模式和组件封装起来,以简化开发者的工作流程。 技术分析 模块化设计:AndroidGenericFramework 遵循模块化的架构,使得不同功能...

gitblog_00004的博客 550

android webview能缓存https网页吗_Android WebView缓存优化探索

写在开头大家好,没错又是我。投稿一时爽,一直投稿一直爽,爽完还有积分拿,何乐而不为呢?进入正题由于H5的开发周期短,可以跨平台使用,灵活性较好,越来越多的App开始嵌入H5进行混合开发。但使用这种方式存在2个突出的性能问题:页面加载速度慢、流量消耗大。在这里我将针对这2个问题,提供一个解决方案。01Android WebView存在的性能问题1.1 H5页面渲染速度慢H5页面的渲染速度...

weixin_39782709的博客 290

推荐文章:探索高效Android缓存新境界 —— 咔咔缓存(KakaCache)

推荐文章:探索高效Android缓存新境界 —— 咔咔缓存(KakaCache) 项目介绍 在快节奏的移动开发领域,缓存的重要性不言而喻。咔咔缓存(KakaCache),正如其名,旨在让缓存变得简单快捷,成为Android开发者手中的得力助手。这是一套专注于Android平台上的网络请求与图片加载缓存解决方案。尽管该项目被标记为实验性质,但其广泛的功能覆盖与灵活性已经吸引了众多开发者的眼球。 项目...

gitblog_01181的博客 882

三级缓存对性能的影响,面试字节跳动两轮后被完虐,系列篇_三级缓存对编程有影响吗

UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!

2401_84183669的博客 991

Android系统开发(一):AOSP 架构全解析:开源拥抱安卓未来

修改启动动画文件:替换目录下的启动图像资源。重建系统测试效果:将生成的 boot.img 刷入目标设备。Android AOSP 是系统开发者不可或缺的开源利器,它让开发者能够掌控从内核到应用的每一行代码。尽管上手可能有一定难度,但通过学习,你将解锁整个安卓技术栈的潜力,为未来的开发铺平道路。

刘 争 6410

android开发艺术探索

====================activity生命周期=============== activity异常退出后执行==》新的activity创建后生成. onSaveInstanceState==》onRestoreInstanceState     系统配置发生改变后,activity会被重建,如何避免重建activity? activity 的 fl...

TheClimb的池塘 146

开源项目:购物安卓应用开发教程

开源项目:购物安卓应用开发教程 项目介绍 本项目是由 GitHub 用户 i-vishi 提供的一个名为 "shopping-android-app" 的开源安卓应用程序示例。该应用旨在展示如何构建一个基本的电商应用,包括商品浏览、搜索、添加到购物车等功能。它对于学习Android应用开发,尤其是电商应用界面设计和功能实现的新手开发者而言,是一个宝贵的资源。 仓库链接: ht...

gitblog_00038的博客 1314

【亲测免费】 Android PDF阅读器:PDFView深度探索

在开源世界里,【PDFView】是一个亮点,专为Android平台量身定制的PDF查看解决方案。此项目由Java和Kotlin双语种构建,展现了一流的技术融合。它不仅仅是一个工具,而是一扇通往流畅PDF体验的大门。 ## 核心功能概览: PDFView以自定义View的形式出现,其核心能力令人印象深刻: - **滑动与缩放**:提供直观的用户交互,支持平滑滚动及 pinch-to-zoom 功能...

gitblog_01264的博客 1477

[Android开发]Activity的四种启动模式及其应用场景

启动模式(launchMode)在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。Activity一共有以下四种la

陶程的博客 6万+
上一篇: [Android开发]WebView里改变浏览字体大小
下一篇: [Android开发]屏幕适配问题
陶程
博客等级 码龄12年 360粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值