Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Category java

详解SpringCloud feign内部实现代码的细节 附详细代码解析

什么是Feign?它在SpringCloud框架的作用是什么?根据这两个问题,下面,我就和大家分享一下在SpringCloud中feign内部实现代码的细节,希望能够对于正在学习SpringCloud框架的小伙伴有一定的帮助! 1. 概述 Feign用于服务间调用,它的内部实现是一个包含Ribbon(负载均衡)的**JDK-HttpURLConnection(Http)**调用。虽然调用形式是类似于RPC,但是实际调用是Http,这也是为什么Feign被称为伪RPC调用的原因。 内部调用过程如下: 2. 代码细节 1) BaseLoadBalancer.java配置初始化 重点功能: 1. 初始化负载均衡策略 2. 初始化取服务注册列表调度策略 void initWithConfig(IClientConfig clientConfig, IRule rule, IPing ping, LoadBalancerStats stats) { … // 每隔30s Ping一次 int pingIntervalTime = Integer.parseInt(“” + clientConfig.getProperty( CommonClientConfigKey.NFLoadBalancerPingInterval, Integer.parseInt(“30”))); // 每次最多Ping 2s int…

Android Handler消息机制源码解析

好记性不如烂笔头,今天来分析一下Handler的源码实现 Handler机制是Android系统的基础,是多线程之间切换的基础。下面我们分析一下Handler的源码实现。 Handler消息机制有4个类合作完成,分别是Handler,MessageQueue,Looper,Message Handler : 获取消息,发送消息,以及处理消息的类 MessageQueue:消息队列,先进先出 Looper : 消息的循环和分发 Message : 消息实体类,分发消息和处理消息的就是这个类 主要工作原理就是: Looper 类里面有一个无限循环,不停的从MessageQueue队列中取出消息,然后把消息分发给Handler进行处理 先看看在子线程中发消息,去在主线程中更新,我们就在主线程中打印一句话。 第一步: 在MainActivity中有一个属性uiHandler,如下: Handler uiHandler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 100){ Log.d("TAG","我是线程1 msg.what=" + msg.what + "…

WorkManager 在 Kotlin 中的实践

WorkManager 是一个 Android Jetpack 扩展库,它可以让您轻松规划那些可延后、异步但又需要可靠运行的任务。对于绝大部分后台执行任务来说,使用 WorkManager 是目前 Android 平台上的最佳实践。 WorkManager Android Jetpack 在这篇文章中,我们将讨论: 在 Kotlin 中如何使用 WorkManager CoroutineWorker 类 如何使用 TestListenableWorkerBuilder 测试您的CoroutineWorker 类 CoroutineWorker TestListenableWorkerBuilder Kotlin 版的 WorkManager 本文的示例代码是用 Kotlin 编写的并使用了 KTX 库 (Kotlin Extensions)。KTX 版的…

SharedPreferences源码解析

1、简述 有段时间没写博客了,写博客的习惯还是应该保持的。 写在前面,要很好的理解SP的工作机制,请一定要先看QueuedWork介绍文章,先了解QueuedWork的工作机制。 本片博客主要是对Android的一个常用组件SharedPreferences(以下简称SP)进行分析,首先分析SP日常使用步骤中,每一步的源码,看看后面发生了什么,然后对SP存在的问题进行分析和寻找解决。 首先提几个问题,如果都能给出答案的同学就可以不用看了,如果还有不知道的,看了文章之后能找出答案并会有所收获。 问题: SP是什么时候读取磁盘的数据?是打开APP的时候还是第一次使用SP的时候?从磁盘读取数据是一次全部xml文件的数据都读出来还是只读当前SP操作的xml。 对于当前SP操作的xml,每次commit/apply提交数据,只是将修改的数据写到磁盘还是将所有的都要写到磁盘。 我们提交的数据有可能还未保存,程序就退出,导致数据丢失吗? SP为什么会有可能造成 “卡顿” 呢?使用apply()的方式修改数据就不会卡顿了吗? 假设一个场景:对于当前SP操作的xml,先使用commit提交一个需要耗时10ms的任务,记为任务1,立即再使用apply提交一个需要耗时5ms的任务,记为任务2。那么任务2一定会在任务1前执行完的结论,对不对? 接下来我们就带着问题,开始源码的分析。 对于SP,我们一般是按如下步骤使用的: //获得SP SharedPreferences sp = getSharedPreferences("test", Context.MODE_PRIVATE); //获得Editor SharedPreferences.Editor editor = sp.edit(); //设置数据 editor.putString("key", "value"); //提交 editor.commit(); //or editor.apply(); 接下来会分析每一步的源码。 在分析源码之前,先看看类的组织关系: public interface SharedPreferences { //监听SP的改变…

发现Kotlin一个神奇的bug

本文将会通过具体的业务场景,由浅入深的引出Kotlin的一个bug,并告知大家这个bug的神奇之处,接着会带领大家去查找bug出现的原因,最后去规避这个bug。 现实开发中,我们经常会有将Json字符串反序列化为一个对象问题,这里,我们用Gson来写一段反序列代码,如下: fun <T> fromJson(json: String, clazz: Class<T>): T? { return try { Gson().fromJson(json, clazz) } catch (ignore: Exception) { null } } 以上代码,仅适用于不带泛型的类,对于带泛型的类,如List<T>,我们就要再改造一下,如下: fun <T> fromJson(json: String, type: Type): T? { return try { return Gson().fromJson(json, type) } catch…

Android WebView加载优化

1.前言 最近几年关于原生WebView与H5混合开发的项目越来越多,这种开发带来了很多便利,但也会有一些缺点,比如说通过WebView加载H5会有一定的卡顿现象,会影响用户体验。下面本文就此问题一一展开讨论。 2. 场景 根据日常需求一般是通过webView.loadUrl()方法加载指定的网页,其大概流程如下: image.png 创建WebView:通过Java代码创建WebView,设置相关的参数和属性 发起请求:通过底层内核会先检查缓存,然后决定是否创建对应的请求,建立对应的http请求。 页面解析:下载对应的DOM树和相关资源。 内容处理:根据上面的资源和树形结构,进行渲染展示。以上是整个网页请求的大概过程,优化也是在这几个过程中分别作出细致对应的方案。 2.1 创建WebView WebView创建的时机会对整个流程是有影响的,Webview的启动相对来说比较耗时,因此这个时候我们可以采用提前启动Webview,这样就可以在加载网页的时候已经准备好。比如我在做Browser的时候发现有Native页面点击网页icon,启动相对来说比较慢,那么采用的策略就是进入Native页面后,一段时间后提前创建Webview。一开始本以为这样就可以,但是浏览器在tab页面可以新建多个网页加载器,也就是会有多个webview。显然光是提前创建也不太好,后面采用创建一个WebView的池子来管理这些Webview /** * webview 复用池 */ public class WebViewPool { private static final String DEMO_URL = "https://www.baidu.com"; private static final String APP_CACAHE_DIRNAME = "webCache"; private static List<WebView> available…

协变和逆变

本文同步发表于我的微信公众号,在微信搜索 OpenCV or Android 即可关注。 协变、逆变 概念 许多程序设计语言的类型系统支持子类型。例如,如果Cat是Animal的子类型,那么Cat类型的表达式可用于任何出现Animal类型表达式的地方。所谓的变型(variance)是指如何根据组成类型之间的子类型关系,来确定更复杂的类型之间(例如Cat列表之于Animal列表,回传Cat的函数之于回传Animal的函数…等等)的子类型关系。当我们用类型构造出更复杂的类型,原本类型的子类型性质可能被保持、反转、或忽略───取决于类型构造器的变型性质。 协变与逆变用来描述类型转换(type transformation)后的继承关系:A、B表示类型,f表示类型转换,A≦ B表示A为B的子类,那么则存在: 当A ≦ B时,如果有f(A) ≦ f(B),那么f叫做协变; 当A ≦ B时,如果有f(B) ≦ f(A),那么f叫做逆变; 如果上面两种关系都不成立则叫做不可变。 具象化 定义Cat、Animal两个类型,且Cat是Animal的子类,类型构造器采用数组的形式: 协变(covariant):一个Cat[]也是一个Animal[] 逆变(contravariant):一个Animal[]也是一个Cat[] 不变(invariant):以上两种均不满足。 总结:假想程序设计语言中的类型为输入,数组、列表、泛型等类型构造器为函数,当函数值与输入正相关时为协变,当函数值与输入负相关时为逆变。父子类关系代表输入的大小。 语言场景 Java Java语言中,数组支持协变,泛型类原生既不支持协变,也不支持逆变。 定义类Dog,类Animal,且Dog为Animal的子类 public static void main(String[] args) { Dog[] dogs…

Android Activity生命周期,启动模式,启动过程详解

接触过Android开发的同学都知道Activity,Activity作为Android四大组件之一,使用频率高。简单来说Activity提供了一个显示界面,让用户进行各种操作,本文主要分为以下三个部分:Activity的生命周期,启动模式,以及Activity的工作过程。文中大部分篇幅来自《Android开发艺术探索》一书,尽管想多以流程或图片的形式说明,奈何文笔有限,Android系统整体把握还不够深入,只能借鉴参考前辈的成果,本文主要目的是帮自己梳理Activity的相关问题,疏漏之处欢迎指出。 说明:本文中的源码都是基于Android-25版本。 生命周期 首先给出Activity的完整生命周期,如下图所示: Activity生命周期 图片来源Android开发者官网 看完了完整的生命周期,我们再分别简单介绍单个生命周期含义。 onCreate:表示Activity正在被创建,做一些初始化工作,如加载布局文件,对一些变量或者控件进行初始化 onStart:表示Activity正在启动,此时Activity已经可见了,但还无法和用户交互 onResume:表示Activity已经在前台,可以和用户交互了 onPause:表示Activity正在停止,此时可以进行一些轻量级的存储数据和停止动画等工作,但不能太耗时,否则会影响到新Activity的显示,Android指定如果onPause在500ms内没有执行完毕的话就会强制关闭Activity。某些极端情况下,这个时候Activity会回到当前Activity,此时onResume会被执行,很难重现这一情形 onStop:表示Activity即将停止,此时Activity已经不可见了,但是Activity对象还存在内存中,没有被销毁,这个阶段也主要做一些资源回收的工作,不能太耗时 onDestory:表示Activity即将被销毁,可以做一些回收工作和最终的资源释放,最后一个回调方法 onRestart:表示Activity重新启动,当前Activity从不可见重新变为可见时会调用onRestart,这种情况一般是用户的行为导致的,比如:用户按Home键切换到桌面或者打开了一个新的Activity 三个问题 onCreate,onStart和onResume之间的区别? onCreate时Activity还不可见,onStart已经可见,还不在前台,onResume已经出现在前台 onCreate方法只在Activity创建时执行一次,而onStart方法在Activity的切换以及按Home键返回桌面再切回应用的过程中被多次调用,因此数据恢复在onStart方法中比较合适,onResume方法可以做一些开启动画和独占设备的操作 onPause,onStop和onDestroy之间的区别? onPause时Activity还可见,onStop已经不可见,但Activity对象还存在内存中,onDestroy后Activity对象就不存在了 内存不足时,可能不会执行onStop方法,因此程序状态保存,停止动画,存储数据等操作最好放在onPause中 切换Activity时生命周期执行顺序 假设当前Activity为A,此时用户打开Activity B,那么A和B的生命周期的执行顺序为: Activity跳转生命周期.png 为了验证生命周期执行顺序,我们写个例子实测,MainActivity中单击按钮跳转到SecondActivity,然后在相应的生命周期中输出日志,如下: public class MainActivity extends Activity { private static final String TAG = "MainActivity"; ……

面试官:给你了十分钟,讲出实现 Router 框架的原理

Android 开发中,组件化,模块化是一个老生常谈的问题。随着项目复杂性的增长,模块化是一个必然的趋势。除非你能忍受改一下代码,就需要十几分钟的漫长阅读时间。 模块化,组件化随之带来的另外一个问题是页面的跳转问题,由于代码的隔离,代码之间有时候会无法互相访问。于是,路由(Router)框架诞生了。 目前用得比较多的有阿里的 ARouter,美团的 WMRouter,ActivityRouter 等。 今天,就让我们一起来看一下怎样实现一个路由框架。 实现的功能有。 基于编译时注解,使用方便 结果回调,每次跳转 Activity 都会回调跳转结果 除了可以使用注解自定义路由,还支持手动分配路由 支持多模块使用,支持组件化使用 使用说明 基本使用 第一步,在要跳转的 activity 上面注明 path, @Route(path = "activity/main") public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } 在要跳转的地方…

探索Google浏览器电脑版:功能与安装指南

在这个数字化飞速发展的时代,网络浏览器已成为我们日常生活中不可或缺的工具。其中,Google浏览器(也称为Chrome)凭借其简洁的界面和强大的功能,受到了广泛的欢迎。很多用户可能在寻求关于Google浏览器电脑版的信息,今天我将为大家详细介绍它的功能、优势以及如何安装。 Google浏览器电脑版的主要特点 Google浏览器电脑版以其一系列的独特功能和用户友好的设计,使浏览网络变得更加高效。以下是几个突出的特点: 极速浏览:Chrome以其强大的引擎而闻名,加载网页的速度通常比其他浏览器快。这得益于其使用了V8 JavaScript引擎,能够迅速处理复杂的脚本。 广泛的扩展库:Chrome提供了丰富的扩展程序,可以满足各种不同需求。从广告屏蔽到在线文档编辑,你都能找到适合自己的工具。 多平台同步:通过Google账户,用户可以在不同设备间无缝同步书签、历史记录、密码等信息,让使用体验更为一致。 隐私保护与安全性:Chrome内置了强大的安全防护功能,提醒用户关于潜在的安全风险,确保上网的安全性。 简洁易用的界面:用户界面设计简单直观,操控轻松,让新用户也能快速上手。 Google浏览器电脑版的安装步骤 如果你还没有在自己的电脑上安装Google浏览器,下面的步骤将帮助你轻松完成安装: 打开你的任意浏览器,访问Google浏览器的官方网站 [e.com/chrome/](e.com/chrome/)。 点击网页上的“下载Chrome”按钮,选择你的操作系统版本。 下载完成后,双击安装包,按照屏幕上的提示进行安装。 安装完成后,打开Chrome浏览器,按照提示登录你的Google账户,实现数据同步。 常见问题解答 在使用Google浏览器的过程中,用户可能会遇到一些问题。以下是一些常见问题及其解决方法: Chrome浏览器卡顿怎么办?:可能是由于插件过多或缓存过大导致的。可以尝试禁用不常用的插件,或定期清理浏览器缓存。 如何恢复丢失的书签?:可以通过“书签—书签管理器”找到并恢复最近删除的书签。 如何使用隐身模式?:在浏览器右上角点击三点菜单,选择“新建隐身窗口”,即可开启隐私浏览模式。 为何选择Google浏览器? 对于大多数用户来说,选择Google浏览器电脑版是一种明智的选择,特别是当你需要一种快速、安全且强大功能的浏览体验时。它不仅支持多种扩展和应用,还能让用户在不同设备上都能享受流畅的使用体验。 无论你是重度网络用户还是偶尔上网的普通用户,Google浏览器的性能和灵活性都能满足你的需求,成为你日常上网的最佳伴侣。希望今天的介绍能够帮助你更好地了解并使用Google浏览器电脑版。