1 int main() 2 { 3 // 动态规划问题之 --- 在所给出的钱里面凑够i元最少需要多少个硬币 或 张数? 4 // 状态和状态转移方程 5 // d(i)=j来表示凑够i元最少需要j个硬币 6 int a[3] = {1,3,5}; // 代表 每次可取的钱的个数 7 int sum = 11; // 代表 目标要凑够的钱数 8 int d[12]; // 代表 表示凑够最少需要的硬币个数 9 d[0] = 0; 10 //我们假设存在1元的硬币那么i元最多只需要i枚1元硬币,当然最好设置dp[i]等于无穷大 11 for(int i = 1; i <= sum; i++) 12 d[i] = i; // 代表着最多的次数,因为由一块一块凑起来的,肯定是最多 13 14 for(int i = 1; i <= sum; i++){ // 凑到 11 块,从 1 开始循环,逐渐到 11 块的情况,得出结果 15 for(int j = 0; j < 3; j++){// 第一次可能拿到的钱的面值的可能次数 16 // dp[i - a[j]] , i - a[j] 代表当前的钱减去第一次拿到的这块剩下的钱 17 // dp[剩下的] , 就代表着 凑够 剩下的钱,至少需要的硬币数目 18 if(i >= a[j] && d[i - a[j]] + 1 < d[i]){
// i >= a[j] ,代表当前的钱的值,a[j] 代表当前取到的面值,例如给出的 1 3 5,如果面值 > 当前循环到要凑的总数,就不满足了,所以要加这个限制 19 // dp[i - a[j]] + 1 代表着, 能够凑够剩下的钱的硬币数 + 第一次拿到的次数,总是一次,因为题目求的是硬币的个数 20 // < dp[i],由于 dp[i] 在上面的逐次的循环中都是代表了最小的硬币数,所以如果 dp[剩下的] + 1 < dp[i] 21 // 那么下面就可以重新赋值, 新的最小的次数,进入下一轮循环 22 d[i] = d[i- a[j] ] + 1; 23 } 24 // 下面的代码片段等同于上面的片段,可以看出,如果要求最多的硬币数,我们只需要改变 > 和 max 25 if(i >= a[j]){ 26 d[i] = min(d[i - a[j]] + 1,d[i]); 27 } 28 } 29 } 30 cout<<d[sum]<<endl; 31 return 0; 32 }
------------------------
Android 本地秘钥加密
http://drakeet.me/android-security-guide/
------------------------
Loopring
但目前考虑到ETH的成熟和普及程度,所以选择ETH作为第一个开发区块链平台。然而路印协议并不是为ETH量身定做的,它可以在满足条件的多条异构区块链上得以实施。后续考虑在EOS,ETC,量子链,Hyperledger(如果支持ERC20),及ChinaLedger社区版上进行开发。
------------------------
geth 命令比较好的一些文章:
http://www.yaozihao.cn/2017/07/07/geth%E5%91%BD%E4%BB%A4%E9%80%89%E9%A1%B9%E4%BB%8B%E7%BB%8D/
https://blog.csdn.net/weixin_40144050/article/details/79260598
geth --testnet 启动 以太坊测试链
geth --dev 启动 以太坊开发测试链
geth 自动同步以太坊公网
eth.blockNumber结果为0 解析
https://blog.csdn.net/wo541075754/article/details/78075643?locationNum=10&fps=1
eth.Syncing 解析
https://my.oschina.net/u/3782027/blog/1811152
以太坊 geth 当然命令在 json_rpc 中的体现
https://www.cnblogs.com/liujitao79/p/8441247.html
------------------------
区块链技术性教程文章:https://blog.csdn.net/sportshark/article/details/52249607
-----------------------
虚拟货币的免费数据获取 第三方 API 接口文档。
可以获取常见的市值多少,多少钱一个,周小时,七天的涨幅等
https://coinmarketcap.com/zh/api/
-----------------------
RPC 类 API,如何使用传统 RSET API 的 GET / POST
https://blog.csdn.net/fjscqjj1/article/details/79279226
-----------------------
非对称加密中,公钥 和 私钥都是可以用来加密和解密的。
公钥 加密 私钥 解密,这个过程我们习惯称为加密
私钥 加密 公钥 解密,这个过程我们习惯称为---签名
一、公钥加密
假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥。
我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用
数字2,就是我的私钥,来解密。这样我就可以保护数据了。
我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,
只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。
二、私钥签名
如果我用私钥加密一段数据(当然只有我可以用私钥加密,因为只有我知道2是我的私钥),结果所有的人都看到我的内容了,因为他们都知
道我的公钥是1,那么这种加密有什么用处呢?
但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他
解密看是不是c。他用我的公钥1解密,发现果然是c。
这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。
这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。
-----------------------
路印协议
https://www.jianshu.com/p/c88270224a80
-----------------------
go net/http/server.go 源码解析
https://www.zhihu.com/search?type=content&q=Golang%E7%BD%91%E7%BB%9C%3A%E6%A0%B8%E5%BF%83API%E5%AE%9E%E7%8E%B0%E5%89%96%E6%9E%90%28%E4%B8%80%29
-----------------------
在 Kotlin 中有一个约定,如果函数的最后一个参数是一个函数,并且你传递一个 lambda 表达式作为相应的参数,你可以在圆括号之外指定它
因此可以实现如下
view.setOnClickListener({v -> viewClicked(v) })
=>
view.setOnClickListener() {v -> viewClicked(v) }
在 Kotlin中还有另外一个约定,如果一个函数的参数只有一个,并且参数也是一个函数,那么可以省略圆括号
view.setOnClickListener() {v -> viewClicked(v) }
=>
view.setOnClickListener{v -> viewClicked(v) }
-----------------------
Golang 高并发性能优化
https://zhuanlan.zhihu.com/p/21514693
-----------------------
解决unix:///tmp/supervisor.sock no such file的问题
https://blog.csdn.net/qq_28885149/article/details/79364685
------------------------
水波纹效果:
当你使用了Material主题后,波纹动画会自动应用在所有的控件上,我们当然可以来设置其属性来调整到我们需要的效果。
可以通过如下代码设置波纹的背景:
android:background="?android:attr/selectableItemBackground"波纹有边界
android:background="?android:attr/selectableItemBackgroundBorderless"波纹超出边界
------------------------
Picasso 具备本地缓存的证据
https://www.cnblogs.com/gdpdroid/p/6226055.html
------------------------
Android 匿名共享内存 Ashmeme,及其在图片框架的应用 和 各大图片框架的对比
https://blog.csdn.net/u013134722/article/details/56676078
https://blog.csdn.net/wenyiqingnianiii/article/details/53045528
https://www.jianshu.com/p/d9bc9c668ba6
https://www.cnblogs.com/wytiger/p/5690039.html
tmpfs
https://www.cnblogs.com/wangtao_20/p/4828432.html
------------------------
xshell 过期
https://blog.csdn.net/pingqiwei/article/details/78502144
------------------------
go defer 的执行时机
https://segmentfault.com/a/1190000006823652
------------------------
supervisor Linux 进程管理
https://www.v2ex.com/t/372936
------------------------
Binder 机制一些文章
https://blog.csdn.net/lijizhi19950123/article/details/77920054
https://www.zhihu.com/question/39440766/answer/89210950
------------------------
链表的翻转,图解
https://blog.csdn.net/feliciafay/article/details/6841115
------------------------
Glide 缓存机制详解
https://juejin.im/post/5ab9a6b56fb9a028bf0553bd
Glide 自定义缓存key
https://blog.csdn.net/carson_ho/article/details/79256773
------------------------
关于 Android 4.4 及其以下的手机出现如下错误的原因和改法:
android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
这个错误在一些手机上面是不会出现的,一些却会。原因是我们在添加给 ListView 及其子类的 itemView 的时候,
itemView 里面使用了 new ViewGroup.LayoutParams
改法:
改用 new AbsListView.LayoutParams
------------------------
Android Studio 同步错误
界面显示这种信息:
gradle project sync failed.Basic functionality(e.g.editing,debugging) will not work properly
然后查看 idea.log,如果出现有下面的信息:
8-03-17 08:44:18,041 [se-915-b01] INFO - pl.ProjectRootManagerComponent - project roots have changed
2018-03-17 08:44:18,067 [thread 102] WARN - ea.IdeaSyncPopulateProjectTask - Sync failed: null
java.lang.RuntimeException: java.lang.NullPointerException
那么可以定位错误原因是。两个相同的项目但是在不同的目录,都曾被 as 打开过导致的缓存问题。解决方案是删除其中一个。
例如:
xxx/project/项目A
xxx/project/newDir/项目A
------------------------
为什么 String 不可变。
http://blog.csdn.net/zhangjg_blog/article/details/18319521
------------------------
String StringBuffer StringBuilder 三者区别
http://www.cnblogs.com/su-feng/p/6659064.html
------------------------
top K 问题,XX 亿个数中找最大的 y 个,这类题:
http://blog.csdn.net/zyq522376829/article/details/47686867
http://doc.okbase.net/zyq522376829/archive/169290.html
------------------------
阻塞队列中:
put 和 take 是会阻塞等待的。
offer 和 poll 不会等待,同时也可以设置一定的等待时间。
------------------------
java runtime 三个计算内存函数:
maxMemory 获取当前 APP 最大能够申请的内存,超过就会 OOM
totalMemory 获取当前 APP 已经从系统拿到的内存,包含使用上了的和没有用上的,因为一般申请会申请多一部分,它总是慢慢按需要从系统拿取
freeMemory 获取当前 APP 拿到的内存中,还没用上的,既是可以被 gc 回收的。
计算此刻 APP 已经使用了的内存是 : totalMemory - freeMemory = usedMemory
------------------------
Synchornous 修饰静态方法和普通方法的区别:
1,static 是对于 .class 对象而言的,注意这里不是实例,它还不是一个具体的对象,具体的对象 == 实例。
2,那么修饰 static 的时候,也就是修饰这个 .class,当使用 Class.function(...) 的时候会产生对应的锁效果。
3,修饰普通方法的时候,是针对实例而言的,也就是 new XXX().function(...) ,这个时候,会对同一个实例里面产生对应的锁效果。
具体什么锁效果,查看该博文下面的另外一条:java synchronized详解
------------------------
让 静态方法 和 普通方法 都产生互斥。
使用锁静态常量,语句块方法,如下:
public final static Byte[] locks = new Byte[0]; public static void staticX() throws InterruptedException { synchronized (locks) { ...... } } public void x() throws InterruptedException { synchronized (locks) { ..... } }
------------------------
Class.forName(...) 的真正作用:获取制定的类,如果这个类已经在 jvm 中装载了,那么直接返回,引用与已经装载的一样,否则便先装载再返回。
参考文章:http://www.jb51.net/article/113928.htm
同时要注意,它返回的不是类实例,只是类对象,也就不会进行构造函数的调用。
http://blog.csdn.net/xiongmaodeguju/article/details/70854645
------------------------
AlertDialog 实现背景透明,即网易云音乐的更新对话框,一个图标所在区域的背景一半透明一半不透明的例子:
http://blog.csdn.net/android_hdh/article/details/75098221
------------------------
Win adb 无法连接手机,在尝试了在 .android 目录下添加 xxx.ini 文件后且加入 0xYYYY 之后仍然无法解决的情况下,
如果在电脑的设备管理页面看到 adb interface 有黄色感叹号就参考这篇文章解决
http://blog.csdn.net/chtnj/article/details/49718809
其中驱动文件可以在 sdk manager 中下载,也可以去这里下载
http://download.csdn.net/download/af913337456/10250732
------------------------
jackson 常见错误:
bean 没定义无参构造函数;
bean 设置成了内部类,这是不允许的。JsonMappingException: No suitable constructor found for type
------------------------
mysql insert into select from 组合使用,适用于数据迁移
https://www.cnblogs.com/jpfss/p/6973048.html
------------------------
Linux ubuntu 如果出现输入不了中文,去搜索处,搜索 fcitx,点击一次即可
------------------------
Collections.sort compare :
1 , return 1 指compare方法第一个参数要放在第二个参数的前面,-1 指第一个参数要放在第二个参数后面 , don't return 0
2 , part sort can use ' list.subList '
------------------------
golang 加解密文件 https://segmentfault.com/q/1010000009581717?_ea=1979263
------------------------
java try-catch-finally https://www.cnblogs.com/aigongsi/archive/2012/04/19/2457735.html
------------------------
mysql 并发锁的问题 https://www.cnblogs.com/leefreeman/p/8286550.html
------------------------
golang exec.Command cmd.Dir参数指定的是当前执行的目录,如果不设置,那么默认就是当前可执行程序的
------------------------
APP 锁屏后,避免被 kill 掉,解决方案之一,使用手Q的一像素方案,成型 demo 参照 非ROOT版微信自动回复APP。
注意点:
1,targetSdk 最好低于 23
2,LiveAc 的 theme
------------------------
Https 会加密头部,在浏览器里面查看得到本地请求的头部的原因是,浏览器帮我们处理了。
------------------------
mysql 导出数据库和恢复数据库到任意的另外一个数据库。
导出:控制台命令 mysqldump -u {用户名} -p {要导出的数据库名 A}>xxx.sql
恢复:进入另外一个服务器的 mysql,create database A,use A,source xxx.sql
------------------------
mysql 错误:Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
https://www.cnblogs.com/sunss/p/6245403.html
------------------------
Mysql switch 语句 样例:
http://blog.csdn.net/djd1234567/article/details/51332267
------------------------
golang clear file content do not use this function --- os.Truncate(xxx,0),it may cause some 0 char problems
------------------------
HttpUrlConnection https 认证 http://blog.csdn.net/u012527802/article/details/70172357
------------------------
landscape 锁屏拉伸,add this below
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="landscape"
------------------------
TRIM_MEMORY_COMPLETE maybe will be called when the app frist start
------------------------
openSSL 在服务端 生成 可供 Android 使用的秘钥文件,开启 Https 用到
1 openssl req -new -key server.key -subj "/CN=IP地址" -out server.csr 2 3 # 签发服务端证书 4 # ca.crt equals xx.pem, ca.key equals xx.pem 5 openssl x509 -req -in server.csr -CA fullchain.pem -CAkey privkey.pem -CAcreateserial -out server.crt -days 5000 6 7 # 客户端 8 openssl genrsa -out client.key 2048 9 10 openssl req -new -key client.key -subj "/CN=client" -out client.csr 11 12 echo extendedKeyUsage=clientAuth > extfile.cnf 13 14 openssl x509 -req -in client.csr -CA fullchain.pem -CAkey privkey.pem -CAcreateserial -extfile extfile.cnf -out client.crt -days 5000 15 16 # 生成P12,p12 转 bks,安卓用 17 openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 18 19 # create xxx.cer ,安卓使用 20 openssl x509 -inform pem -in fullchain.pem -outform der -out server_public.cer
------------------------
onTrimMemory http://blog.csdn.net/ithouse/article/details/53319589
------------------------
Wechat service way to keep live : https://www.cnblogs.com/MouTou/p/5607423.html
------------------------
去 Editext 控件的父控件处设置
android:focusable="true"
android:focusableInTouchMode="true"
这样,已进入页面,它就不会获得焦点
------------------------
Android 进程级别及对应的情况 https://www.cnblogs.com/0616--ataozhijia/p/4323135.html
------------------------
友盟的分享SDK,在分享单图片的时候,即没有文字,如果发生失败,没权限什么的之类,可以在传入的时候传入 File,不传 String
------------------------
四大组件之一 Service 的总结点:
1,使用 startService 启动一个 service,即时启动它的组件已经销毁了,例如 Activity,这个 service 也不会被销毁,只有调用了这个 service 自身的 stopSelf() 或 stopService 才会终止。
2,使用 bindService 启动一个 service,顾名思义。这种方式会让它和启动它的组件绑在一起,只用当与它绑定的组件销毁了,它才会 unBind 销毁,stopSelf 不能销毁。
3,一个 service 可以被多个组件 bind,这个时候只有全部 bind 了的组件都进行了 unBind,这个 service 才会被销毁。
4,既执行了 startService 又执行了 bindService,onCreate 只会被调用一次,且销毁的时候以 unBind 为主。
5,不同的启动方式,生命周期的 执行流程 也不一样。
6,Service 运行在主线程,intentService 运行在子线程。
------------------------
Serializable 和 Parcelable 的简介与区别
相同点:
1,两者都可以进行序列化与反序列化;
不同点:
1,Serializable 的数据最后是存放在硬盘上的,那么读的时候也是 I/O 操作,而 Parcelabe 是存放在内存中的。这就导致了下面的一点
2,Parcelable 的读写速度比 Serializable 在数据量大的时候,快很多
3,Serializable 的实现十分简单,而 Parcelable 的代码量却比较多
引申:
1,在使用 bundle 传递数据的时候,因为bundle 是使用 binder 机制进行数据传输的, 一个 binder的数据缓冲区是有大小限制的;
2,一个进程的默认 binder 线程是15个。
------------------------
阻塞队列的 poll offer put 等解析,https://www.cnblogs.com/dolphin0520/p/3932906.html
------------------------
补码,原码,反码复习,https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html
------------------------
IM sdk 的设计中,消息的发送到成功态,UI的刷新不要依赖 position,例如 notifyItemChanged(position),如果采用了翻转类型的 layoutManager,刚发的消息 pos 总是 0,
这样如果有新的消息到来,而自己刚发的还没返回成功,这时候,pos 就被占了,导致错误。应该传入 MessageBean 的引用
------------------------
EventBus 的粘性事件需要注意,可能会多次接收。例如接收后回到桌面,再次 restart 进入,可能会由于 EventBus 里面的粘性事件集合引用还存在,
导致再次分发,接收到上一次的事件。通过源码可以得出该结论。因为其在 postSticky 的时候分发一次,等到 register 的时候,因为标明了 stick = true 导致再次分发。
源码分析: http://blog.csdn.net/yanghuinipurean/article/details/51646819
------------------------
聊天页面如果要实现QQ的回复的时候消息的顶起效果,即是不回滚到底部,在当前浏览的位置顶起。使用 recyclerView,只需要把,linearLayoutManager 设置为翻转模式即可。
------------------------
1 /** 2 * 状态栏处理:解决全屏切换非全屏页面被压缩问题 3 * 原理就是,把状态栏设置为透明后,自定义添加一个 View 进去 4 */ 5 public void initStatusBar(int barColor) { 6 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 7 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 8 int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 9 // 获取状态栏高度 10 int statusBarHeight = getResources().getDimensionPixelSize(resourceId); 11 View rectView = new View(this); 12 // 绘制一个和状态栏一样高的矩形,并添加到视图中 13 LinearLayout.LayoutParams params 14 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight); 15 rectView.setLayoutParams(params); 16 //设置状态栏颜色 17 rectView.setBackgroundColor(getResources().getColor(barColor)); 18 // 添加矩形View到布局中 19 ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); 20 decorView.addView(rectView); 21 ViewGroup rootView = (ViewGroup) ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0); 22 // true 使得状态栏不被 content view 挡住 23 rootView.setFitsSystemWindows(true); 24 rootView.setClipToPadding(true); 25 } 26 }
------------------------
Android 硬件加速文章 https://tech.meituan.com/hardware-accelerate.html
------------------------
layoutManager.getChildCount 和 lastVisibleItemPosition 一样,都是添加过的 view 总数。而 layoutManager.getItemCount 是指 adapter 所绑定 list 添加了的总数。
差比在于: 如果我们没有自定义 headerView,那么三者一样,否则就是 childCount = itemCount + header.size
------------------------
recyclerView 异常 "Called attach on a child which is not detached" 的原因是,使用了一个还没被回收缓存的 view 去重新加入到视图中,导致异常,debug 断点其内函数 attachViewToParent 即可明了。
一般引发的原因有很多,notifyRemove 和 insert 最容易触发。解决方案是传入正确的 postion
------------------------
混淆的时候,各个 library 的混淆文件对应自身目录的 .pro 文件,互不影响
------------------------
注:当使用混淆打包时可能会出现一个问题
Error:Execution failed for task :transformClassesAndResourcesWithProguardForRelease'.
> java.io.IOException: Please correct the above warnings first.
这个问题是在说你在混淆打包的时候有些类有可能找不着,所以会包错,和warning
解决的办法:
找到报warning的类都给他在你的proguard-rules.pro
混淆器文件中
添加代码-dontwarn 包名+类名.**
给取消掉warning就可以了,如果你不想那个类被混淆,那就添加代码:-keep class 包名+类名{*;}或者包名.**{*;}
------------------------
android studio error : symbols/androidTest/debug/R.txt (没有那个文件或目录)
add this to your gradle:
dependencies {
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
------------------------
较好的 OKHttp 源码分析文章。
http://blog.csdn.net/qq_19431333/article/details/53141013
http://www.jianshu.com/p/9ed2c2f2a52c
http://blog.csdn.net/ethanco/article/details/78268750
http://blog.csdn.net/evan_man/article/details/51182087
缓存 http://blog.csdn.net/qq_21430549/article/details/52069708
Connect() http://blog.csdn.net/chenzujie/article/details/47093723
------------------------
SynchornousQueue 的详解-----http://www.cnblogs.com/shangxiaofei/p/5707552.html
------------------------
volatile可以保证变量的内存可见性。链接:http://www.cnblogs.com/yanfengfree/p/6271359.html
------------------------
动态规划求,最长公共子序列: http://blog.csdn.net/hrn1216/article/details/51534607
------------------------
Intent.putExtra 传进去在源码层可以看到是内存拷贝传的,也就是深复制.
------------------------
android 实现多点触控的问题,本身已经支持,在 onTouch 或者 onTouchEvent 等函数里面,可以通过 MotionEvent 的 api getPointerCount 来获取屏幕的触点数目,
而 getX(...) getY(...) 则可以根据传入的 position 来或者对应触点的坐标,然后就可以写自己的逻辑来控制了。
------------------------
mysql 修改 root 的权限,http://www.cnblogs.com/kyosusan/p/5198934.html
------------------------
Jni 中 C++ 调用 java 接口,如果没有返回值的,就一定要不用返回值的 jni 函数,例如 env->CallVoidMethod(...) 否则在循环多次后会造成内存泄露底层异常,无法解决!
------------------------
SurfaceView 自身没有调用 onDraw,需要子 View 手动调用,或者在 xml 配置 bgColor 的时候,设置,这样会自动调用一次,然后你在 子View 的 onDraw 里面设置个 loop,loop里面 postInvalidate 就能一直调用了。
代码动态设置 bgColor 也可以,visible 测试不能引起 onDraw 的调用
------------------------
EventBus 3.0.x 中的粘性事件 , 发送端使用 postSticky 是不够的 , 接收端 , 还要在 @Subscribe 处后面加上 (sticky = true) , ===> @Subscribe(sticky = true)
------------------------
在结合 view.getGlobalVisibleRect(...) 获取的 rect 和 属性动画 ObjectAnimator.ofFloat(...) 的使用中 , 需要注意位置的不同 .
1 , getGlobalVisibleRect 获取的 rect 是从屏幕左上角开始的 , 也就是说 , 把我们手机顶部显示时间,电量,wifi等图标的那一栏给计算进去了
2 , 属性动画的开始 标准 , 如果是平移之类的话 , 例如 X或者 Y 这类 , 它的开始是从当前的 decorView 开始的 , 也就是说没有计算 电量 那一栏 .
结论:
为了防止误差 , 你得把你通过 getGlobalVisibleRect 得出的 rect 减去顶部的高
------------------------
onMeasure(最终整个期望的宽,最终整个期望的高) 是代表着控件的最终期望宽高
MeasureSpec.makeMeasureSpec(size,mode) size 是期望的大小 , mode 是模式 . 例如设置 宽 高
1 , 最终期望的宽 width = MeasureSpec.makeMeasureSpec(期望的宽 , mode)
2 , 最终期望的高 height = MeasureSpec.makeMeasureSpec(期望的高 , mode)
mode 的不同情况 :
MeasureSpec.AT_MOST 这个的情况 , 就是使用 期望的值 去和 最终控件对应的 size 做比较 , 返回 最小的一个 , 一般我们都是使它返回控件组的即可,所以我们可以传一个很大的期望, 例如 Integer.MAX_VALUE >> 2
MeasureSpec.EXACTLY 这个的情况 , 就是直接使用 期望的值 , 设置多少就是多少
MeasureSpec.UNSPECIFIED 这个是 , 直接使用 控件组对应的 size , 无论你设置的 期望是多少 .
补充:
1 所谓的控件组的 size 就是 , layout 的大小 , 就是我们通过 R.layout.xxx 或者其他设置时候 , 该 layout 占的总大小.
2 上面的 三种 mode 的最终效果 , 还要看当前的 ViewGroup 的内部设置而定 . 例如 GridView 在 UNSPECIFIED 的情况设置了最终整个 GridView 仅仅返回一行的高 , 也就是总是一组的高 , 此时一组的期望高 = 控件的 size.高
但是在 AT_MOST 的时候 , 和上面一样 此时一组的期望的高 = 控件的 size.高 , 但是最终的整个 GridView 的高是全部 组 布满后的尺寸
3 如果 需要 完全手动 设置 宽高 , 例如处理 bitmap 的时候 , 应该使用函数 setMeasuredDimension(宽 , 高) , 而不是使用 onMeasure , 因为 onMeasure 的情况是必须是与 32 做了 与或 运算的 , 在内部分解的时候也会和 32 做反操作 ,
即是说 , 你传的如果没和 32 做过 与或 运算的话 , 在内部反操作的时候就会乱掉 . 而 setMeasuredDimension 会在你传的值之后 帮你完成 32 的 与或操作 , 同时也需要你必须先调用 onMeasure 再 调用 setMeasureDimension ,否则会有错误
1 @Override 2 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3 4 super.onMeasure(widthMeasureSpec,heightMeasureSpec); 5 6 setMeasuredDimension(500,600); 7 }
所以:
在解决 嵌套 问题的时候, 我们一般
MeasureSpec.makeMeasureSpec(
足够大的值, // 当足够大的时候 > 一组控件的 size , 就会直接返回 一组控件的
MeasureSpec.AT_MOST
);
----------------------------------------
OKHttp 如果已经附带 header 进行过请求,在之后的请求修改 header 是无效的,总是使用第一次的,可以通过销毁当前的对象,重新 new 一个设置 header 发起请求解决。
-----------------------------------------
截屏 getDrawingCache 的陷阱 , 每次在执行这个函数之前 , 先将上一次的给 destroy 掉 , 否则 , 会导致总是同一张 , 哪怕此时你的 View 已经加入了其他的子 View , 正确流程
gpuImageView.destroyDrawingCache(); gpuImageView.setDrawingCacheEnabled(true); gpuImageView.buildDrawingCache(); Bitmap editbmp = Bitmap.createBitmap(gpuImageView.getDrawingCache());
------------------------------------------
聊天页面软键盘把内容顶起
recyclerViewLayoutListener = new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1);
}
};
------------------------------------------
Android 一些需要用到 Context 来获取的,如果是全局修改,例如语言的切换,务必使用 getApplicationContext,如果使用单个 Activity 的话,可能有些页面不会被影响到。
Sql 中 string 类型的采用 order by,顺序不是正确的,数字类型会正确
--------------------------------------
scrollTo 是一步到位,scrollBy 是逐渐累加,scrollTo(100,100) 后,想到 120,那么是 scrollTo(120,120),此时如果换成 scrollBy 就是 scrollBy(20,20),内部在 to 的基础上累加。
--------------------------------------
在使用 View.getLocationInWindow(int[] ) 函数的时候,要注意,在 ViewPager 的情况下,例如第二页的一个控件,x 的坐标会把第一页的计算进去。onScreen 一样,内部因为调用了 inWindow。
---------------------------------------
Activity 里面使用 ViewPager 装载 Fragment 的时候,如果此时的 Fragment 再在里面装载其他 ViewPager + Fragment 的时候,Fragment 里面的 ViewPager 的 FragmentManager 不要使用 getSupportFragmentManager() ,要使用 getChildFragmentManager(),否则会造成,有些时候, Fragment 里面的 Fragment 显示一片空白!原因是,getSupportFragmentManager 是基于 Activity 的,getChildFragmentManager 是基于 Fragment 的。
---------------------------------------
关于 AlarmManager 在 5.1 前后的不同 5.1之前,可以随便设置多少秒的间距,5.1之后,<60 秒就会强制变成 1 分钟,就是至少一分钟
----------------------------------------
消除 Android App 自身启动时候的 白屏,以及改为自定义启动页的方法:
<item name="android:windowBackground">@mipmap/welcome</item>
Activity 的 style 加上上面一句,但是也要在完全进入主页后设置 背景 没有,否则会一直显示作为 WindowBackGround
----------------------------------------
WindowManager 如果要在 Activity 添加 View,不能采用 getApplicationContext(...) 来获取 systemService 否则,会产生异常:Unable to add window -- token null is not valid; is your activity running.
type 要使用 System_Application,flags 使用全屏,no limits
synchronized和ReentrantLock的区别
Java多线程(九)之ReentrantLock与Condition
java synchronized详解 理解 2~3 点的时候要明确:m4t1 和 m4t2 方法都是类 Thead2的代码部分,Thead2 此时充当 object
进阶 https://juejin.im/entry/58d2d12f2f301e007e674cd1
git 提交 pull request http://jingyan.baidu.com/article/358570f64dcdc2ce4724fc32.html
代码连接 mysql 出现错误: dial tcp 127.0.0.1:3306: getsockopt: connection refused 而且通过sock文件在终端登录 mysql 使用 show variables like 'port'; 是 0 的话,参照此文章解决, http://blog.csdn.net/shaochenshuo/article/details/50070315 是因为一个 skip-networking 参数
Amh 面板的 mysql 连接的时候爆出错误找不到 mysql.sock ,先查找下,find / -name "*.sock",再复制一份到 tmp,
ln -s /tmp/mysql-generic-5.5.sock /tmp/mysql.sock , 再连接即可。
-------2017-3-8 开始
针对 Android Studio 情况的 .so 匹配问题,有如下一个规则:如果测试手机自身是支持 armeabi,armeabi-v7a,x86 的,而此时,项目中 eabi ,v7a,x86 都含有 a.so,但是 eabi 和 v7a 单独还多有 b.so,此时如果编译运行到该手机,那么就会爆出无法 在x86 找到 b.so 的异常。
根据不同的手机为准,例如小米就是有一个层次级别加载,它先从自己支持的列表中去找,例如 x86 找,此时你的项目也含有 x86 的库文件夹,那么它就认定这个了,此时你代码里面需要加载 b.so 但是 x86 没有,所以报错。
解决方法就是,要么就别建含有 x86 的情况,或者在每种架构中都编译全 .so 文件。
------2017-3-8 结束
MySql,对于 select .... where xx in (?) 的预处理语句,如果 ?对应是一组字符串,例如 3,6,8 那么在传过来的时候事实是 '3,6,8' ,内部使用了如下方法:CAST('4,3' AS INT),强转为 int 后,只能查处一条,即是 3 的。所以对于这种清理,使用 FIND_IN_SET 解决,改为 select .... where FIND_IN_SET(要查询的字符串,传过来的)
java 匿名对象的使用,若非延时调用,那么不会造成内存泄露,下面举例子:
1 /** 没引起其它,用完即可被回收 */ 2 new Thread(new Runnable() { 3 @Override 4 public void run() { 5 6 } 7 }).start(); 8 9 /** 持有外部 Activty 引用,延时这段时间,无法被回收 */ 10 new Handler(){ 11 @Override 12 public void handleMessage(Message msg) { 13 super.handleMessage(msg); 14 } 15 }.postDelayed(new Runnable() { 16 @Override 17 public void run() { 18 19 } 20 },60*1000);
http://blog.csdn.net/jiahui_zhu/article/details/50234311
WINScp 解决经常断开链接的问题, 选项-》选项-》面板-》远程-》刷新面板间距,时间调小
启动 MariaDB: systemctl start mariadb.service
三大手写算法
1 /** 冒泡 */ 2 public static void bober(int[] array){ 3 int length = array.length; 4 for(int i=0;i<length-1;i++){ /** 每两个比较一次,总次数是 length-1 */ 5 for(int j=0;j<length-1-i;j++){ // 每次总有一个最大的找出 -i 6 if(array[j]>array[j+1]){ 7 int temp = array[j]; 8 array[j] = array[j+1]; 9 array[j+1] = temp; 10 } 11 } 12 } 13 } 14 15 /** 快排 */ 16 public static void quickSort(int[] array,int left,int right){ 17 if(array==null){ 18 return; 19 } 20 int length = array.length; 21 if(length == right){ // 防止输入数组的非下标长度,造成越界 22 right = right -1; 23 } 24 if(left > right){ 25 return; 26 } 27 int low = left; 28 int hight = right; 29 int key = array[left]; 30 31 while(low<hight){ 32 while(low<hight && array[hight]>=key){ 33 hight --; 34 } 35 array[low] = array[hight]; 36 while(low<hight && array[low]<=key){ 37 low++; 38 } 39 array[hight] = array[low]; 40 } 41 array[low] = key; /** 被比较的数此时应该回到 low 位置 */ 42 quickSort(array,left,low-1); 43 quickSort(array,low+1,right); 44 } 45 /** 二分查找 */ 46 public static int binary(int[] array, int value){ 47 int low = 0; 48 int high = array.length - 1; // 防止越界 49 while(low <= high){ 50 int middle = (low + high) / 2; 51 if(value == array[middle]){ 52 return middle; // 下标 53 } 54 if(value > array[middle]){ 55 low = middle + 1; 56 } 57 if(value < array[middle]){ 58 high = middle - 1; 59 } 60 } 61 return -1; 62 }
as 修改默认 apk 名称:
1 buildTypes { 2 release { 3 minifyEnabled false 4 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 5 applicationVariants.all { variant -> 6 variant.outputs.each { output -> 7 output.outputFile = new File(output.outputFile.parent, 8 output.outputFile.name.replace("app-release", "AccurMe") 9 ) 10 } 11 } 12 } 13 debug{ 14 applicationVariants.all { variant -> 15 variant.outputs.each { output -> 16 output.outputFile = new File(output.outputFile.parent, 17 output.outputFile.name.replace("app-debug", "AccurMe") 18 ) 19 } 20 } 21 } 22 }
android studio,gradle的编译默认是会找依赖关系最近的覆盖,如果一个相同的 xml 布局文件分布在不通的模块,此时修改一个,再 findView。。有可能引发空指针,因为就近的如果不是被修改的就会如此
当LinearLayout设置android:orientation="vertical" 时, 只有水平方向的left,right,center_horizontal设置起作用,垂直方向的设置不起作用。
同样的:
当LinearLayout设置android:orientation="horizontal" 时, 只有垂直方向的top,bottom,center_vertical设置才起作用,水平方向的设置不起作用。
IM架构设计中,好友删除部分,如果当前被删者在发送消息的页面,而且断网期间没接收到被删除推送,那么恢复网络后,他发消息给删除者,应该在删除者端判断,该人还是否在好友列表再决定显示,避免在发送 服务端 每次做查询操作
android 6.0+ 如果 activity 此时正在用 surfaceView 播放视频,你却调用 finish,一定要 surfaceView.getHolder().removeCallback(surfaceViewLis); 和 surfaceView=null,否则爆底层异常,闪退,6.0 以下不会。
Nginx 的 php-fmp 监听的端口要和nginx.conf 里面的 fastcgi_pass xxxx:port 的一样,否则会出现502错误
兼容系统自带的 emoji 的方法是,发送的时候将内容加密,获取的时候再解密即可,加解密是为了防止在传输的时候编码被转成乱码导致显示不了,系统是一个表情的编码,utf8 不存在。
XRecyclerView 使用 notifyItemChanged 会闪的原因是:
原作者,没用重写: onBindViewHolder(final RecyclerView.ViewHolder holder, int position,List<Object> payLoads) , 后面的payLoad,默认是null,不为null 的时候,就是只更新唯一改了的地方。notifyItemChanged(position,new Object())
7linux控制台启动程序后,关掉控制台不让程序停止, ./test & 加上 & 这样是将命令放入到一个作业队列中。如果还是失败,安装 nohup ,nohup ./xxx &
【
信号量的当前值,N > 0,该值表示有N个可用资源
如果为 N = 0,没有进程处于等待状态
如果 N < 0,有N个进程处于等待状态。
】
Win 安装驱动,若提示哈希值什么错之类的,是系统验证签名的原因,开机关掉强制验证驱动签名即可
Win cmd 设置环境变量是 set
下面这条写于2016年9月12日晚,很基础,但我还是搞反了,特地放在所有的前面,为的是警示自己,基础的如果不常用就应该多回头看看。
ARP协议主要是将IP地址转化为物理地址。
TCP的socket本身就是长连接
a~y 25个字母编码,a->0,aa->1,aaa->2,aaaa->3 以此类推,满25 进一。
1 public static int getIndex(String str){ 2 int[] numbes = new int[]{ 3 1+25+25*25+25*25*25, // a 4 1+25+25*25, // ab 5 1+25,// abb 6 1 //a 7 }; 8 char[] chars = str.toCharArray(); 9 int len = chars.length; 10 int result = 0; 11 for(int i=0;i<len;i++){ 12 result += (chars[i]-'a')*numbes[i]; 13 } 14 return result+(len - 1); 15 }
N*N 个方格中有 1^2+2^2+3^2+...+(n-1)^2+n^2 个正方形
InputMetohdManager 单例模式,按钮事件的监听、广播是观察者模式
AsyncTask 比 handler 更耗资源
SingleTop 不会弹栈
Message提供了消息池,Thread默认不提供资源池,AsynTask是线程池改造的,Looper,没提供池
Theme类不可以继承
一个TextView的style中定义了textColor属性,TextView本身也设置textColor属性,那么TextView本身定义的优先级较高
进程重要性:前台进程>可见进程>服务进程>后台进程和空进程;所以销毁的顺序是逆方向。
继承 AppCompatActivity 的 Activity , AlertDialog 很难全屏
RadioButton 的 OnCheckedChangeListener 如果另一个调用了,最近之前点过的也会调用一次,不同的是,最近的是 check false
要确保不在子线程中修改Adapter所绑定的 ArrayList 的数据内容,而要在UI Thread中修改,和 notifityDataChange 一起连用
在 Fragment 中采用 startActivityForResult 跳到对应的 Activity,返回时回调的首先是 fragment的onActivityResult 然后是 所传 context 对应的 Activiy 的 onActivityResult
setResult(...) 要在finish() 之前设置,否则没效!
调用 onBackPressed,那么 finish()->onBackPressed(),调用 finish(),只用 finish()
NDK,Jni实现HelloWold 的最简单代码:
jstring Java_包名_所在类名_函数名字(JNIEnv *env,jobject thiz){ return (*env)->newStringUTF(env,"helloWorld"); }
显示系统的 Emoji 到 textView 的时候,不要 toString 要采用 Spinnable 或者 SpinnableString,再 setText
两道经典算法题
1 import java.io.*; 2 import java.util.HashMap; 3 import java.util.Arrays; 4 5 /** 6 * Created by 林冠宏 on 2016/8/9. 7 * 8 * 1,寻找单词 9 * 10 * 2,大数相乘,字符串版 11 * 12 */ 13 14 class test 15 { 16 public static void main (String[] args) throws java.lang.Exception 17 { 18 String testText = "I I I I I I Last year,I went to Guilin for travel,+" + 19 "it was a great trip for me.I not only had a look at the beautiful scenery,+" + 20 "but also made friends.I knew a lovely girl from America," + 21 "we met each other on the train.As we were almost at the same age,+" + 22 "we communicated a lot.We shared our opinion about the culture and learned a lot." + 23 "When our train reached the destination,+" + 24 "we needed to separate,we promised to keep in touch by the Internet." + 25 "Now a year has passed,+" + 26 "we make our promise and keep in touch all the time." + 27 "I have improved my English and she is so interested in China.+" + 28 "It seems that we can never finish our topic," + 29 "because we always have so much to share with each other.+" + 30 "I am so lucky to make a good friend."; 31 32 System.out.println("MaxWord is :"+search(testText)); 33 System.out.println("BigNumberMutiply is "+multiply("5991299","998889799")); 34 } 35 36 /** 文章中找出出现次数最多的单词 */ 37 /** 38 * 算法概述,利用 HashMap 的特点 39 * */ 40 public static String search(String text){ 41 String maxWord = ""; 42 int maxTime = 0; 43 String[] words = text.split(" |\.|,"); 44 int length = words.length; 45 System.out.println("length is :"+length); 46 HashMap<String,Integer> one = new HashMap<>(); /** 一个map是可以put多个的 */ 47 for(int j=0;j<length;j++){ 48 Integer number = one.get(words[j]); 49 if(number != null){ 50 number = number + 1; 51 /** 找到次数加 1 */ 52 one.put(words[j],number); 53 if(maxTime < number){ 54 maxTime = number; 55 maxWord = words[j]; 56 } 57 }else{ 58 /** 没找到,赋值 1 */ 59 one.put(words[j],1); 60 } 61 } 62 System.out.println("maxTime is :"+maxTime); 63 return maxWord; 64 } 65 66 /** 大数相乘 */ 67 /** 68 * 算法概述,就是小学的乘法规则,例如 69 * 33*44 70 * 33 71 * X 44 72 * ----- 73 * 12 (2 是 n,1 是 n-1) 74 * 12 (以此类推) 75 * ----- 76 * 132 77 * ...... 78 * */ 79 public static String multiply(String str1,String str2){ 80 81 Integer[] resultChar; 82 char[] strChar1 = str1.toCharArray(); 83 char[] strChar2 = str2.toCharArray(); 84 85 int str1Len = strChar1.length; 86 int str2Len = strChar2.length; 87 88 int n = str1Len+str2Len-1; 89 resultChar = new Integer[n+1]; 90 /** 初始化 */ 91 for(int i=0;i<=n;i++){ 92 resultChar[i] = 0; 93 } 94 95 for(int i = str1Len-1;i>=0;i--){ 96 /** 减去 48 是转为数字 */ 97 int temp1 = strChar1[i] - 48; 98 for(int j = str2Len-1;j>=0;j--){ 99 /** 一轮后的 n--,此时 n 变为上一轮的 n-1 */ 100 int temp2 = resultChar[n] + (strChar2[j] - 48)*temp1; 101 if(temp2 >= 10){ 102 /** 取余数 */ 103 resultChar[n] = temp2 % 10; 104 /** 进位取整数 */ 105 /** 在一大轮完成后,新n会与上一大轮的n相等,这里要在n-1位叠加 */ 106 resultChar[n-1] += temp2/10; 107 }else{ 108 resultChar[n] = temp2; 109 } 110 n--; 111 } 112 /** 跳出一层内循环,证明 1 个数已被乘完,n 要重置 */ 113 n = n + str2Len - 1; 114 } 115 /** 返回结果 */ 116 StringBuffer result = new StringBuffer(""); 117 for(int k=0;k<resultChar.length;k++){ 118 result.append(resultChar[k]); 119 } 120 return result.toString(); 121 } 122 }
线程池中的任务队列,并发型阻塞队列 ArrayBlockingQueue,poll() 和 take() 都是获取一个任务,内部操作皆有锁lock,差别是:使用take()函数,如果队列中没有数据,则线程wait释放CPU,而poll()则不会等待,直接返回null;同样,空间耗尽时offer()函数不会等待,直接返回false,而put()则会wait,因此如果你使用while(true)来获得队列元素,千万别用poll(),CPU会100%的。源码中有一个 allowCoreThreadTimeOut,如果设置为true,则会进入 poll(),newCacheThreadPool 也会引起poll()。
TCP:
握手阶段:ack=seq+1
数据传输阶段:ack=seq+待确认数据包长度
Jvm 虚拟机中 类的加载机制最后一步执行初始化 clinit<> 是线程安全的,这也是为什么单例模式中,非饿汉模式中的静态内部类模式能够达到线程安全的原因。
静态内部类和非静态内部类的加载规则都是 在调用的时候才加载,时间是一样的,会先加载外部类。如果不调用,那么就不会被加载!
handler.removeCallBacksAndMessages(null) 将所有的Callbacks和Messages全部清除掉。可以防止内存泄漏
handler.post() 运行在主线程中,勿做耗时操作!
FFmpeg 的裁剪,crop 和改变视频方向 transpose 不能在 vcode 为 copy 的情况下使用,否则没效,因为是复制,但是可以进行时间长短的截取
OS 安全状态肯定不会导致死锁,不安全状态不一定会导致死锁
String str=new String("abc"); 创建了两个对象, String a = "a"+"b"; 3 个
URL实际上就是是对资源的一种描述:<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]<query-string>
主键 | 唯一索引 | |
---|---|---|
个数 | 有且只有一个 | 0,1,多个 |
Allow NULL | x | √ |
与对方的关系 | 充分不必要 | 必要不充分 |
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 <!-- android:state_pressed 设置点击时候的属性 --> 4 <item android:state_pressed="true"> 5 <shape> 6 <solid android:color="#0CA5DF" /> 7 <!-- 描边 --> 8 <stroke 9 android:dashGap="0dp" 10 android:dashWidth="5dp" 11 android:width="0dp" 12 android:color="#0CA5DF" /> 13 <!-- 圆角 --> 14 <corners 15 android:bottomLeftRadius="0dp" 16 android:bottomRightRadius="0dp" 17 android:topLeftRadius="0dp" 18 android:topRightRadius="0dp" /> 19 20 <!-- <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" /> --> 21 </shape> 22 </item> 23 <!-- android:state_pressed 设置获取了焦点时候的属性,也就是onTouch 的 move --> 24 <item android:state_focused="true"> 25 <shape> 26 <solid android:color="#0CA5DF" /> 27 28 <stroke android:width="0dp" android:color="#0CA5DF" /> 29 30 <corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" /> 31 32 <!-- <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" /> --> 33 </shape> 34 </item> 35 36 <!-- android:state_pressed 设置没被点击或者触摸时候属性 --> 37 <item android:state_enabled="false"> 38 <shape> 39 <solid android:color="#0050AB" /> 40 41 <corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" /> 42 43 <!-- <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" /> --> 44 </shape> 45 </item> 46 47 <item> 48 <shape> 49 <!-- <solid android:color="#0a9c89" /> --> 50 <solid android:color="#0050AB" /> 51 52 <!-- <stroke android:width="3dp" android:color="#000000" /> --> 53 54 <corners android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" /> 55 56 <!-- <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" /> --> 57 </shape> 58 </item> 59 60 </selector>
代码获取 sha1
1 public static String sHA1(Context context) { 2 try { 3 PackageInfo info = context.getPackageManager().getPackageInfo( 4 context.getPackageName(), PackageManager.GET_SIGNATURES); 5 byte[] cert = info.signatures[0].toByteArray(); 6 MessageDigest md = MessageDigest.getInstance("SHA1"); 7 byte[] publicKey = md.digest(cert); 8 StringBuffer hexString = new StringBuffer(); 9 for (int i = 0; i < publicKey.length; i++) { 10 String appendString = Integer.toHexString(0xFF & publicKey[i]) 11 .toUpperCase(Locale.US); 12 if (appendString.length() == 1) 13 hexString.append("0"); 14 hexString.append(appendString); 15 hexString.append(":"); 16 } 17 String result = hexString.toString(); 18 return result.substring(0, result.length()-1); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 return null; 23 }
大于0的就是指compare方法第一个参数要放在第二个参数的前面,小于0就是指第一个参数要放在第二个参数后面