- 博客(31)
- 资源 (1)
- 问答 (2)
- 收藏
- 关注
原创 HashSet理解(三)add方法(jdk1.7及以前)是如何插值的
& (按位与)运算的结果 &运算符,具体怎么算的,这篇:java运算符手把手教你计算。按位与有个特点,算式x&y中,当y=2^n-1时,例如3,7,15等,其作用类似于x%y。测试下: public static void main(String[] args) { System.out.println(15&15); System.out.println(16&15); System.out.println(
2021-10-31 21:40:51 249
原创 HashSet理解(二)怎么做到存储的值不重复
HashSet的实现,是一个value为PRESENT的HashMap。为什么value设置为PRESENT,是null不是更加节省空间吗?因为HashSet的add方法,要返回一个boolean值,为true,表示添加了新的元素,false表示添加了一个重复的值。add方法内部调用了HashMap的put方法: public boolean add(E e) { return map.put(e, PRESENT)==null; } //HashMap pu
2021-10-31 19:20:26 615
原创 java不可变类和不可变对象
什么是不可变对象?下面是《Effective Java》这本书对于不可变对象的定义:不可变对象(Immutable Object):对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。不可变对象就是不可变类的实例,那么什么是不可变类?从程序的角度讲:类一般用final修饰,不可被继承。不提供set方法,修改对象属性如果要修改方法,需要创建一个新的对象,然后修改状态。常见的不可变类有哪些?String,Integer,其他包装类不可变对象的好处是什么?有
2021-10-29 23:45:00 566
原创 ButterKnife省略findViewById的原理
ButterKnife是JakeWhartorn及其他程序员开发的第三方库。ButterKnife源码地址:ButterKnife.java为什么大公司都不用ButterKnife了?
2021-10-28 13:46:46 128
原创 ButterKnife简单使用(Android studio 4.1.1)
开发人员先在xml中写了id,只有又要在MainActivity中,再把id写一遍,还有逐个添加点击事件,比较麻烦。ButterKnife代码自动生成比较迅速。下载安装Android ButterKnife Injections (Support Kotlin)插件,不要安装Android ButterKnife Zelezny,这个在2017年就停止更新了。我尝试用zelezny,没有效果。新建项目,在project级别下的build.gradle文件下添加:classpath 'com.ja
2021-10-27 19:52:49 1637
原创 解决:fatal: unable to access... OpenSSL SSL_read: Connection was reset, errno 10054
向github push代码报错如下:fatal: unable to access 'https://github.com/projectXX.git': OpenSSL SSL_read: Connection was reset, errno 10054 解决办法:检查本地账户和github账户是否一致,如果不一致,要切换本地账户。详细步骤参考:Git如何切换账户再次push代码,又报错:Push failed Unable to access 'https://github.com/pro
2021-10-26 15:46:18 2005
原创 kotlin系列:变量后面的?表示变量可以为空
例如自定义view时,构造函数写法: constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)表示attrs可以为空。Kotlin入门(三)——变量与问号
2021-10-26 09:42:34 332
原创 设计模式3:单例模式:堆中对象是线程共享的,为什么还需要用volatile来修饰对象?
volatile有两个作用,一是禁止指令重排序,二个是保证共享变量对所有线程的内存可见性。禁止指令重排序,在单例模式中防止出现空指针异常。对于保证内存可见性,堆中对象明明是线程共享的,为什么还需要用volatile来修饰对象? 多线程堆共享变量的修改分为很多步骤。举个简单的例子:public class VolatileTest { private static boolean flag = true; public static void main(String[
2021-10-25 17:04:39 986
原创 canvas.drawText()文字居中和靠左
文字居中:paint.setTextAlign(Paint.Align.Center);canvas.drawText(txt,viewW/2.0f,0f,paint);文字靠左paint.setTextAlign(Paint.Align.Left);canvas.drawText(txt,0f,0f,paint);参考:Android Canvas的drawText()和文字居中方案
2021-10-25 11:29:57 596
原创 kotlin(二)Android stuido 4.1.1配置并运行kotlin Demo
在Android studio 4.1.1版本,直接新建kotlin项目,会有报错Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.网上有许多解决办法,很麻烦。直接改参数,要简单些:project级别的build.gradle文件配置中ext.kotlin_version = "1.3.72"改为ext.kotlin_version = "1.4.3
2021-10-25 10:39:02 276
原创 内存泄漏(一)MVP模式中的内存泄漏以及解决方案
MVP模式为什么会存在内存泄漏的隐患? 当用户按返回键时,页面Activity退出,如果Model在子线程上执行耗时任务,还没有结束,Model持有Presenter的引用,Presenter持有Activity的引用。那么这个Activity对象就没有办法被回收。怎么解决这个内存泄漏? 在Activity的onDestroy方法中,通过Presenter间接将Model中的耗时任务取消,然后将Presenter和Model置空。既然这样可以解决内存泄漏,为什么还要用弱引用(也有代码中用..
2021-10-24 22:24:40 2352
原创 设计模式6:适配器模式
类的适配器模式类中已有的方法,不支持新的接口。适配器类继承原有的类,并且实现新的接口。适配器类继承的目的是为了兼容原有的功能。对象的适配器模式(常用)类中已有的方法,不支持新的接口。适配器类持有原有类的对象,并且实现新的接口。与类的适配器模式不同,对象的适配器模式不采用继承的方式来实现兼容,而是采用持有原有类的对象的方式实现兼容。这一点符合合成复用原则(尽量使用关联关系来替代继承关系)。接口的适配器模式(常用)接口中抽象方法太多,实现类必须实现一些不需要的抽象方法。解决办法是使用抽象
2021-10-22 16:27:31 90
原创 Android Studio系列:安装并使用JetBrains Mono字体
下载jetbrains mono字体:https://www.jetbrains.com/lp/mono/解压打开JetBrainsMono-2.242\fonts\ttf,全选,然后安装:重启Android studio,一定要重启。然后选择jetbrains mono字体就好了。问题补充:win10系统,字体文件都安装在哪个目录?C:\Windows\Fonts...
2021-10-22 13:52:03 809
原创 .sh文件
.sh文件是什么文件?“.sh”文件是脚本文件,一般都是bash脚本,我们可以使用sh命令运行“sh xxx.sh”,并且由于在linux中sh是链接到bash上的,所以sh与bash在功能上是没有区别的。
2021-10-20 14:46:43 1095
原创 ANR系列:如何分析ANR和避免ANR?
(1)避免在主线程上进行复杂耗时的操作,比如说发送接收网络数据/进行大量计算/操作数据库/读写文件等。这个可以通过使用AsyncTask或者使用多线程来实现。(2)broadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个Service来处理(3)在设计及代码编写阶段避免出现出现同步/死锁或者错误处理不恰当等情况。...
2021-10-16 14:28:03 106
原创 ANR系列:广播触发ANR的原理
无序广播和有序广播的区别:平时使用的广播默认就是无序广播,也叫普通广播。无序广播不可以被拦截,不可以被终止,不可以被修改,无序广播任何接收者只要匹配条件都可以接收到,无优先级问题。无需广播是异步执行的,接受顺序不确定。有序广播是按照接收者的优先级接收,只有一个广播接收者能接收信息,在此广播接收者中逻辑执行完毕后,才会继续传递。无序广播会不会造成ANR?有序广播发送给下一个的时候,首先会判断,上一个是否已经超时,也就是anr,如果超时,就会发送anr既broadcasttimoutlocked,
2021-10-15 13:36:25 1697
原创 ANR系列:Service触发ANR的源码分析
关于Service的基本使用,参考:Service创建和生命周期从调用startService(new Intent(this, TestService.class));
2021-10-14 00:51:49 124
原创 设计模式3:单例模式梳理
这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。这种写法能够在多线程中很好的工作,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,所以不建议用这种模式。懒汉模式申明了一个静态对象,在第一次使用时初始化,虽然节约了资源,但第一次加载时需要实例化,反应稍慢一些,而且在多线程不能正常工作。似乎静态内部类看起来已经是最完美的方法了,其实不是,可能还存在。
2021-10-11 21:12:51 84
原创 笔试题:创建三个线程,第一个线程打印1 2 3 4 5, 第二个线程打印 6 7 8 9 10...
题目:创建三个线程,第一个线程打印1 2 3 4 5, 第二个线程打印 6 7 8 9 10, 第三个线程打印11 12 13 14 15,然后第一个线程再打印16 17 18 19 20,然后第二个线程接着打印21… 依此类推,直到打印到100。有哪些坑?synchronized关键字对值为[-128,127]之间的Integer类型,不起作用。所以不能用Integer作锁对象。为了防止打印的值超过100,在每次输出钱都要检查是否超过100了。打印完成后,锁没有及时释放,导致其他没有获得锁的线程
2021-10-11 20:31:30 450
原创 @Retention注解的作用
Java中java/lang/annotation/Retention.java源代码:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.ANNOTATION_TYPE)public @interface Retention { RetentionPolicy value();}Retention的中文意思是:保留,记忆力。更具体的分析见:@Retention注解作用...
2021-10-10 17:16:33 866
原创 @Documented注解的作用
许多注解头部都有@Documented注解,例如jdk中自带的@Deprecated注解,路径是:java/lang/Deprecated.java,头部就含有这个注解。@Documented@Retention(RetentionPolicy.RUNTIME)@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})public @interface Deprecated {}那么
2021-10-10 16:16:19 49346 1
原创 synchronized修饰方法、static方法、this、.class、obj的代码示例
在static方法中,synchronized(XX.class){...}public class PrintFruit { public static void printA(){ System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date())+" Apple"); } public static void printB(){ System.out.println(n
2021-10-09 10:26:56 436
原创 Handler延时是在UI线程实现的,那么为什么没有出现界面卡顿?
答案在文章的最后,着急的话,直接跳到文末。先看看代码逻辑。 public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() +
2021-10-04 17:58:49 219
原创 Handler机制的作用真的是线程间通信吗?
首先,线程之间本来就可以相互修改对象属性,因为对象存储在堆内存中,堆内存本来就是线程共享的。看下面这段代码的运行结果,就明白了。public class HandlerTest { static class Message { String name; int age; } public static void main(String[] args) { Message msg = new Message(); .
2021-10-03 17:49:51 167
原创 EventBus实现组件通信的原理
在理清原理之前,先要明白EventBus的使用场景和主要方法的调用,可以参考EventBus 3.0的使用。Publish/Subscribe模式,就是发布订阅模式。点击在线查看EventBus.java源码。EventBus的核心思想就是把event和订阅者,对应存在一个HashMap中,post方法调用后,再根据入参event,从HashMap中取出对应的订阅者对象,调用订阅方法,完成通信。下面逐步分析EventBus的几个重要方法。getDefault()使用单例模式新建唯一单例EventBu.
2021-10-03 00:01:51 357
《Software Architecture Design Patterns in Java》原版PDF 下载
2017-12-08
在公司做android源码开发,怎么解决编译一次耗时,太久的问题?
2018-11-01
Android:逐帧动画里面,能不能使图片的位置移动?
2016-08-22
TA创建的收藏夹 TA关注的收藏夹
TA关注的人