安卓渐变色状态栏
节选自:Android实现状态栏(statusbar)渐变效果的示例 (有改动)
private View statusBarView; @Override protected void onCreate(Bundle savedInstanceState) { getWindow().getDecorView().addOnLayoutChangeListener(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) { initStatusBar(); } }); } private void initStatusBar() { if (statusBarView == null) { int identifier = getResources().getIdentifier("statusBarBackground", "id", "android"); statusBarView = getWindow().findViewById(identifier); } if (statusBarView != null) { statusBarView.setBackgroundResource("你的渐变drawable资源id"); } }
【转】Android 端 Rsa加密数据
1.android 端加密方式
- 非对称加密 (RSA)
- 对称加密 (DES,AES,3DES)
- MD5加密
- BASE64编码
ps:这篇主要介绍android rsa加密
2.Rsa加密原理
1.随机选择两个大质数p和q,p不等于q,计算N=pq;
2.选择一个大于1小于N的自然数e,e必须与(p-1)(q-1)互素。
3.用公式计算出d:d×e = 1 (mod (p-1)(q-1)) 。
4.销毁p和q。
最终得到的N和e就是“公钥”,d就是“私钥”,发送方使用N去加密数据,接收方只有使用d才能解开数据内容。
3.Rsa相比对称加密算法优缺点
优点:
- 对称加密比对称加密算法更安全
缺点:
- 加密速度更慢,适用于加密少量数据
4.示例 (公钥加密,私钥解密)
通过公钥字符串 获取PublicKey对象
byte[] buffer = Base64Utils.decode(publicKeyStr); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); RSAPublicKey publicKey = (RSAPublicKey) RSAPublicKey.generatePublic(keySpec);
使用publickey加密数据
Cipher cipher = Cipher.getInstance("转换"); // 编码前设定编码方式及密钥 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 传入编码数据并返回编码结果 byte[] encrptData = cipher.doFinal(data);
几个关键参数介绍:
1.转换 是一个字符串,它描述为产生某种输出而在给定的输入上执行的操作(或一组操作); 形式可以是 算法/模式/填充 或 算法; 常见的模式如下:
RSA (如果你的明文不够128字节加密的时候会在你的明文前面,前向的填充零。解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的零去掉,才是真正之前加密的明文。)
RSA/ECB/PKCS1Padding (加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样)
RSA/None/PKCS1Padding
第一个 RSA 等价于 RSA/None/NoPadding .使用此模式加密后 同一个明文、同一个公钥每次生成同一个密文.攻击者能够据此识别到同一个信息都是何时被发送。 所以一般使用第二个 RSA/ECB/PKCS1Padding .
2.编码方式设定
cipher.init(MODE, publicKey);
常见编码方式 (MODE):
ENCRYPT_MODE: Cipher 初始化为加密模式的常量 (常用)
DECRYPT_MODE: Cipher 初始化为解密模式的常量 (常用)
WRAP_MODE :Cipher 初始化为密钥包装模式的常量
UNWRAP_MODE :Cipher 初始化为密钥解包模式的常量
PUBLIC_KEY :解包的密钥为“公钥”的常量
PRIVATE_KEY : 解包的密钥为“私钥”的常量
SECRET_KEY :解包的密钥为“秘密密钥”的常量
5.开发过程中容易遇到的坑
1.客户端需要与后端确认好使用同一转换模式 做到一一对应. 如果后端(java使用 RSA),则前端 需要使用(RSA/ECB/PKCS1Padding) 而不是 RSA.
2.前端请求下来的公钥字符串如果 包含 “—–BEGIN PUBLIC KEY—–” 和 “—–END PUBLIC KEY—–“,需要将其切掉,如果直接使用 会报 InvalidKeySpecException .
Android指纹登录
CRMEB
高品质开源商城系统-CRMEB
系统采用TP6+Swoole4高性能框架开发,支持数据库独立部署、服务器集群;数据采用redis缓存、队列、数据库连接池等技术,提升系统整体性能,为品牌商家长效增长保驾护航。
Swoole:PHP 协程框架
Swoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务,让 PHP 不再局限于 Web 领域。Swoole4 协程的成熟将 PHP 带入了前所未有的时期, 为性能的提升提供了独一无二的可能性。Swoole 可以广泛应用于互联网、移动通信、云计算、 网络游戏、物联网(IOT)、车联网、智能家居等领域。使用 PHP + Swoole 可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
Android NFC 开发相关文章
DirectAdmin笔记
数据库密码
/usr/local/directadmin/conf/mysql.conf
CSF防火墙
如何在 CentOS 8 上安装和配置服务器防火墙 (CSF)?
编辑配置文件 vi /etc/csf/csf.conf 重启CSF防火墙 csf -r
Redis
编辑配置文件 vi /etc/redis.conf 使用配置文件启动 redis redis-server /etc/redis.conf &
【转】高分辨率屏幕远程桌面的时候屏幕内容过小解决方案
转载自:高分辨率屏幕远程桌面的时候屏幕内容过小,有哪位大神知道如何解决这个问题
因为现在新出的笔记本屏幕分辨率较高,使用远程桌面时由于两边分辨率不同,导致自己看到对方桌面的图片和文字都很小,特别影响体验。亲测解决办法如下:
1、修改注册表:
用运行-regedit编辑注册表,找到:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide
新建DWORD,命名PreferExternalManifest,并双击设置值为1.
2、控制面板-文件资源管理器选项-查看-高级选项-隐藏已知文件类型的扩展名,去掉打勾。
3、到桌面右键新建-文本文档-确认。复制并粘贴如下代码,保存后修改文本名称为:mstsc.exe.manifest(后缀也修改为manifest了)。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"> </assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b"> </assemblyIdentity> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</ms_windowsSettings:dpiAware> </asmv3:windowsSettings> </asmv3:application> </assembly>
———————————————华丽分割
4、将这个文件放到指定路径中:C:\Windows\System32;找不到路径的,在桌面已经生成的远程桌面快捷方式,右键-属性-打开文件所在位置,就能看到C:\Windows\System32\mstsc.exe,将代码文件放到文件夹里,重启电脑,再次打开RemoteAPP和远程链接,Bingo!分辨率是不是正常了,虽然虚了一些,但是起码看得清楚!
【转】Android编程实现自定义ProgressBar样式示例(背景色及一级、二级进度条颜色)
转载自:Android编程实现自定义ProgressBar样式示例(背景色及一级、二级进度条颜色)
本文实例讲述了Android编程实现自定义ProgressBar样式。分享给大家供大家参考,具体如下:
效果图如下,本例中设置了第一级进度条和第二级进度条。
样式资源:progressbar_bg.xml,放在drawable文件夹下:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!--3个层的顺序即为显示时的叠加顺序--> <!--背景色--> <item android:id="@android:id/background"> <shape> <corners android:radius="5dip" /> <solid android:color="#CCCCCC" /> </shape> </item> <!--二级进度条的颜色--> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="5dip" /> <solid android:color="#88F56100" /> </shape> </clip> </item> <!--一级进度条的颜色,也可以直接替换成图片--> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="5dip" /> <solid android:color="#F56100" /> </shape> </clip> </item> </layer-list>
布局代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ProgressBar android:id="@+id/progress_bar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="100dp" android:minHeight="20dp" android:padding="10dp" android:progressDrawable="@drawable/progressbar_bg" /> </LinearLayout>
【转】Toast 在 Android 7.1 崩溃排查及修复
转载自:Toast 在 Android 7.1 崩溃排查及修复
崩溃详情
尝试复现
- 通过崩溃信息从网上找到的一些论述,发现这个问题是因为主线程被阻塞了,而 Toast 没有及时销毁导致的,那么接下来让我们对它进行复现
- 为什么出现这个问题,是因为 Toast 的显示是通过 Handler.sendMessage,所以这个操作是异步的,而 Thread.sleep 会阻塞主线程,从而导致 Handler.handleMessage 在接收到消息的时候 WindowToken 已经失效了
- 经过实际的测试:如果是短吐司,sleep 2000 毫秒的时候还是会抛出异常,sleep 1500 毫秒则不会发生异常;如果是长吐司,sleep 3500 毫秒的时候也是会抛出异常,sleep 3000 毫秒的时候就不会发生异常
- 由此可见,WindowToken 失效的时间是跟 Toast 的显示时长有关,如果是短吐司,那么 WindowToken 有效时长只能在 2 秒以内;如果是长吐司,那么 WindowToken 的有效时长只能在 3.5 秒以内
- 然后再通过 WindowManager.addView 的时候,它会对 WindowToken 例行检查,如果是失效状态则会抛出异常给上层,而这个机制恰好是 Android 7.1 的时候才有的,谷歌那个时候并没有考虑到对 Toast 的一些处理。因为通过浏览 Android 7.0 和 Android 6.0 的源码,发现谷歌也是没有进行 try 处理,但是崩溃的机型却全是清一色的 Android 7.1
问题排查
- 通过查看这个崩溃都是在 Android 7.1 的机型才会出现,那么我们可以对比 Android 7.1 的源码和 Android 8.0 看看
- 通过追踪不同 API 等级的源码,发现这个问题在 Android 8.0 上面已经被被修复了
- 通过查看 Toast 的源码,发现 Toast 其实就是一个 WindowManager,并且通过 Handler 来显示和隐藏。
- 而产生崩溃的地方是在 handleShow 方法里面
- 而 handleShow 方法是被 Toast 中的名为 TN 静态内部类中的 Handler 对象调用
进行修复
- 那么解决这一问题的方式的思路是,将这个 Handler 对象通过反射获取到,然后使用静态代理的方式对它进行回调并对进行捕获异常
- 最后经过验证,是 OK 的,已经没有崩溃的问题出现了。
- 但是新的问题又出现了,我们以前写 Toast 是这样的
Toast.makeText(this, "666", Toast.LENGTH_LONG).show();
- 但是如果为了修复这个崩溃问题,我们需要这样写
Toast toast = Toast.makeText(this, "666", Toast.LENGTH_LONG); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) { try { // 获取 mTN 字段对象 Field mTNField = Toast.class.getDeclaredField("mTN"); mTNField.setAccessible(true); Object mTN = mTNField.get(toast); // 获取 mTN 中的 mHandler 字段对象 Field mHandlerField = mTNField.getType().getDeclaredField("mHandler"); mHandlerField.setAccessible(true); final Handler mHandler = (Handler) mHandlerField.get(mTN); // 偷梁换柱 mHandlerField.set(mTN, new Handler() { @Override public void handleMessage(Message msg) { // 捕获这个异常,避免程序崩溃 try { mHandler.handleMessage(msg); } catch (WindowManager.BadTokenException ignored) {} } }); } catch (IllegalAccessException | NoSuchFieldException ignored) {} } toast.show();
- 这样写感觉心好累,不想这样写,有没有一种方式可以一劳永逸?
- 答案当然是有了,使用第三方 Toast 封装的框架:https://github.com/getActivity/Toaster,框架内部已经处理了这个问题,调用者无需关心此问题。
- 使用框架后,可以这么写
Toaster.show("666");
- 还是一句代码,就问你 6 不 6
问题总结
- 问题描述:Toast 在主线程阻塞情况下会导致 WindowToken 失效,从而导致应用崩溃
- 涉及范围:所有 Android 版本为 7.1 的用户,并且项目中使用了原生 Toast 的地方都有可能触发崩溃
- 解决方案:不直接使用原生 Toast,而使用第三方 Toast 框架