详情

全站展示位

Don’t Store Data in the Application Object |

There is always some information that is needed in many places in your app. It can be a session token, the result of an expensive computation, etc. It is often tempting to avoid the overhead of passing objects between activities or keeping those in persistent storage. A pattern that is sometimes suggested is to dump your data in the Application object with the idea that it will be available across all activities.。。。

推荐

琥珀之月,空谷之兰,皆是孤芳,既是孤芳,但求自赏便罢!

30字的完美简历[转载] |

这个世界上,总有很多人很自以为是地以为若是他们做不到的事情,别人做到了,必定不是什么光彩的正道,必定不是靠自己的实力。包括我。 曾经看到托福GMAT拿满分的人,就会想着:“怎么可能!这个人肯定是小时候在国外生活过吧!” 看到保养地特别好的中年女人,就会撇嘴:“肯定是花重金打玻尿酸啊这针那针啊!” 看到年纪貌美的女孩开着豪车经过,就会想着:“肯定是二奶呀!” 看到年纪轻轻上了富豪榜的青年才俊,就会揣测:“肯定是家族企业啊!” 看到年少成名靠参加选秀红遍大江南北的歌手明星,就会怀疑人家:“估计是被潜规则了。” …… 这样的例子几乎每天都发生着,我也曾一度全然不觉自己在这样的渊里越堕越深。 直到大四有一次去参加一个牛逼公司的面试,面试通知邮件里最后有一条是:请携带不超过30字的Personal Statement(简称PS,个人陈述)。 我一看,疯了吧?30字?!我挨个把自己工作实习过的公司名字和读过书的学校名字列一遍都不止30个字了啊?!我想了想,绝对不可能!应该是他们漏写了个0吧?于是便也不去多想了。 等到面试那天,我带了份自认为已经是非常简洁的PS过去,一路上都觉得真是憋屈啊,很多东西没写进去呢实在没有发挥我洋洋洒洒的特点,都没充分展示我的闪光点呢!但是没办法还是尽量符合这个公司简洁精准的办事风格来吧。 到了公司,我递交上我的PS后,三个面试官不约而同皱起了眉头,一个头发花白的外国男人问我:“你这个字数超过30字了,起码得有400字吧,为什么不按我们的要求做?” 我愣了一下,什么?真的是30字?不是逗我玩? 我有点怀疑地说:“30字?30字写一篇PS根本是不可能做到的呀!这字数也太少了吧!” 一个女面试官很凌厉的口气说:“不可能?不可能的事情我们怎么会要求你做?”她说着把一叠PS亮在我面前,“他们都可能,为什么只有你不可能?” 我刷地一下脸就红了,支吾着说不出话。这是我唯一一次期待着面试官赶紧说:“好了可以了,请你出去吧。” 但是试场里出现里几秒钟的沉默,这几秒钟对我来说,竟然跟失眠的夜晚一样难熬。 那花白头发面试官又开口了:“你觉得这个世界上不可能的事情,是因为你没有试着去做。” 我犹豫了一下说:“谢谢您。我知道我的问题出在哪里了。不知道是否方便让我看一眼其他人的PS,我想知道自己的差距有多大。” 他们几个互相望了一下,点头示意后将一沓PS递给我。 我在拿过来的一瞬间已经被最上面的一份震惊到了。 那整张纸上画了一个应该是以面试者自己为原型的卡通人物,最上面是他的名字,然后是一个巨大的脑袋,脑袋顶部是开放的,用一大片电脑芯片画成了原始森林的样子,旁边写着“computerized mind”,左手拿着画板,写着“Photoshop Skiller ”,右手举着一叠报告,写着“Reportexpert”, 中间的领带处别着个话筒,上面写着“Good Presenter”,心脏的位置画了一颗奇形怪状的心,写着“Creative heart”,脚踩锃亮的皮鞋,穿着毫无褶皱的西裤,旁边写着“Detail-cared”…… 我一边看,一边手心出汗。 这样一份不超过20个单词的PS,我在看完四年后的今天还能够一字不差地回想起来,并且画面栩栩如生,你可以想象它当时带给我的震惊,以及给面试官们带来的印象有多深刻。 接下来的一沓PS里,有画一个大转盘,写出自己的几个特质的;有在一条竖直的时间轴上写了自己做成的几件大事的;还有剪切了几幅自己参加过的作品粘上去的…… 总之没有一个是多于30个字的! 但是每一份PS我看完都如同看到了一个活生生的人站在我面前,我知道他的个性如何,特长是什么,有过什么值得称赞的荣誉。 而我那张全是字的白纸,恐怕人家连看都不想看,即使看了,也不会留下任何印象。 我很不好意思地将一摞纸还给面试官,很诚恳地鞠了一躬,“很抱歉浪费了你们的时间,在来这里之前,我总觉得有些事我做不到,就是不可能做的到的。谢谢你们让我知道我的想法有多愚蠢。谢谢。” 我关上身后那扇门的时候,长长地吁了一口气。 回去的一路,都走的很慢。 我不是在难过失掉了这么一个工作机会,而是在难过地回想在过去的十几年光阴里我究竟失掉了多少次机会?让本该存在的可能,成了我嘴里的不可能。 我明白了一个让人很恼火去承认的事实就是: 那些我觉得不可能的事情,其实根本不是不可能,只是我认为不可能而已。 对一个根本不会去思考去想办法的庸人来说,很多事情都会成为不可能! 后来我试着去做一份字数在30字以内的简历,用了四个晚上后,真的也做出来了。 后来我试着再去做另一份简报似的简历,在用了三个晚上后,同样也真的做出来了。 而在之前,我认为简历就该是白纸黑字,从教育背景到工作经验到兴趣爱好,但其实它充满了那么多的可能性! 可是真的该如此理所当然吗? 我们自己不可能做到,真的是因为我们无能,还是我们根本没有尝试去做? 托福考满分的同学,说不定我们没看到的是,人家起早摸黑悬梁刺股每天练口语练到喉咙发炎; 开着豪车的美女,说不定我们没看到的是,姑娘辛苦打拼几年每天工作累得像狗辛苦攒钱; 保养的很好的中年女人,说不定我们没看到的是,她们每天下班后还去健身房睡觉一定不趴着睡,每晚一定做面膜,十几年如一日; 优秀的青年企业家们,说不定我们没看到的是,他们无数个不眠不休的夜晚,付出比我们这些在睡梦中的人多的多的努力; 那些一朝红遍全国的明星,说不定我们没看到的是,人家之前十几年的默默无闻用心苦练基本功…… 我们什么都没看到,就说别人不可能;我们什么都没去尝试,就说这事不可能。 其实,我们觉得不可能做到的事情,别人真的可以做到。对一个根本不敢去做的人来说,一切都是不可能。 想是问题,做是答案,有时候答案就藏在问题后面!

Android Jetpack Compose 超快速上手指南 |

Compose 介绍 Jetpack Compose发布也快有一年的时间了,虽然目前仍是DEV阶段,但是距离可用已经不远了。Compose库是用响应式编程的方式对View进行构建,可以用更少更直观的代码,更强大的功能,能提高开发速度(可以参考几乎一模一样的Flutter,开发速度确实很快)。 Jetpack Compose对于没有接触过声明式UI的小伙伴可能会学习曲线有点陡峭,对于已经能熟练开发Flutter应用的小伙白来说几乎没有难度。(Compose就是参考flutter的模式开发的,代码中还可以看到Flutter的相关注释) 这篇文章不回去解释过多的原理与技巧,只要是让你能够快速上手开发项目。 Compose 如何使用 因为目前(2020年09月27日)Compose仍处于开发阶段,所以需要使用最新 Canary 版的 Android Studio 预览版。 可以选择直接创建Empty Compose Activity来创建一个全新的Compose应用,或者可以选手动修改gradle的方式来创建Compose应用 修改Gradle 在模块的build.gradle文件中新增: android { ... kotlinOptions { jvmTarget = '1.8' useIR = true } buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion compose_version kotlinCompilerVersion '1.4.0' } } dependencies中新增: implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.ui:ui-tooling:$compose_version" 目前最新的Compose版本是1.0.0-alpha03 使用Compose最低的buildTools版本要求为29 使用 @Compose 所有关于构建View的方法都必须添加@Compose的注解才可以。并且@Compose跟协程的Suspend的使用方法比较类似,被@Compose的注解的方法只能在同样被@Comopse注解的方法中才能被调用

解决 golang IDEA中不能debug问题 |

IDEA是2018-01版本,Golang是go-1.12.1,IDEA在Plugins中安裝的Go插件,我在运行go程序時是正常的,但是提示could not launch process: decoding dwarf section info at offset 0x0: too short 解決方案: 1:在终端运行 go get -u github.com/derekparker/delve/cmd/dlv。 2:运行上面的命令之后运行环境中就有dlv了。替换IDEA go 插件中的dlv macOS中的插件地址是:/Users/用户名 /Library/Application Support/IntelliJIdea2018.1/intellij-go/lib/dlv/mac 替换之后就正常了。

心灵鸡汤

孩子高考 家长牵挂

文/洛水无痕

儿子参加高考那年,前一天晚上,我和他爸已经把该带的文具、证件等都准备好了,早上起来后又仔细检查了一遍,才送儿子到考场门口。看着他和同学说笑着进了考场,我们才离开。

上午考语文,我担心儿子考不好,回到家后六神无主,坐卧不安。下午考数学,这是儿子的强项,我很放心,可他爸又担心起来,和我上午的症状一模一样。一天下来,儿子到家该吃吃、该睡睡,哪知道父母受尽了折磨。

第二天下午,英语考试结束的铃声响后,孩子们走出考场,家长们笑着迎上去,到处是关切的问询声,有的父母还给孩子送上大捧鲜花。

遥想20多年前我参加高考时,带队老师带着我们一大帮通过预选的考生,提前坐长途汽车到县城,找个旅社住下,吃大锅饭,住六人间。两个晚上我都是吃过晚饭,在县城里散散步,然后回到旅社呼呼大睡。第一天考完后,在县城的二哥来看我,简单问了几句就走了。看着别人的父母对考生嘘寒问暖,我当时还真有些怪父母不把我参加高考当回事。

后来听母亲说,高考结束后,她心里着急,还特意跑到集会上找“算命仙儿”给我算了一卦。原来,母亲以这种方式牵挂我参加高考。

又到一年高考时,回想我和儿子参加高考的情景,相似之中又有不同,但天下父母牵挂儿女的心是一样的。

列表展示

主站展示位

软件开发 |

琥珀之月,空谷之兰,皆是孤芳,既是孤芳,但求自赏便罢!

GetX Router 设置返回值 |

通过别名导航: var result = await Get.toNamed(Routes.WEB_VIEW, arguments: { "url": item?.link ?? "", "index": index, "collect": item?.collect ?? false, }); 返回值: Get.back(result: {"collect": collect.value}); 完整代码: () async { /// 导航到新的界面 var result = await Get.toNamed(Routes.WEB_VIEW, arguments: { "url": item?.link ?? "", "index": index, "collect": item?.collect ?? false, }); /// 接收返回值 bool collect = result["collect"]; }

RecyclerView里notifyItemRemoved的坑 |

RecyclerView很多时候是展示静态的数据,并不会有删除的操作,讲到RecyclerView时,会提到它提供了一个很好的展现删除操作动画的函数,代码片段一般是这样的 @Override public void onBindViewHolder(final CommonViewHolder holder, final int position) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { contentList.remove(position); notifyItemRemoved(position); } }); } 这样写的话,很快会产生数据删除错乱和超出索引异常导致崩溃。 原因是函数里面的传入的参数position,它是在进行onBind操作时确定的,在删除单项后,已经出现在画面里的项不会再有调用onBind机会,这样它保留的position一直是未进行删除操作前的postion值。 对于尚未进入画面的单项来说,它会使用新的position值,这个值是正确的,如果在单项里加上下面的代码 holder.textView.setText(contentList.get(position) + "#" + String.valueOf(position)); 在删除第一屏的一项后,向上滚动,会发现新滚上来的一行和它上面的一行的textview显示是一样的。 解决办法也很简单 先remove,再notifyItemRemoved, 最后再notifyItemRangeChanged remove:把数据从list中remove掉, notifyItemRemoved:显示动画效果 notifyItemRangeChanged:对于被删掉的位置及其后range大小范围内的view进行重新onBindViewHolder

【MongoDB for Java】Java操作MongoDB |

一、准备工作 1、 首先,下载mongoDB对Java支持的驱动包 驱动包下载地址: mongoDB对Java的相关支持、技术: 驱动源码下载: 在线查看源码:

Flutter |

琥珀之月,空谷之兰,皆是孤芳,既是孤芳,但求自赏便罢!

Android ListView 与 RecyclerView 对比浅析—缓存机制 |

一,背景 RecyclerView是谷歌官方出的一个用于大量数据展示的新控件,可以用来代替传统的ListView,更加强大和灵活。 最近,自己负责的业务,也遇到这样的一个问题,关于是否要将ListView替换为RecyclerView? 秉承着实事求是的作风,弄清楚RecyclerView是否有足够的吸引力替换掉ListView,我从性能这一角度出发,研究RecyclerView和ListView二者的缓存机制,并得到了一些较有益的”结论”,待我慢慢道来。 同时也希望能通过本文,让大家快速了解RecyclerView与ListView在缓存机制上的一些区别,在使用上也更加得心应手吧。 PS:相关知识: ListView与RecyclerView缓存机制原理大致相似,如下图所示: 过程中,离屏的ItemView即被回收至缓存,入屏的ItemView则会优先从缓存中获取,只是ListView与RecyclerView的实现细节有差异.(这只是缓存使用的其中一个场景,还有如刷新等) PPS:本文不贴出详细代码,结合源码食用更佳! 二. 正文 2.1 缓存机制对比 层级不同: RecyclerView比ListView多两级缓存,支持多个离ItemView缓存,支持开发者自定义缓存处理逻辑,支持所有RecyclerView共用同一个RecyclerViewPool(缓存池)。 具体来说: ListView(两级缓存): RecyclerView(四级缓存): ListView和RecyclerView缓存机制基本一致: 1). mActiveViews和mAttachedScrap功能相似,意义在于快速重用屏幕上可见的列表项ItemView,而不需要重新createView和bindView; 2). mScrapView和mCachedViews + mReyclerViewPool功能相似,意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的ItemView重用. 3). RecyclerView的优势在于a.mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;b.mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势.客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。 缓存不同: 1). RecyclerView缓存RecyclerView.ViewHolder,抽象可理解为: View + ViewHolder(避免每次createView时调用findViewById) + flag(标识状态); 2). ListView缓存View。 缓存不同,二者在缓存的使用上也略有差别,具体来说: ListView获取缓存的流程: RecyclerView获取缓存的流程: 1). RecyclerView中mCacheViews(屏幕外)获取缓存时,是通过匹配pos获取目标位置的缓存,这样做的好处是,当数据源数据不变的情况下,无须重新bindView: 而同样是离屏缓存,ListView从mScrapViews根据pos获取相应的缓存,但是并没有直接使用,而是重新getView(即必定会重新bindView),相关代码如下: //AbsListView源码:line2345 //通过匹配pos从mScrapView中获取缓存 final View scrapView = mRecycler.getScrapView(position); //无论是否成功都直接调用getView,导致必定会调用createView final View child = mAdapter.getView(position, scrapView, this); if (scrapView != null) { if (child != scrapView) { mRecycler.

用组合代替继承能为 Activity 带来什么 |

原文链接 : Composition over Inheritance,What it means for your Activities 原文作者 : Josh Brown 译者 : chaossss 校对者: Mr.Simple 状态 : 完成  事实上我们在很多 Java 进阶书籍上看到过“开发时应该更倾向于选择组合而不是继承”的建议,为什么建议我们更倾向于而不是完全代替呢,因为当类 A 能完全代替另一个类 B(我们想让 B 成为 A 的父类)时,我们就应该使用继承,如果 A 仅仅是和 B 有着某些共同的行为,是不应该使用继承的(更多的讨论戳我)。然而,在我阅读别人的源码时,滥用继承的情况实在是太多了,多少人创建了一个 BaseActivity 后,就让所有 Activity 继承它,在子 Activity 中实现业务逻辑。  而且这样做问题大大的有,最鲜活的例子就是:Joe Newguy 加入到我们组,并实现了 ShinyFeatureActivity,那会组里没有任何规定强迫他必须让 ShinyFeatureActivity 继承于 BaseActivity,但他还是这么干了……万幸我们在 Code Review 时发现了这个问题。此外,如果每一个 Activity 都继承于 BaseActivity,在某些情况下,你可能要继承的是其他 Activity(例如:PreferenceActivity、ListActivity)。尽管大部分 Activity 的子类都有相应的 Fragment 代替,但还是有一部分是没有对应 Fragment 的,某些库仍然需要相应的 Activity 子类。  有些更潜在的问题是:有时候某些 Activity 需要这些行为,其他的 Activity 需要其他行为,而 Java 并不支持多继承,这就意味着我们得将行为有交集的 Activity 的所有行为放到一个独立的类里面。但这样做会降低可维护性,甚至带来性能影响。

Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存? |

!!! 原文出处:  0、写在前面本文涉及到屏幕密度的讨论,这里先要搞清楚 DisplayMetrics 的两个变量,摘录官方文档的解释: density:The logical density of the display. This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5”x2” screen), providing the baseline of the system’s display. Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc. This value does not exactly follow the real screen size (as given by xdpi and ydpi, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi.

⾃定义布局流程 |

⾃定义布局流程 布局过程 确定每个 View 的位置和尺⼨ 作⽤:为绘制和触摸范围做⽀持 绘制:知道往哪⾥绘制 触摸反馈:知道⽤户点的是哪⾥– 流程 从整体看 测量流程:从根 View 递归调⽤每⼀级⼦ View 的 measure() ⽅法,对它们进⾏测量 布局流程:从根 View 递归调⽤每⼀级⼦ View 的 layout() ⽅法,把测量过程得出的⼦ View 的位置和尺⼨传给⼦ View,⼦ View 保存 为什么要分两个流程? 从个体看,对于每个 View: 运⾏前,开发者在 xml ⽂件⾥写⼊对 View 的布局要求 layout_xxx ⽗ View 在⾃⼰的 onMeasure() 中,根据开发者在 xml 中写的对⼦ View 的要求,和⾃⼰的可⽤空间,得出对⼦ View 的具体尺⼨要求

android 10 [API 29]适配指南 |

Android 11[API 30]已经发布正式版,来看看全新的 android 11 [api 30] 适配指南 非SDK接口 google 针对非SDK接口的限制 非SDK接口检测工具 官方给出了一个检测工具,下载地址:veridex veridex使用方法: appcompat.sh --dex-file=apk.apk blacklist、greylist、greylist-max-o、greylist-max-p含义 以上截图中,blacklist、greylist、greylist-max-o、greylist-max-p含义如下: blacklist 黑名单:禁止使用的非SDK接口,运行时直接Crash(因此必须解决) greylist 灰名单:即当前版本仍能使用的非SDK接口,但在下一版本中可能变成被限制的非SDK接口 greylist-max-o: 在targetSDK<=O中能使用,但是在targetSDK>=P中被禁止使用的非SDK接口 greylist-max-p: 在targetSDK<=P中能使用,但是在targetSDK>=Q中被禁止使用的非SDK接口 设备ID 从Android 10开始已经无法完全标识一个设备,曾经用mac地址、IMEI等设备信息标识设备的方法,从Android 10开始统统失效。而且无论你的APP是否是配过Android 10。 IMEI等设备信息 从Android10开始普通应用不再允许请求权限android.permission.READ_PHONE_STATE。而且,无论你的App是否适配过Android Q(既targetSdkVersion是否大于等于29),均无法再获取到设备IMEI等设备信息。 受影响的API Build.getSerial(); TelephonyManager.getImei(); TelephonyManager.getMeid(); TelephonyManager.getDeviceId(); TelephonyManager.getSubscriberId(); TelephonyManager.getSimSerialNumber(); targetSdkVersion<29 的应用,其在获取设备ID时,会直接返回null targetSdkVersion>=29 的应用,其在获取设备ID时,会直接跑出异常SecurityException 如果您的App希望在Android 10以下的设备中仍然获取设备IMEI等信息,可按以下方式进行适配: <uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="28" /> Mac地址随机分配 从Android10开始,默认情况下,在搭载 Android 10 或更高版本的设备上,系统会传输随机分配的 MAC 地址。(既从Android 10开始,普通应用已经无法获取设备的真正mac地址,标识设备已经无法使用mac地址) 唯一ID的替代 Google给出的解决方案是:如果您的应用有 追踪非登录用户重装 的需求,可用ANDROID_ID来标识设备。 ANDROID_ID的生成规则为:签名+设备信息+设备用户 ANDROID_ID重置规则:设备恢复出厂设置时,ANDROID_ID将被重置 String androidId = Settings.

Android实现图片缩放与旋转 |

本文使用Matrix实现Android实现图片缩放与旋转。示例代码如下: package com.android.matrix;import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ImageView.ScaleType; /** * Android实现图片缩放与旋转。 * @author Administrator * */ public class MatixActivity extends Activity { public void onCreate(Bundle icicle) { super.onCreate(icicle); setTitle("Android实现图片缩放与旋转。"); LinearLayout linLayout = new LinearLayout(this); //加载需要操作的图片,这里是一张图片 Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.r); //获取这个图片的宽和高 int width = bitmapOrg.

Android将汉字转换成拼音 |

采用了单利的模式,可以查看里面的注释 /** * Java汉字转换为拼音 * */ public class CharacterParser { private static int[] pyvalue = new int[] {-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032, -20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728, -19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -19270, -19263, -19261, -19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006, -19003, -18996, -18977, -18961, -18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696, -18526, -18518, -18501, -18490, -18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183, -18181, -18012, -17997, -17988, -17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721, -17703, -17701, -17697, -17692, -17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983, -16970, -16942, -16915, -16733, -16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433, -16429, -16427, -16423, -16419, -16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959, -15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631, -15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180, -15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941, -14937, -14933, -14930, -14929, -14928, -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857, -14678, -14674, -14670, -14668, -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353, -14345, -14170, -14159, -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, -14094, -14092, -14090, -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, -13847, -13831, -13658, -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, -13343, -13340, -13329, -13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, -12888, -12875, -12871, -12860, -12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, -12556, -12359, -12346, -12320, -12300, -12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, -11798, -11781, -11604, -11589, -11536, -11358, -11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, -11041, -11038, -11024, -11020, -11019, -11018, -11014, -10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, -10533, -10519, -10331, -10329, -10328, -10322, -10315, -10309, -10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, -10254}; public static String[] pystr = new String[] {"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", "chang", "chao", "che", "chen", "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", "cou", "cu", "cuan", "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du", "duan", "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang", "gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", "hai", "han", "hang", "hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", "ji", "jia", "jian", "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "ken", "keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng", "li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", "lue", "lun", "luo", "ma", "mai", "man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", "nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", "niu", "nong", "nu", "nv", "nuan", "nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", "pian", "piao", "pie", "pin", "ping", "po", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sen", "seng", "sha", "shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", "shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yo", "yong", "you", "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", "zhan", "zhang", "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", "zhun", "zhuo", "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo"}; private StringBuilder buffer; private String resource; private static CharacterParser characterParser = new CharacterParser(); public static CharacterParser getInstance() { return characterParser; } public String getResource() { return resource; } public void setResource(String resource) { this.

Typecho to Hugo |

这两天正式把博客从 typecho 转到 hugo 了。更准确的说应该是从动态博客转到了静态博客。 以前我是很抵制静态博客的。主要是感觉: 更新麻烦(现在仍然是这种感觉) 放在 github pages 上访问速度也不快,为了加速还需要套个 CDN。(同样是花钱,打折期间买个国内云服务器,速度不慢,还能干其他的) 配置真的很麻烦 这次换到 hugo 的起因是一个域名要备案,博客所在的域名要关闭评论系统,备案完后,打开评论发现,只要有评论的文章就卡死,然后 502。懒得折腾,直接关闭评论功能,发现关了后台也会卡死。索性转移到了 Hugo Hugo 如何安装配置网上很多这里不再赘述,主要说一下我是如何转换的。 部署在哪里 本来打算部署在腾讯对象存储 COS 上的,不过最后还是放弃了。 域名备案,内容审查。 不方便自动化处理,虽然通过github action + 云函数 + hook 可以做到更新仓库后自动构建,下载到 COS 但还是略显麻烦。需要配置好几个地方。 最终选择了部署在 在文章前面可以加很多参数的比如 --- title: "Typecho to Hugo" slug: "typecho-to-hugo" date: 2022-03-11T10:49:59+08:00 categories: [岁月如歌] tags: [Typecho,Hugo] showToc: true TocOpen: true draft: false # description: "Desc Text.

Android 声明式 UI 框架 Litho 初探 —— Layout |

Litho底层使用的是Yoga,Yoga是Facebook的另一个开源项目,它是一个跨iOS、Android、Windows平台在内的布局引擎,兼容Flexbox布局方式。 所以只要熟悉Flexbox布局,那么在使用Litho进行UI布局时基本毫无压力。 如果熟悉Flutter开发,那在使用Litho时,会有一些似曾相识的感觉,Litho中的 Row 与 Column 相关属性与Flutter中的 Row 与 Column 几乎无二。 本来想写一点示例代码,但是感觉没什么可写的。下面这个链接是Yoga 官网的playground。 你可以通过它可视化的调整UI,构建你需要的layout。同时可以生成相应的Litho代码 在线可视化构建UI: 直接生成的Litho代码: 在 Flexbox 中可以通过 positionType(ABSOLUTE)属性来实现Android 中的 FrameLayout效果: @OnCreateLayout fun createLayout(c: ComponentContext): Component { return Column.create(c) .child( SolidColor.create(c) .color(Color.MAGENTA) .widthDip(100f) .heightDip(100f) ) .child( Text.create(c) .text("FrameLayout") .marginDip(YogaEdge.TOP, 30f) .positionType(YogaPositionType.ABSOLUTE) ) .build(); } 运行效果:

解决 golang IDEA中不能debug问题 |

IDEA是2018-01版本,Golang是go-1.12.1,IDEA在Plugins中安裝的Go插件,我在运行go程序時是正常的,但是提示could not launch process: decoding dwarf section info at offset 0x0: too short 解決方案: 1:在终端运行 go get -u github.com/derekparker/delve/cmd/dlv。 2:运行上面的命令之后运行环境中就有dlv了。替换IDEA go 插件中的dlv macOS中的插件地址是:/Users/用户名 /Library/Application Support/IntelliJIdea2018.1/intellij-go/lib/dlv/mac 替换之后就正常了。

Android调用手机中的应用市场 |

public static void goToMarket(Context context, String packageName) { Uri uri = Uri.parse("market://details?id=" + packageName); Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); try { context.startActivity(goToMarket); } catch (ActivityNotFoundException e) { e.printStackTrace(); } }

ViewModel之自定义构造函数 |

刚入坑架构组件没多久,发现很多基础性的东西理解起来是没什么问题的,但是一到具体使用就各种问题,相关实践文章也比较少,更多的只能靠自己解决 = =。今天无意间了解了AndroidViewModel的一个使用场景和实现原理,特地记录下来。 ###前言 一开始,跟着官方文档,ViewModel我们是这样实现的: public class MyViewModel entends ViewModel { //... } 然后是创建实例对象: MyViewModel viewModel = ViewModelProviders.of(this).get(MyViewModel.class); 可以注意到,我们定义的ViewModel是没有构造函数的,也就是说如果遇到比较复杂情况下(需要在创建ViewModel时赋一些初始值),应该怎么办呢?总不能自己加一个构造函数,然后new出来吧,或者通过set方法一个一个加也行,但是这样就有点low了。于是,我发现了一个类AndroidViewModel AndroidViewModel AndroidViewModel这个类的定义很简单,它继承自ViewModel,然后添加了一个application私有属性: public class AndroidViewModel extends ViewModel { @SuppressLint("StaticFieldLeak") private Application mApplication; public AndroidViewModel(@NonNull Application application) { mApplication = application; } /** * Return the application. */ @SuppressWarnings("TypeParameterUnusedInFormals") @NonNull public <T extends Application> T getApplication() { //noinspection unchecked return (T) mApplication; } } 上面提到,很多时候我们需要在初始化ViewModel时需要传递一些参数,例如Activity中的一些参数等,但是根据ViewModel的生命周期我们知道,ViewModel中是不能传入Activity等实例对象的,因为在ViewModel存活的过程中,Activity是有可能会被销毁的。因此,Google爸爸推荐我们传入application。

博客寄语:

    从14年开始写博客,到现在再有2年就10年了。

实时播报:

博客号-学习成长

相信每一分耕耘都有每一分收获,致力帮助博客主所创作的博客能更快的被收录! 如果有其它需求,可联系下方邮箱。