浅谈Java中的软引用
个人博客
http://www.milovetingting.cn
浅谈Java中的软引用前言Java中有四种引用类型:强引用、软引用、弱引用、虚引用。四种引用类型分别有不同的应用场景,本文主要演示软引用的简单使用、可能遇到的问题以及对应的解决方法。
软引用的简单使用软引用的特点是:如果一个对象只存在软引用,那么当内存不足时,GC就会回收这个对象。
设置JVM的最大内存为了模拟内存不足,这里通过-Xmx来设置JVM的最大可分配内存。
1-Xmx100m
这里是使用IntelliJ IDEA来创建项目的。在Run-Edit Configurations中打开
先输出JVM当前的内存信息
123456789private static void showInitialMemoryInfo() { MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); System.out.println("最大可用内存:" + toMB(mbean.getHeapMemoryUsa ...
Kotlin的协程
个人博客
http://www.milovetingting.cn
Kotlin的协程前言本文是Kotlin协程的一个简单笔记,由于刚接触Kotlin语言,如有理解错误,为避免误导别人,可留言评论,以便本人及时修改,感谢各位大佬!关于协程的进阶文章,可参考其它相关资料!
协程是什么
协程是一种并发设计模式,在 Android 平台上使用它来简化异步执行的代码。
以上是官方文档对协程的简单定义。
下面通过代码来展示协程的具体使用。
假设有以下的需求:有一个耗时的任务要执行,在执行完成后,需要在主线程刷新UI。
不使用协程在Activity的onCreate中分别调用以下方法
123456789101112131415io()ui()private fun io() { thread { Log.d(TAG, "io method,thread:${Thread.currentThread().name}") delay(1000) } ...
使用BinderPool管理AIDL
个人博客
http://www.milovetingting.cn
使用BinderPool管理AIDL前言平时我们用到AIDL,一般的流程可能是这样:
定义AIDL接口
定义服务,在onBind方法中返回实现了AIDL接口的Stub类的实例
调用bindService方法,在ServiceConnection的onServiceConnected回调中获取到Binder对象
通过Binder对象调用接口中的方法
如果我们只是用到比较少的AIDL调用,那么上面的方法的确是可行的,但是,如果需要调用数量较多的AIDL,那么可以通过先访问一个BinderPool,然后再由BinderPool来查询相关的Binder服务,再将Binder服务返回。通过这种统一管理的方式,可以方便地管理AIDL。
下面详细介绍BinderPool具体的定义
定义IBinderPool定义IBinderPool,queryBinder方法返回IBinder对象
123interface IBinderPool { IBinder queryBinder(int queryCode ...
Flutter开发环境搭建
个人博客:http://www.milovetingting.cn
Flutter开发环境搭建前言
参考链接:https://flutterchina.club/
Windows系统下Flutter开发环境搭建使用镜像由于在国内访问Flutter有时可能会受到限制,Flutter官方为中国开发者搭建了临时镜像,可以将如下环境变量加入到环境变量中:
变量名
值
PUB_HOSTED_URL
https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL
https://storage.flutter-io.cn
Flutter SDK 下载
去flutter官网下载其最新可用的安装包:https://flutter.dev/docs/development/tools/sdk/releases#windows
将安装包zip解压到你想安装Flutter SDK的路径(如:C:\src\flutter;注意,不要将flutter安装到需要一些高权限的路径如C:\Program Files\)
在Flutter安装目录的fl ...
Android自定义View-圆形图片控件
个人博客
http://www.milovetingting.cn
Android自定义View-圆形图片控件前言在日常开发中,圆形的图片效果还是很常见的。可以通过给Paint设置Xfermode来实现,这里简单记录如下。
实现实现圆形效果的核心是PorterDuffXfermode,对于PorterDuffXfermode,这里不展开,可以查询相关资料。
核心代码12345678//绘制背景canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2, mPaint);//设置模式为:显示背景层和上层的交集,且显示上层图像mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//绘制要显示的图像canvas.drawBitmap(mSrcBitmap, 0, 0, mPaint);//重置XfermodemPaint.setXfermode(null);
自定义属性1234567891011121314<?xml version="1.0&quo ...
浅析对象的创建过程
个人博客
http://www.milovetingting.cn
浅析对象的创建过程前言我们平时在创建对象时,可能都会这样创建:
1Object object = new Object();
看起来很简单的一个过程,那么这个new操作的背后,有哪些相关的知识点,是需要我们掌握的,本文针对这些来展开介绍。
对象的创建过程类都是由JVM加载到内存中的,类加载采用双亲委派机制,双亲委派机制具体信息,这里不作展开。类加载包含以下几个过程:
加载加载Class信息到内存中,可以从Class文件读取,也可以从Zip包读取,或者在运行时通过动态代理读取。
连接验证验证Class文件的字节流中包含的信息是否符合虚拟机要求。
准备为类对象的成员变量分配内存并设置类的成员变量的初始值。
解析虚拟机将常量池中的符号引用替换为直接引用。
初始化执行类构造器的init方法。
使用对象的使用过程。
卸载当类的所有对象都释放后执行卸载。
创建方式对象的创建方式可以直接通过new的方式来创建,但一般为便于实现对象全局唯一,都会通过单例为实现。
单例的实现简单来分,有以下几种:
饿汉式
懒汉式
静态内部 ...
Java对象占用内存大小--Java对象的内存结构分析
个人博客
http://www.milovetingting.cn
Java对象占用内存大小–Java对象的内存结构分析前言本文主要介绍Java对象的内存结构。
Java对象的内存结构Java对象的内存结构包括:
对象头
实例数据
对齐填充
普通对象和数组对象,在内存结构上有一些不同,主要体现在对象头中。普通对象的对象头由Mark Word和Klass Pointer组成,而数组对象,对象头还包括一个数组长度。
具体结构如下图:
对象头普通对象:
Mark Word:包含HashCode、分代年龄、锁标志等。
Klass Pointer:指向当前对象的Class对象的内存地址。
数组对象:
Mark Word:包含HashCode、分代年龄、锁标志等。
Klass Pointer:指向当前对象的Class对象的内存地址。
Length:数组长度
实例数据存储对象的所有成员变量,static成员变量不包括在内。
对齐填充Java对象的内存空间是8字节对齐的,因此总大小不是8的倍数时,会进行补齐。
Java对象的内存占用大小分析工具:JOL为便于分析对象的 ...
对AQS的简单理解及自定义锁的实现
个人博客
http://www.milovetingting.cn
对AQS的简单理解及自定义锁的实现AQSAQS,即AbstractQueuedSynchronizer,意为队列同步器,是用来构建锁或者其它同步组件的基础框架。
AQS使用一个int类型的state表示同步状态。
AQS使用了模版方法的设计模式,子类继承AQS后,通过实现抽象方法来管理同步状态。
AQS在ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch等类中都有广泛使用。
ReentrantLock中的AQS下面以ReentrantLock为例,来看下AQS的具体使用
ReentrantLock中有一个Sync类型的成员变量sync。
1private final Sync sync;
Sync的定义
123abstract static class Sync extends AbstractQueuedSynchronizer { //... }
Sync是一个继承自AQS的抽象类,只实现了一部分 ...
IntelliJ IDEA插件开发的简单流程
个人博客
http://www.milovetingting.cn
IntelliJ IDEA插件开发的简单流程前言平时用Android Studio开发项目时,我们都会或多或少接触到一些插件,这些插件能帮助我们提高开发效率。如果我们有一些特定的需求,但还没有插件可以满足这些需求,那么可以通过自定义插件来实现。
自定义插件创建插件工程
File-New-Project,在创建工程的界面,选择IntelliJ Platform Plugin,右侧选择SDK,这里需要选择IntelliJ IDEA安装目录下的SDK,这个SDK包含后面插件开发所需要的jar。
点击Next后,在弹出的界面配置工程信息,包括工程名称,保存地址。
配置SDK如果前面创建工程时,没有IntelliJ IDEA的SDK可选,可以在这里配置
File-Project Structure-Platform Settings-SDKs.
如果右侧没有任何可选的SDK,那么需要先配置JDK。点+号-Add JDK
选择JDK的位置
添加JDK后
添加IntelliJ IDEA SDK ...
IOC之运行时注入-实现Activity的布局注入+控件注入+事件绑定
个人博客
http://www.milovetingting.cn
IOC之运行时注入-实现Activity的布局注入+控件注入+事件绑定前言本文主要介绍基于IOC的设计原则,实现以下功能:
布局注入
控件注入
事件注入
其实这些功能,在之前也有零散地介绍过,这里再做一个统一的整理。
这里暂时不考虑运行时反射的效率问题,只是展示一种实现方案。
IOC的定义IOC,即Inversion of Control,意为控制反转,是面向对象编程中的一种设计原则,可以用来降低代码间的耦合。最常见的方式是依赖注入(Dependence Injection,简称DI)。通过IOC,对象在创建时,由外界来控制,而不是内部直接控制。
布局注入平时,我们在Activity中,可能会通过在onCreate方法中调用setContentView的方法,给Activity绑定布局。而基于IOC,则可以通过注解来实现:
注解的定义12345678910@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interfac ...