全部 文章 问答 分享 共找到69个相关内容
[文章] CSS如何实现文章展开阅读全文的效果?
CSS如何实现文章展开阅读全文的效果?很多网站都有这样的功能?我也不知道为什么需要这个功能,展开阅读。先是只能见一部分。
2020-03-06 15:10 · 前端 / CSS / 阅读全文
[分享] Rxjava源码阅读指南
本文不对Rxjava的基本使用进行讲解,仅对源码做分析,如果你对Rxjava的基本使用还有不清楚的,建议学习官方文档之后再阅读本文 本文会逐一解析Rxjava的create()、subscribe
2020-02-06 12:39 · Android / RxJava / 源码 / 异步
[问答] 如何实现类似于微信朋友圈的图片展示效果以及全文收起按钮功能呢?

还有就是关于文字部分,想做成可以全文,收起的形式

2022-08-17 14:50 · 安卓 / 图片展示 / 图片大小调解

[文章] 安卓端sob_blog解析阅读MarkDown文章
作为一名学习安卓的小菜鸡,自然希望在安卓上也能阅读我们写的文章。所以如果能在安卓上显示MarkDown,那可真是太爽了。考虑到前几天大锯老师在VUE里面引入了一个mavon-editor的库。
2020-08-09 17:13 · 安卓 / markDown / 源码
[文章] 《Kotlin 核心编程》阅读笔记
@[TOC](《Kotlin核心编程》阅读笔记)第四章代数数据类型和模式匹配代数数据类型(ADT)在计算机编程中,特别是函数式编程与类型理论中,ADT是一种组合类型(compositetype)。
1970-01-01 00:00 · kotlin
[分享] Android上层应用源代码
在我们学习内容提供者的时候,我们需要去阅读Android上层应用的源码,在我们学习四大组件的时候,想去打开相机呀,设置呀,系统原生应用的时候。我们需要去阅读源码,查看里的意图过滤规则。
2019-10-27 22:04 · 安卓 / 源码 / 应用 / android / app
[文章] 《kotlin核心编程》阅读笔记 第九章 设计模式
@[TOC](《kotlin核心编程》阅读笔记第九章设计模式)第九章设计模式基于Kotlin崭新的语言特性,实现或替换了Java中部分典型设计模式。
1970-01-01 00:00 · kotlin
[问答] Android系统源码 如何让相册以及视频访问指定路径下的图片及视频?

AOSP,现在我想让系统原生的图库和视频播放器,打开应用的时候,去访问指定目录下的图片和视频;请问下有相关知识可以阅读吗,不太清楚源码所在位置。我想直接修改源码然后重新编译。

2021-08-05 11:31 · Android / AOSP
[文章] 黄仁勋台大毕典演说全文
又到毕业季,来听听最新鲜热乎的演讲无论是追逐食物,或不被人当食物,你都要不停跑下去。坦诚面对错误,谦卑寻求帮助追求愿景的艰苦过程学会放弃是迈向成功的核心关键演讲是英文的如果你感觉英文还可以,可以移步B站,B站linkhttps://www.bilibili.com/video/BV1ik4y1x7Qf以下为演讲内容:(台语)大家好,我今天本来想跟你们说台语,但是⋯⋯我越想越紧张。我在美国长大的,所以我的台语不是很标准,所以我今天跟你们说英文好不好?(台下掌声)Okay,那我们开始吧!(英语)各位贵宾、各位家长,2023年的台大毕业生,大家好!今天是你们的特别日子,也是梦想成真的日子——属于你们父母的,你们要赶快离家。今天是荣耀的日子,父母亲牺牲了他们自己,成就了你们。我爸爸妈妈在这,我哥哥也在这,让我们向养育我们的父母亲展现我们的感谢。十年前我第一次来台大,陈教授邀请我来看他的物理实验室。我记得他的儿子在硅谷得知了Nvidia发明的CUDA(ComputeUnifiedDeviceArchitecture,统一计算架构)技术,建议陈教授在量子物理模拟使用它。当我抵达的时候,他秀给我看他创造的东西:整个房间的Nvidia游戏显卡,插在开放式电脑的主机板上,金属架上都是散热用的大同电扇。他以台湾人的方式,用游戏显卡做了一个超级电脑。他在这里,做了早期NvidiaJOURNEY示范。他很骄傲,他说:“黄先生,因为你的关系,我可以完成我的事业。”他说的那些话至今仍感动我,完美诠释了我们公司的价值:帮助这个时代的爱因斯坦与达文西完成他们的事业。我很高兴能再次回到台大,担任你们的致词嘉宾。给毕业生们:你们所处的年代很複杂,却也是你们的机会当我从俄勒冈州立大学毕业时,世界还比较简单。电视还很大一台,没有无线电视跟MTV、没有手机和行动电话。那是1994年,IBM个人电脑跟MAC麦金塔开始了个人电脑革命。开始日后晶片与运算程式的发展。你们正处在的世界更复杂,面临著地缘政治、社会和环境上的变化和挑战,被科技包围著。我们处于一个永远连接和沉浸的数据世界,与现实世界平行存在。在40年前,当电脑产业创造了家用PC,持续研究AI技术,我们的运算程式驾驶著汽车、或研读X光片影像。AI为电脑自动化开启了大门,其服务涵盖了世界最大的兆级产业:健康照护、金融服务、运输与制造产业。AI为我们带来了巨大的机遇,反应敏捷的企业将利用AI技术提升竞争力,而未能善用AI的企业将面临衰退。很多企业家,包含今天在场的许多人,未来将会开创新公司。如同过去的每个计算机时代能创造新的产业,AI也创造了以前不存在的新工作机会,像是:数据工程师、咏唱工程师、AI工厂操作员和AI安全工程师等,这些工作以前从未存在过。自动化工作将淘汰一些工作,并且毫无疑问的,AI会改变每一个工作,大幅加强程式设计师、设计师、艺术家、行销人员和制造计划者的工作表现。就像在你们之前的每个世代,拥抱科技以获得成功。每个公司与你必须学会利用AI的优势,在AI的帮助下做出惊人成就。有些人担心AI可能会抢走你的工作,有些人可能会让AI发展出自我意志。我们正处于一个新领域的开始,就像个人电脑、网路、移动设备与云端技术一样。但是AI的影响更为根本,每个运算层面都会被重新改写。它改变了我们撰写软件的方式、执行软件的方式。从各方面来看,这是电脑产业的再生契机,对于台湾企业而言更是一个黄金机遇。你们正是这个产业的重要基石。在下个十年,我们的产业将使用新型AI电脑取代价值上兆美元的传统电脑。我的旅程始于你们40年之前,1984年是一个完美的毕业年份,我预测2023年也将如此。我能告诉你什麽呢?今天是迄今为止你们最成功的一天,你们从台大毕业了,我也曾经成功过。在我创办了Nvidia前,我经历过失败,而且是大失败,说起来令人耻辱和尴尬,甚至几乎让我们走向毁灭。让我给你们讲3个故事,这些故事定义了Nvidia今天的样貌。1、坦诚面对错误,谦卑寻求帮助是聪明、成功人士最难学会的。我们创办Nvidia是为了创造加速运算技术。我们的第一个应用是用于个人电脑游戏的3D图形,我们发明了一种非传统的前向纹理处理技术,而且成本相对低廉。我们赢得了与SEGA建造游戏主机的合约。这吸引了游戏开发商用我们的平台开发游戏,并提供我们公司资金。但经过了一年的开发期程,我们意识到我们设计的架构是错误策略,从技术端来看是不合格的。而与此同时,微软即将宣布基于反向纹理映射和三角形的Windows95Direct3D。这代表如果我们完成了SEGA的游戏机,我们将会创造出与Windows不相容的产品;但如果我们不完成这个合约,我们就会破产。无论如何,我们都会面临倒闭的命运。我联络了SEGA执行长,向他解释我们的发明是错误的,我们无法完成合约以及游戏主机,并建议SEGA寻找其他合作伙伴。我对他说:“我们必须停下来。”但我需要SEGA全额支付我们的费用,否则Nvidia将无法继续经营。我很难为情的向SEGA执行长生提出这个要求,但令我惊讶的是,他同意了。他的理解和慷慨让我们多活了3个月,在那段时间,我们建造了Riva128,就在我们差点没钱时,Riva128震撼了新兴的3D市场,让我们开始受到关注,也拯救了公司营运。市场对我们的晶片需求旺盛,让我从4岁离开台湾后又回到了台湾。我与台积电的张忠谋先生会面,并开始一段持续25年的合作关系。我们坦诚面对错误、谦卑的寻求帮助,拯救Nvidia的存续。这些特质对于像你们这样最聪明、最成功的人而言,是最难养成的。2、追求愿景的艰苦过程塑造我们的品格在2007年,我们宣布了CUDAGPU加速计算技术,我们的期望是让CUDA成为一个程式设计模型,在科学运算、物理模拟到图像处理方面,都能提升应用程式的效能。创建一个全新的运算模型非常困难,且在历史上实属罕见。自从IBMSystem360以来,CPU的运算模型已经成为标准已有60年的时间。CUDA需要开发人员撰写应用程式,并展示GPU的优势;开发人员需要一个大型的使用者基础;大型的CUDA使用者基础,需要市场上有人购买新的应用程式。因此,为了解决先有鸡还是先有蛋的问题。我们利用我们的游戏显卡GPUGeForce,它已经拥有庞大的游戏市场,以建立使用者基础。但CUDA的成本非常高,Nvidia的利润在多年来遭受巨大的打击,我们的市值仅仅维持在10亿美元上下。我们多年的低迷表现,让股东们对CUDA持怀疑态度,并希望我们专注于提高盈利能力。但我们坚持下来,我们相信加速运算的时代将会到来,我们创建了一个名为GTC的会议,并在全球不辞辛劳的推广CUDA技术。然后CT重建、分子动力学、粒子物理学、流体动力学和图像处理等应用程式开始大量出现,我们的开发人员撰写算法,并加快了晶片运算速度。2014年,Alex在我们的GPU上进行了训练,开启AI的大爆炸,幸运的是,我们意识到了深度学习的潜力,我们冒著一切风险去追求深度学习。多年后,AI革命开始了,Nvidia成为了推动引擎。我们为AI发明了CUDA,这个旅程锻造了我们的品格,承受痛苦和苦难,是在追求愿景的路上必经之痛。3、学会放弃是迈向成功的核心关键再讲一个故事,在2010年,Google将Android系统打造成出色图形的平台,而手机行业也有调制解调器的晶片公司。Nvidia优秀的运算能力,让Nvidia成为Android系统良好的合作伙伴。我们取得成功、股价飙升,但竞争对手也很快就涌入,调制解调器制造商们也在学习如何生产运算晶片,而我们却在学习调制解调器。因为手机市场庞大,我们能抢佔市占率。然而,我们却做出艰难的决定,放弃这块市场。因为Nvidia的使命,是创造出能解决“普通电脑解决的问题”的电脑,我们应该专注在愿景上,发挥我们的独特贡献。我们的放弃获得了回报,我们创造了一个新的市场——机器人技术,拥有神经网路处理器和运行AI算法的安全架构。当时,这还是个看不见规模的市场。从巨大的从手机市场撤退,再创造一个不知道市场规模的机器人市场。然而,现在的我们拥有数十亿美元的自动驾驶、机器人技术的事业,也开创一个新的产业。“撤退”对像你们如此聪明且成功的人来说并不容易。然而,战略性的撤退、牺牲、决定放弃什麽是成功的核心,非常关键的核心。跑吧!无论如何都要保持著奔跑2023年毕业的同学们,你们即将进入一个正在经历巨大变革的世界,就像我毕业时遇到个人电脑和晶片革命时一样,你们正处于AI的起跑线上。每个行业都将被革命、重生,为新思想做好准备-你们的思想。在40年的时间裡,我们创造了个人电脑、网路、移动设备、云端技术。现在的AI时代,你们将创造什么?无论是什么,像我们一样全力以赴去追求它,跑吧!不要慢慢走。不论是为了食物而奔跑,或不被他人当做食物而奔跑。你往往无法知道自己正处在哪一种情况,但无论如何,都要保持奔跑。在你的旅程中,带上一些我犯过的错、有过的经验。希望你们能谦卑的面对失败,承认错误并寻求帮助。你们将承受实现梦想所需的痛苦和苦难,并做出牺牲,致力于有意义的生活,冲刺你们人生的事业。2023年毕业的同学们,我致以衷心向你们每一位祝贺。加油!
2023-05-30 11:21 · AI / 人工智能 / 黄仁勋 / 英伟达 / Nvidia
2019-11-18 17:27 · 美团 / 饿了么 / 分类 / 轮播图 / 安卓
[文章] google广告新创建的页面无法加载
google广告新创建的页面无法加载我一直以为是自己的问题整天在找原因,去分析别人的网站查看源码阅读英文资料然后发现别人的网站也是不行的。那怎么整呢?只能从产品的角度去优化这个问题了。晕菜。
2020-05-09 01:55 · google / 广告 / 加载 / adsense / 谷歌
[分享] 喜马拉雅FM电台项目代码
另外一个则是提高同学们的代码阅读能力。如果学习中遇到问题的话,可以发帖子提问交流,感谢大家的支持!
[问答] 64位MuPDF在android中兼容问题

目前的应用中,引入了libmupdf.so库来使用MuPDF组件,打开PDF阅读器。现在为了新的功能,加入了"arm64-v8a"后,再打开PDF就白屏了,崩了。

[问答] 这段代码我明明写了右边却没有显示右边
layout_centerHorizontal="true"android:layout_alignParentBottom="true"android:layout_marginBottom="50dp"android:text="登录即代表阅读并同意阅读条款
2019-12-05 15:00 · 代码与视频教程的问题
[文章] 《Kotlin》阅读笔记 第八章 元编程
@TOC第八章元编程Java的反射只是元编程的一种方式。示例:将dataclass转换成Map的例子。dataclassUser(valname:String,valage:Int){funtoMap(a:User):Map<String,Any>{returnhashMapOf("name"toname,"age"toage)}}这样实现有一个缺点:对每一个新的类型我们都需要重复实现toMap函数,因为每个类型都拥有不同的属性。程序和数据通过反射实现:dataclassUser(valname:String,valage:Int){funtoMap():Map<String,Any>{returnhashMapOf("name"toname,"age"toage)}}objectMapper{fun<A:Any>toMap(a:A):Map<String,Any?>{//获取A中的所有属性returna::class.memberProperties.map{m->valp=masKProperty<*>p.nametop.call(a)}.toMap()}fun<A:Any>toMap1(a:A)=run{//获取A中的所有属性a::class.memberProperties.map{m->valp=masKProperty<*>p.nametop.call(a)}.toMap()}}funmain(){for(entry1inUser("Kar",19).toMap()){println("${entry1.key}---->${entry1.value}")}for(entryinMapper.toMap(User("Jack",20))){println("${entry.key}---->${entry.value}")}for(entryinMapper.toMap1(User("Tom",18))){println("${entry.key}---->${entry.value}")}}上面代码中的两个toMap方法,是类似的。这里的a::class的类型是KClass,是Kotlin中描述类型的类型(也称为metaclass);在传入参数类型为User时,a::class则可以描述User类型的数据。这样描述数据的数据就称为元数据。什么是元编程操作元数据的编程就是元编程。程序即是数据,数据即是程序。这句话包含两个意思:前半句指的是访问描述程序的数据,如我们通过反射获取类型信息。后半句则是指:将这些数据转化成对应的程序,也就是所谓的代码生成。元编程就像高阶函数一样,是一种更高阶的抽象,高阶函数将函数作为输入或输出,而元编程则是将程序本身作为输入或输出。常见的元编程技术运行时通过API暴露程序信息反射;动态执行代码多见于脚本语言。如JavaScript就有eval函数,可以动态地将文本作为代码执行。通过外部程序实现目的如编译器,在将源文件解析成AST之后,可以针对这些AST做各种转化。这种实现思路最典型的例子是我们常常谈论的语法糖,编译器会将这部分代码AST转化为相应的等价的AST,这个过程通常被称为desuger(解语法糖)。AST:抽象语法树是源代码语法结构的一种抽象表示;它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每一个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句可以使用带有两个分支的节点来表示。反射,有时候也称为自反,是指元语言(即前文提到的描述程序的数据结构)和要描述的语言是同一种语言的特性。除了运行时反射之外,也有许多语言支持编译期反射,编译期反射通常需要宏等技术结合实现,编译器将当前程序的信息作为输入传入给宏,将其结果作为程序的一部分。宏:Koltin不支持宏。模板元编程:和Kotlin关系并不大。Kotlin的反射kotlin和Java反射Kotlin的KClass和Java的Class可以看作同一个含义的类型,并且通过.java和.kotlin方法在KClass和Class之间相互转化。Kotlin中的KCallable和Java的AccessiableObject都可以理解为可调用元素。Java中构造方法为一个独立的类型,而Kotlin则统一作为KFunction处理。Koltin中的KProperty和Java的Filed不太相同,Koltin的KProperty通常指相应的Getter和Setter(只有可变属性Setter)整体作为一个KProperty(通常情况Kotlin并不存在字段的概念),而Java的Field通常仅仅指字段本身。koltin的KClassKCLass的特别属性或函数特别属性或函数|含义--------|-----isCompanion|是否伴生对象isData|是否数据类isSealed|是否密封类objectInstance|object实例(如果是object)companionObjectInstance|伴生对象实例declareMemberExtensionFunctions|扩展函数declareMemberExtensionProperties|扩展属性memberExtensionFunction|本类及超类扩展函数memberExtensionProperties|本类及超类扩展属性starProjectedType|泛型通配类型示例:获取object实例sealedclassNat{companionobject{objectZero:Nat()}valCompanion._0get()=Zerofun<A:Nat>Succ<A>.proceed():A{returnthis.prev}}dataclassSucc<N:Nat>(valprev:N):Nat()fun<A:Nat>Nat.plus(other:A):Nat=when{otherisSucc<*>->Succ(plus(other.prev))else->this}funmain(){println(Nat.Companion::class.isCompanion)//trueprintln(Nat::class.isSealed)//trueprintln(Nat.Companion::class.objectInstance)//chapter8.Nat$Companion@646be2c3println(Nat::class.companionObjectInstance)//chapter8.Nat$Companion@646be2c3println(Nat::class.declaredMemberExtensionFunctions.map{it.name})//[proceed]println(Nat::class.declaredMemberExtensionProperties.map{it.name})//[_0]'println(Succ::class.declaredMemberExtensionProperties.map{it.name})//[]println(Succ::class.declaredMemberExtensionFunctions.map{it.name})//[]println(Succ::class.declaredMemberExtensionProperties.map{it.name})//[]println(Succ::class.memberExtensionProperties.map{it.name})//[_0]println(Succ::class.memberExtensionFunctions.map{it.name})//[proceed]println(Succ::class.starProjectedType)//chapter8.Succ<*>println(Nat::class.memberExtensionFunctions.map{it.name})//[proceed]}kotlin的KCallable如何获取Class的成员:通过members方法,它的返回值是一个Collection<KCallable<*>>。KCallable提供的APIKCallable提供的API|含义--------|-----isAbstract:Boolean<KParameter>|此KCallable是否为抽象的isFinal:Boolean|此KCallable是否为finalisOpen:Boolean|此KCallable是否为openname:string|此KCallable的名称parameters:List<KParameter>|调用此KCallable需要的参数returnType:KType|此KCallable的返回类型typeParameters:List<KTypeParameter>|此KCallable的类型参数visibility:KVisibility?|此KCallable的可见性call(varargargs:Any?):R|给定参数调用此KCallablefunmain(){val_1=Succ(Nat.Companion.Zero)valpreceed=_1::class.members.find{it.name=="proceed"}println(preceed?.call(_1,_1)==Nat.Companion.Zero)}上面代码通过反射执行Succ的扩展函数proceed,这里传入了两个Nat对象,因为执行扩展函数时,除了参数实例外,需要传入接受者实例。在Kotlin中,并不是所有的属性都是可变的,因此我们只能对那些可变的属性进行修改操作。KMutableProperty是KProperty的一个子类。使用When表达式来识别属性。dataclassPerson(valname:String,valage:Int,varaddress:String)funKMutablePropertyShow(){valp=Person("YanLq",22,"SWPU")valprops=p::class.memberPropertiesfor(propinprops){when(prop){isKMutableProperty<*>->prop.setter.call(p,"DZ")else->prop.call(p)}}println(p.address)}funmain(){KMutablePropertyShow()}获取参数信息Koltin把参数分为3个类别,分别是函数的参数(KParameter),函数的返回值(KType)以及类型参数(KTypeParameter)KParameter使用KCallable.parameters即可获取一个List<KParameter>,它代表的是函数(包括扩展函数)的参数。API描述index:Int返回该参数在参数列表里面的indexisOptiona:Boolean该参数是否为OptionalisVarags:Boolean该参数是否为varagskind:Kind该参数的kindname:String?该参数的名称type:KType该参数的类型funKParameterShow(){for(cinPerson::class.members){print("${c.name}->")for(pinc.parameters){print("${p.type}--")}println()}}funmain(){KParameterShow()}KType获取KCallable的返回值类型。每一个KCallable都可以使用returnType来获取返回值类型,它的结果类型是KType。API描述arguments:List<KtypeProjection>该类型的类型参数classifier:KClassifier该类型在类声明层面的参数,如该类型为List<String>,那么通过classifier得到结果为List(忽略类型参数)isMarkedNullable:Boolean该类型是否标记为可空类型dataclassPerson(valname:String,valage:Int,varaddress:String){funfriendsName():List<String>{returnlistOf("Yison","Jilen")}}funmain(){Person::class.members.forEach{println("${it.name}->${it.returnType.classifier}")}}>>>address->classkotlin.Stringage->classkotlin.Intname->classkotlin.Stringcomponent1->classkotlin.Stringcomponent2->classkotlin.Intcomponent3->classkotlin.Stringcopy->classchapter8.Personequals->classkotlin.BooleanfriendsName->classkotlin.collections.ListhashCode->classkotlin.InttoString->classkotlin.StringclassifierAPI其实就是获取该参数在类层面对应的类型。KTypeParameter对于函数和类来说,还有一个重要的参数——类型参数,在KClass和KCallable中我们可以通过typeParameters来获取class和callable的类型参数,它的返回结果集是List<KTypeParameter>,不存在类型参数时就返回一个空的List。dataclassPerson(valname:String,valage:Int,varaddress:String){funfriendsName():List<String>{returnlistOf("Yison","Jilen")}fun<A>get(a:A):A{returna}}funKTypeParameterShow(){for(cinPerson::class.members){if(c.name.equals("get")){println(c.typeParameters)}}vallist=listOf<String>("How")println(list::class.typeParameters)}funmain(){KTypeParameterShow()}>>>[A][E]Kotlin注解Kotlin的注解创建语法:annotationclassFooAnnotation(valbar:String)注解koltin.Metadata这是实现Kotlin大部分独特特性反射的关键,Koltin将这些信息直接以注解形式存储在字节码文件中,以便运行时发射可以获取这些数据。和Java一样注解的参数只能是常量,并且仅支持下列类型:与Java对应的基本类型字符串Class对象(KClass或者Java的Class)其他注解上述类型数组。基本类型数组需要指定为对应的XXXArray,如:IntArray而不是Array<Int>/标注在注解上的注解我们称之为元注解。Java有下列5个元注解。-Documented文档(通常是API文档)中必须出现给注解。-Inherited如果超类标注了该类型,那么其子类型也将自动标注该注解而无需指定。-Repeatable这个注解在同一位置可以出现多次。-Retention表述注解用途。有三种取值。-Sourc仅在源代码中存在,编译后的class文件不包含该注解信息。-CLASSclass文件中存在该注解,但不能被反射读取。-RUNTIME注解信息同样保存在class文件中并且可以在运行时通过反射获取。-Target表明注解可应用于何处。Kotlin也有相应类似的元注解在kotlin.annotation包下。Kotlin和Java的注解整体上保持一致。Koltin目前不支持Inherited。无处不在的注解Kotlin(AnnotationTarget)Java(Target)说明CLASSTYPE作用于类ANNOTATION_CLASSANNOTATION_TYPE作用于注解本身(即元注解)TYPE_PARAMETERTYPE_PARAMETER作用于类型参数PROPERTYNA作用于属性FIELDFIELD作用于字段(属性通常包含字段Getter以及Setter)LOCAL_VARIABLELOCAL_VARIABLE作用于局部变量VALUE_PARAMETERNA作用于val参数CONSTRUCTORCONSTRUCTOR作用于构造函数FUNCTIONMETHOD作用于函数(Java只有method)PROPERTY_GETTERNA作用于GetterPROPERTY_SETTERNA作用于SetterTYPETYPE_USE作用于类型EXPRESSIONNA作用于表达式FILEPACKAGE作用于文件开头/包声明TYPEALIASNA作用于类型别名annotationclassCache(valnamespace:String,valexpires:Int)annotationclassCacheKey(valkeyName:String,valbuckets:IntArray)@Cache(namespace="hero",expires=3600)dataclassHero(@CacheKey(keyName="heroName",buckets=intArrayOf(1,2,3))valname:String,valattack:Int,valdefense:Int,valinitHp:Int)精准控制注解位置假设我们有注解annotationclassCacheKey。精准的注释控住语法:用法|含义-|-@file:CacheKey|CacheKey注解作用于文件@property:CacheKey|CacheKey注解作用于属性@field:CacheKey|CacheKey注解作用于字段@get:CacheKey|CacheKey注解作用于Getter@set:CacheKey|CacheKey注解作用于Setter@receiver:CacheKey|CacheKey注解作用于扩展函数或属性@param:CacheKey|CacheKey注解作用于构造函数参数@setParam:CacheKey|CacheKey注解作用Setter的参数@delegate:CacheKey|CacheKey注解作用于存储代理实例的字段@Cache(namespace="hero",expires=3600)dataclassHero(@property:CacheKey(keyName="heroName",buckets=[1,2,3])valname:String,@field:CacheKey(keyName="atk",buckets=[1,2,3])valattack:Int,@get:CacheKey(keyName="def",buckets=[1,2,3])valdefense:Int,valinitHp:Int)获取注解信息代码标记上注解以后,注解本身也成为了代码的一部分。我们可以获取注解信息。通过反射获取注解信息但是前提是这个注解的Retention标注为Runtime或者没有显示注定(默认为Runtime)。annotationclassCache(valnamespace:String,valexpires:Int)annotationclassCacheKey(valkeyName:String,valbuckets:IntArray)@Cache(namespace="hero",expires=3600)dataclassHero(@CacheKey(keyName="heroName",buckets=[1,2,3])valname:String,valattack:Int,valdefense:Int,valinitHp:Int)funmain(args:Array<String>){valcacheAnnotation=Hero::class.annotations.find{itisCache}asCache?println("namespace->${cacheAnnotation?.namespace}")println("expires->${cacheAnnotation?.expires}")}>>>namespaceheroexpires3600通过反射获取注解信息是在运行时发生的。注解标准位置也会影响注解信息的获取。注解处理器JSR269引入了注解处理器(annotationprocessors),允许在编译过程中挂钩子实现代码生成,得益于此,如dagger之类的框架实现了编译时依赖注入这样原本只能通过运行时反射支持的特性。importjavax.annotation.processing.AbstractProcessorimportjavax.annotation.processing.RoundEnvironmentimportjavax.lang.model.element.ElementKindimportjavax.lang.model.element.TypeElementimportkotlin.reflect.full.memberPropertiesannotationclassMapperAnnotationclassMapperProcessor:AbstractProcessor(){privatefungenMapperClass(pkg:String,clazzName:String,props:List<String>):String{return"""package$pkgimportjava.utils.*;publicclass${clazzName}Mapper{publicMap<String,Object>toMap($clazzNamea){Map<String,Object>m=newHashMap<String,Object>();${props.map{"m.put(\"${it}\",a.${it})"}}}}""".trimIndent()}overridefunprocess(annotations:MutableSet<outTypeElement>?,roundEnv:RoundEnvironment?):Boolean{valel=roundEnv?.getElementsAnnotatedWith(MapperAnnotation::class.java)?.firstOrNull()if(el?.kind==ElementKind.CLASS){valpkg=el.javaClass.`package`.namevalcls=el.javaClass.simpleNamevalprops=el.javaClass.kotlin.memberProperties.map{it.name}valmapperClass=genMapperClass(pkg,cls,props)valjfo=processingEnv.filer.createSourceFile("${cls}Mapper")valwriter=jfo.openWriter()writer.write(mapperClass)writer.close()}returntrue}}我还不太会注解。不知道咋运行。
1970-01-01 00:00 · kotlin
[文章] 《深入理解Java虚拟机》阅读笔记-1
粗略笔记1.虚拟机介绍虚拟机家族SunClassicHostSPotVM经典虚拟机Mobile/EmbeddedVM移动端/嵌入式使用BEAJRockit/IBMJ9VMBEA/IBM公司自有虚拟机...2.内存区域与OOM内存区域java内存区域遵循《JAVA虚拟机规范》并由具体虚拟机进行划分和实现程序计数器占用空间极小,用于指示执行时字节码行号各线程程序计数器私有,不存在OOM异常java虚拟机栈描述的是JAVA方法执行的线程内存模型,方法执行时构造栈帧栈帧包含:局部变量表操作数栈动态连接方法出口hotSpot的虚拟机栈是不可以动态扩展的当线程申请栈空间失败时,会出现OOM异常可能出现的异常:线程请求时的栈深度大于虚拟机所允许的最大深度,抛出StackOverflowError如栈容量动态扩展,当无法申请到组后内存时,排除OOMError本地方法栈为虚拟机使用到的本地方法(Native)服务抛出异常与虚拟机栈相同JAVA堆虚拟机锁管理的内存中最大的一块区域,被所用线程共享、虚拟机启动时创建,用于存放对象实例(“所有的对象实例以及数组都应当在堆上分配”)JAVA堆也是垃圾收集器管理的内存区域,从回收内存角度,和垃圾分代收集理论,堆场被分配新生/老年/永久、eden/from/to等。HotSpot内部垃圾收集器基于经典分代设计。从分配内存角度,所有线程共享的java堆可以划分出多个线程私有的分配缓冲区(TLAB)以提高对象分配的效率-经典分代即新生代(包含一个eden区和两个survivor区)、老年代划分JAVA方法区各个线程共享的内存区域,主要用于存放被虚拟机加载的类型信息、常量、静态变量、即时编译后的代码缓存等《JAVA虚拟机规范》中方法区的描述是堆的一块逻辑部分jdk1.8以前,HotSpot虚拟机的方法区的实现称为永久代,部分数据占用堆内存1.8及之后,HotSpot虚拟机方法区的实现称为元空间,使用本地内存在方法区的垃圾回收主要目的是针对常量池的回收和对类型的卸载,类型的未完全回收有概率引发内存泄漏,从而造成OOM异常对象的创建方法区检查Class类是否被加载,如果没被加载,则进行类文件加载读取Class类元数据,分配堆空间给新对象堆空间规整:指针碰撞堆空间杂乱:空间列表多线程并发:TLABORCAS+失败重试分配的内存空间归零处理,根据类元空间设置对象头信息,调用<init>()方法,完成对象资源的初始化对象构成:[对象头]+[实例数据]+[对齐填充]对象头针对于HotSpot虚拟机,对象头由动态数据结构(Markwork)和类型指针组成-动态数据结构一个有着动态定义的数据结构,根据对象的状态复用自己的存储空间用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标识、偏向锁线程ID、偏向锁时间戳等等数据长度:32比特(32位系统)、64比特(64位系统)Markwork对象哈希码(25bit)对象分代年龄(4bit)锁标志位(2bit)固定0(1bit)类型指针对象指向它的类型元数据的指针,java通过这个指针来确定该对象是哪个类的实例如果对象是一个java数组,那么在对象头中还必须有一块用于记录数组长度的数据。对象的访问定位使用句柄池间接访问堆中对象使用直接指针指向堆中对象调试参数用于堆设置堆最大值-Xms设置堆最小值-Xmx内存溢出时Dump出当前内存堆转储快照-XX:+HeapDumpOnOutOfMemoryError虚拟机栈设置栈容量-Xss用于方法区<=jdk6设置永久代最小-XX:PermSize>=jdk7设置永久代最大-XX:MaxPermSize>=jdk8设置元空间最大值-XX:MaxMetaspaceSize设置元空间初试大小-XX:MetaspaceSize控制垃圾收集后元空间最小剩余容量百分比-XX:MinMetaspaceFreeRatio
2022-10-29 21:50 · java / 虚拟机 / 阅读笔记
[文章] Android开发RecyclerView的适配器notifyDataSetChange做了什么?
接下来我们就阅读一下源码,adapter跟recyclerView是如何通讯的!
2019-11-02 21:05 · RecyclerView / 安卓开发 / 适配器 / adapter
[文章] 《Kotlin核心编程》阅读笔记 第七章 多态和扩展
@TOC第七章多态和扩展Kotlin的扩展其实多态的一种表现形式。多态的不同方式多态是面向对象程序设计的一个重要特性。当用一个子类继承一个父类的时候,这就是子类型多态(Subtypepolymorphism)。另一种熟悉的多态是参数多态(Parametricpolymorphism)。子类型多态用子类型替换超类型实例的行为,就是子类型多态。参数多态理解起来像是把参数抽成一个类型,类似泛型的感觉。对第三方进行扩展即扩展函数。扩展属性和扩展方法的实现是运行在类的实例上,不会修改类本身。特设多态和运算符重载特设多态:一个多态函数是有多个不同的实现,依赖于其实参而调用相应版本。operator:将一个函数标记为重载一个操作符或者和实现一个约定。dataclassArea(valvalue:Double)operatorfunArea.plus(that:Area):Area{returnArea(this.value+that.value)}funmain(){println(Area(1.0)+Area(2.0))}还可以重载减法minus、乘法times、除法div等扩展:为别的类添加方法、属性扩展与开放封闭原则软件实体应该是可扩展,而不可修改的。开放封闭原则开放封闭原则(OCP:OpenClosedPrinciple)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为了实现这一目标服务的,例如以替代原则实现最佳、正确的继承层次,就能保证不会违背开放封闭原则。使用扩展函数、属性funMutableList<Int>.exchange(fromIndex:Int,toIndex:Int){valtmp=this[fromIndex]this[fromIndex]=this[toIndex]this[toIndex]=tmp}这里扩展函数体里的this代表的是接收者类型的对象。标准库中的扩展函数:run、let、also、takeIfrunrun方法的定义:publicinlinefun<T,R>T.run(block:T.()->R):R=block()run是任何类型T的通用扩展函数,run中执行了一个返回值类型为R的扩展函数block,最终返回扩展函数的结果。let定义:publicinlinefun<T,R>T.let(block:(T)->R):R=block(this)let返回的是闭包里面的值。dataclassStudent(age:Int)classKot{valstudent:Student?=getStu()fundealStu(){valresult=student?.let{println(it.age)it.age}}}also定义:publicinlinefun<T>T.also(block:(T)->Unit):T{block(this)returnthis}函数的返回值是该函数的接收者。classKot{valstudent:Student?=getStu()fundealStu(){valresult=student?.also{stu->this.age+=stu.ageprintln(this.age)println(stu.age)this.age}}}takeIf如果我们不仅仅只想判断空,还想加入条件,这是let可能显得有点不足。定义:publicinlinefun<T>T.takeIf(predicate:(T)->Boolean):T?=if(predicate(this))thiselsenull当接收器满足某些条件才会执行。把之前的也写一下:with和applywith的定义:inlinefun<T,R>with(receiver:T,block:T.()->R):Rwith的第一个参数为接收者类型,然后通过第二个参数创建这个类型的block方法。apply的定义:inlinefun<T>T.apply(block:T.()->Unit):T看这些定义还是有点晕的。写代码时,在编译器的提示感觉会好点。
1970-01-01 00:00 · kotlin
[问答] Android项目的 “移植” “引用” 问题
或者有什么文章是讲述类似操作的我一定好好阅读、万分感谢!!!
2020-06-18 12:17 · anroid
[文章] 《Kotlin核心编程》阅读笔记 第五章 类型系统
第五章类型系统null引用在Java中如何解决空指针异常:函数内对于无效值,更倾向于抛异常处理。采用@NotNull/@Nullable标注使用专门的Optional对象对可能为null的变量就行装箱。可空类型在Kotlin中,可以在任何类型后面加上“?"Int?等同于Intornull由于null只能被存储在Java的引用类型中,所以在Kotlin中基本数据类型的可空版本都会使用该类型的包装形式,同样,如果使用基本数据类型作为泛型类的类型参数,Koltin同样会使用该类型的包装类。-安全调用"?."XXX?.YYY:当XXX不为null,才调用YYY-Elvis操作符"?:"或合并操作符。-非空断言"!!"类型检查:在Koltin中用is代替Java中的instanceof当类型需要强制转换时,可以利用"as"操作符来实现。Any:非空类型的根类型Kotlin把Java方法参数和返回类型中用到的Object类型看作Any(更确切的说是当作“平台类型”);Any?:所有类型的根类型。Nothing与Nothing?:Kotlin类型层级结构的最底层是Nothing类型。Nothing是没有实例的类型,Nothing类型的表达式不会产生任何值。它只能包含一个值“null”。自动装箱和拆箱Kotlin中的Int类型等同于int;Kotlin中的Int?等同于Integer;Kotlin中有Array,但是并不是一种原生的数据结构,而是一种Array类。甚至我们可以将Kotlin中的Array视作为集合类的一部分。Kotlin中还为原始类型额外引入了一些实用类:IntArray,CharArray,ShortArray等。分别对应了Java中的int[]、char[]、short[].IntArray等并不是Array的子类。Kotlin对原始类型有特殊优化,推荐使用原始类型数组。泛型将参数的类型进行参数化。泛型的优势:类型检查,能在编译时就帮你检查出错误。更加语义化,比如声明一个List<String>,便可以知道里面存储的是String对象,自动类型转换,获取数据时不需要进行类型强制转换;能写出更加通用的代码。在Kotlin中使用泛型的格式也是<T>,<S>类似的。声明一个泛型类和泛型函数:实现定义一个find方法,传入一个对象,若列表中存在该对象,就返回该对象,不存在则返回空;classSmartList<T>:ArrayList<T>(){funfind(t:T):T?{valindex=super.indexOf(t)returnif(index>=0)super.get(index)elsenull}}funmain(){valsmartList=SmartList<String>()smartList.add("qq")println(smartList.find("qq"))println(smartList.find("aa"))}除了上述做法,还可以有扩展函数;funmain(){valarrayList=ArrayList<String>()arrayList.add("qq")println(arrayList.find("qq"))println(arrayList.find("aa"))}fun<T>ArrayList<T>.find(t:T):T?{valindex=this.indexOf(t)returnif(index>=0)this[index]elsenull}类型约束:设定类型上界;示例;需求为:有一把刀只能用来切长在地上的水果(如西瓜)interfaceGround{}openclassFruit(valweight:Double)classApple(weight:Double):Fruit(weight)classBanana(weight:Double):Fruit(weight)classFruitPlate<T:Fruit>(valt:T)//:类型约束,表示只能装水果的盘子classWatermelon(weight:Double):Fruit(weight),Groundfun<T>cut(t:T)whereT:Fruit,T:Ground{println("Youcancut")}funmain(){cut(Watermelon(5.0))}通过where关键字,他可以实现泛型参数类型添加多个约束条件。上面的泛型是在静态时的行为,也就是Kotlin代码编译阶段关于泛型的知识点。publicclassTestArray{publicstaticvoidmain(String[]args){Apple[]applyArray=newApple[10];Fruit[]fruitArray=applyArray;//fruitArray[0]=newBanana(0.5);List<Apple>appleList=newArrayList<Apple>();//List<Fruit>fruitList=appleList;System.out.println(applyArray.getClass());System.out.println(appleList.getClass());}}>>>class[Lchapter5.Apple;>>>classjava.util.ArrayList数组是协变的,而List是不变的。简单来说就是Object[]是所有对象数组的父类,而List<Object>却不是List<T>的父类。从上面的打印结果可以知道,数组在运行时是可以获取自身的类型,而List<Apple>在运行时只知道自己是一个List,而无法获取泛型参数的类型。而Java数组是协变的,也就是说任意的类A和类B,若A是B的父类,则A[]也是B[]的父类。但是假如给数组加入泛型后,将无法满足数组协变的原则,因为在运行时无法知道数组的类型。Kotlin中的泛型机制和Java中是一样的,上面的特性Kotlin中也存在。类型擦除:Java受限于先后兼容的困扰,使用了类型擦除来实现了泛型,但是它还是通过其他方式来保证了泛型的相关特性。泛型在编译后是会擦除泛型类型的,而泛型的一些相关特性,比如类型检查是在编译器在编译前就会帮我们进行类型检查,类型自动转换是通过强制类型转化来实现的。类型擦除的矛盾:在某些场景需要知道运行时泛型参数类型。既然编译后会擦除泛型参数类型,那我们是不是可以主动指定参数类型来达到运行时获取泛型参数类型的效果呢?funmain(){valapplePlate=Plate(Apple(1.0),Apple::class.java)applePlate.getType()}openclassPlate<T>(valt:T,privatevalclazz:Class<T>){fungetType(){println(clazz)}}使用这种方法确实可以到达运行时获取泛型类型参数的效果,但是这样也有限制。vallistType=ArrayList<String>()::class.java//不被允许还可以使用匿名内部类来是实现。funmain(){vallist1=ArrayList<String>()vallist2=object:ArrayList<String>(){}println(list1.javaClass.genericSuperclass)println(list2.javaClass.genericSuperclass)}>>>java.util.AbstractList<E>java.util.ArrayList<java.lang.String>现在可以设计一个能获取到所有类型信息的泛型类:importjava.lang.reflect.ParameterizedTypeimportjava.lang.reflect.TypeopenclassGenericsToken<T>{vartype:Type=Any::class.javainit{valsuperClass=this.javaClass.genericSuperclasstype=(superClassasParameterizedType).actualTypeArguments[0]}}funmain(){valgt=object:GenericsToken<Map<String,String>>(){}println(gt.type)}Gson也是使用的类似方法。在Kotlin中除了用这种方式来获取泛型参数类型以外,还有另一种方式——内联函数。Kotlin中的内联函数在编译的时候编译器便会将相应函数的字节码插入调用的地方。Java并不支持主动指定一个函数是否是内联函数,所有在Kotlin中声明的普通内联函数可以在Java中调用,因为他不会被当做一个常规函数;而用reified来实例化的参数类型的内联函数则不能在Java中调用,因为它永远是需要内联的。打破泛型不变Kotlin中的List与Java的List有区别虽然都叫List,也同样支持泛型,但是Kotlin中的List定义的泛型参数前面多了一个out关键字。这个关键字就对这个List的特性起到了很大作用。普通方式定义的泛型是不变的,简单来说就是不管类型A和类型B是什么关系,Generic<A>与Generic<B>(Generic代表泛型类)都没有任何关系。在Java中String是Object的子类型,但是List<String>并不是List<Object>的子类型。在Kotlin中泛型的原理是一样的。但是,Kotlin的List为什么允许List<String>赋值给List<Any>呢?一个支持协变的List如果在定义泛型类和泛型方法的泛型参数前面加上out关键词,说明这个泛型类及泛型方法是协变的。类型A是类型B的子类型,那么Generic<A>也是Generic<B>的子类型。因为Kotlin的List支持协变,所以他无法添加元素,只能从里面读取内容;List一旦创建就不能再被修改。这便是将泛型声明为协变需要付出的代价。通常情况下,若一个泛型类Generic<outT>支持协变,那么它里面的方法的参数类型就不能使用T类型,因为一个方法的参数不允许传入参数父类型的对象,可能会导致错误。可以添加**@UnsafeVariance**注解来解除这个限制。一个支持逆变的Comparator逆变:类型A是类型B的子类型,但是Generic<B>反过来又是Generic<A>的子类型。加上现在需要对一个**MutableList<Double>**进行排序,利用其sortWith方法,我们需要传入一个比较器:valdoubleComparator=Comparator<Double>{d1,d2->d1.compareTo(d2)}funmain(){valdoubleList=mutableListOf(2.0,3.0)doubleList.sortWith(doubleComparator)for(iindoubleList){print("$i")}}但是如果又需要对MutableList<Int>,**MutableList<Long>**等进行排序,那我们可能又需要定义不同的Comparator。试想定义一个比较器,给这些列表用,这些数字类的共同父类是Number类。valnumberComparator=Comparator<Number>{num1,num2->num1.toDouble().compareTo(num2.toDouble())}funmain(){valdoubleList=mutableListOf(2.0,3.0)doubleList.sortWith(numberComparator)for(iindoubleList){print("$i")}println()valintList=mutableListOf(5,1)intList.sortWith(numberComparator)for(iinintList){print("$i")}}结果是成功运行了,这说明是可以这样做的。publicfun<T>kotlin.collections.MutableList<T>.sortWith(comparator:kotlin.Comparator<inT>/*=java.util.Comparator<inT>*/):kotlin.Unit{/*compiledcode*/}这里又出现了一个in关键词、和out类似,它也是泛型有个另一个特性——逆变:类型A是类型B的子类型,但是Generic<B>反过来又是Generic<A>的子类型。用out关键字声明的泛型参数类型将不能作为方法的参数类型,但是可以作为方法的返回值类型。而in刚好相反。协变和逆变类型通配符代替泛型参数,Java中的泛型类型通配符为"?",而Koltin中用"*"来表示类型通配符。
1970-01-01 00:00 · kotlin
[文章] 【领券联盟】笔记:视频46,47,48,49-解决刷新控件的事件冲突问题
mRecyclerView.canScrollVertically(1);}returnfalse;}代码很少,老师讲的很多很细,具体内容原理请看视频视频链接【领券联盟】46-添加refresh刷新控件的模块依赖【领券联盟】47-阅读刷新控件的源码
2020-04-02 19:41 · 课堂笔记
[文章] MySQL 索引
A:聚簇索引、非聚簇索引、唯一索引、主键索引、联合索引、全文索引、单列索引、多列索引、复合索引、普通索引、二级索引、辅助索引、次级索引、有序索引、B+Tree​​索引、R-Tree​​索引、T-Tree​​
2023-01-03 11:04 · MySQL / 数据库
[分享] 《书海航线:从历史主线探索世界,轻松选择您的阅读之路》
文章推荐呀,不喜欢看文字的可以看视频,听声音。
2024-03-08 11:07 · 读书 / 经验 / 技巧 / 历史 / 书籍
[文章] 程序员必做的文史题目
——《庄子》B:贪心;回溯;穷举;分治;递归;三、阅读理解(阅读下文,回答后面的问题):美国的贝尔实验室设计了最初的C语言刻在UNIX操作系统距今已有三四十年你在屏幕前凝视数据的缱绻我却在旁轻轻敲打键盘把你的梦想展现循环递归贪心动规是谁的从前喜欢在匈牙利算法中你我牵手的画面经过
2019-10-21 12:37 · 搞笑 / 程序员 / 日常
[文章] 程序员如何解决问题呢?
代码阅读:开源的代码没有秘密,里面的实现原理都给你看了,你还想怎么样呢?所以大家要提升自己的代码阅读能力。一些IDE的快捷键,使用技巧,debug技巧。
2019-11-02 03:41 · 奇淫技巧 / 程序员 / 解问题 / bug / 程序猿
[文章] 前端css的心得(非专业前端开发)
载入样式的时候两个都载入,方便管理和阅读。如果服务器资源更新了,如何让浏览器加载新的内容呢?后台如何通过代码让浏览器更新静态资源?
2020-01-17 12:58 · css / html / 样式 / 前端
[问答] leetcode面试题 17.16. 按摩师 代码提交执行超时
https://leetcode-cn.com/problems/the-masseuse-lcci/阅读前两个提示之后尝试递归解决测试用例:[104,209,137,52,158,67,213,86,141,110,151,127,238,147,169,138,240,185,246,225,147,203,83,83,131,227,54,78,165,180,214,151,111,161,233,147,124,143
2020-03-24 13:13 · JavaScript
[文章] [异性朋友]时间线梳理
发现第一篇文章中的时间线不够明确,于是写一个时间线的梳理方便阅读。没有提到删好友的就是还有好友。另外读本科之后和班上整体氛围合不来,不再有新认识的异性。故目前为止不会有本科阶段的故事。
2022-05-28 11:17 · 时间线
[文章] 你的2019总结来了吗?【有奖征文】
2019和展望2020可以是以下题材:年终总结所学习到的内容技术文章求职经历,经验2020目标规则参与条件:注册用户评分规则评审团打分:占5分(注重内容)点赞数:占4分(文章末尾可以提示用户喜欢的话点赞)阅读
[文章] Google应用内支付
前言之前阅读过一篇通过AIDL方式集成Google支付的文档,想看的,可以去阅读一下。但是呢?这个文档只能适用于API3.0以前的版本,不适用于新版的API,所以还是不推荐去阅读
2023-04-25 14:40 · Android / Kotlin / 支付 / Google
  • 1
  • 2
  • 3