1. 合理的使用context–比如我们常使用的Toast,Service,最好使用getApplicationContext(),因为这些在activity结束的时候可能仍在运行
下图展示了一些场景我们该用哪种context(图是盗的,附原文地址https://possiblemobile.com/2013/06/context/ 是国外的大牛写的关于context的使用)
Android获取存储路径
Android Q(Android 10)之前,需要添加权限,如下:
|
1 2 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> |
Android Q(Android 10)开始 在App专属目录下本App可以随意操作,无需申请权限,不过App专属目录会在App卸载时跟随删除。看下面几个目录(通过Application的context就可以访问)。
- getFilesDir() :/data/user/0/本应用包名/files
- getCacheDir():/data/user/0/本应用包名/cache
- getExternalFilesDir(null):/storage/emulated/0/Android/data/本应用包名/files
- getExternalCacheDir():/storage/emulated/0/Android/data/本应用包名/cache
getFilesDir和getCacheDir是在手机自带的一块存储区域(internal storage),通常比较小,SD卡取出也不会影响到,App的sqlite数据库和SharedPreferences都存储在这里。所以这里应该存放特别私密重要的东西。
getExternalFilesDir和getExternalCacheDir是在SD卡下(external storage),在sdcard/Android/data/包名/files和sdcard/Android/data/包名/cache下,会跟随App卸载被删除。
files和cache下的区别是,在手机设置-找到本应用-在存储中,点击清除缓存,cache下的文件会被删除,files下的文件不会。
谷歌推荐使用getExternalFilesDir。我们项目的下载是个本地功能,下载完成后是存本地数据库的,不是放网络上的,所以下载的音视频都放到了这下面,项目卸载时跟随App都删除了。getExternalFilesDir方法需要传入一个参数,传入null时得到就是sdcard/Android/data/包名/files,传入其他字符串比如"Picture"得到sdcard/Android/data/包名/files/Picture。
参考代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/** * 获取app缓存路径 * * @param context Application Context * @return 缓存路径 */ @NonNull public static String getCacheDir(Context context) { String cacheDir; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { //外部存储可用 final File file = context.getExternalCacheDir(); if (null == file) { cacheDir = context.getCacheDir().getPath(); } else { cacheDir = file.getPath(); } } else { //外部存储不可用 cacheDir = context.getCacheDir().getPath(); } return cacheDir; } /** * 获取app文件路径 * * @param context Application Context * @return app文件路径 */ @NonNull public static String getFilesDir(Context context) { String filesDir; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { //外部存储可用 final File file = context.getExternalFilesDir(null); if (null == file) { filesDir = context.getFilesDir().getPath(); } else { filesDir = file.getPath(); } } else { //外部存储不可用 filesDir = context.getFilesDir().getPath(); } return filesDir; } |
参考链接
IntelliJ IDEA 提示 'try' can use automatic resource management Java7新特性
IntelliJ IDEA会提示
|
1 |
'try' can use automatic resource management。 |
从 Java 7 build 105版本开始,Java 7的编译器和运行环境支持新的try-with-resources语句,称为ARM 块(Automatic Resource Management) ,自动资源管理。
新的语句支持包括流以及任何可关闭的资源。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public static void filyCopy(File one,File two){ FileInputStream fileInput = null; FileOutputStream fileOutput = null; try { fileInput = new FileInputStream(one); fileOutput = new FileOutputStream(two); byte[] b = new byte[1024]; int len = 0; while((len = fileInput.read(b)) != -1){ fileOutput.write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); } finally {//释放资源 try { if(fileInput != null){ fileInput.close(); } if(fileOutput != null){ fileOutput.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } |
使用try-with-resources语句来简化代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void filyCopy2(File one,File two){ try (FileInputStream fileInput = new FileInputStream(one); FileOutputStream fileOutput = new FileOutputStream(two);){ byte[] b = new byte[1024]; int len = 0; while((len = fileInput.read(b)) != -1){ fileOutput.write(b, 0, len); } } catch (Exception e) { e.printStackTrace(); } } |
在这个例子中,数据流会在try执行完毕后自动被关闭,前提是,这些可关闭的资源必须实现java.lang.AutoCloseable接口。
注:目前java.lang.AutoCloseable接口的子接口或实现类如下:
所有已经子接口:
|
1 |
AsynchronousByteChannel, AsynchronousChannel, BaseStream, ByteChannel, CachedRowSet, CallableStatement, Channel, Clip, Closeable, Connection, DataLine, DirectoryStream, DoubleStream, FilteredRowSet, GatheringByteChannel, ImageInputStream, ImageOutputStream, InterruptibleChannel, JavaFileManager, JdbcRowSet, JMXConnector, JoinRowSet, Line, LongStream, MidiDevice, MidiDeviceReceiver, MidiDeviceTransmitter, Mixer, MulticastChannel, NetworkChannel, ObjectInput, ObjectOutput, Port, PreparedStatement, ReadableByteChannel, Receiver, RMIConnection, RowSet, ScatteringByteChannel, SecureDirectoryStream, SeekableByteChannel, Sequencer, SourceDataLine, StandardJavaFileManager, Statement, Stream, SyncResolver, Synthesizer, TargetDataLine, Transmitter, WatchService, WebRowSet, WritableByteChannel |
所有已知实现类:
|
1 2 3 4 |
AbstractInterruptibleChannel, AbstractSelectableChannel, AbstractSelector, AsynchronousFileChannel, AsynchronousServerSocketChannel, AsynchronousSocketChannel, AudioInputStream, BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, ByteArrayInputStream, ByteArrayOutputStream, CharArrayReader, CharArrayWriter, CheckedInputStream, CheckedOutputStream, CipherInputStream, CipherOutputStream, DatagramChannel, DatagramSocket, DataInputStream, DataOutputStream, DeflaterInputStream, DeflaterOutputStream, DigestInputStream, DigestOutputStream, FileCacheImageInputStream, FileCacheImageOutputStream, FileChannel, FileImageInputStream, FileImageOutputStream, FileInputStream, FileLock, FileOutputStream, FileReader, FileSystem, FileWriter, FilterInputStream, FilterOutputStream, FilterReader, FilterWriter, Formatter, ForwardingJavaFileManager, GZIPInputStream, GZIPOutputStream, ImageInputStreamImpl, ImageOutputStreamImpl, InflaterInputStream, InflaterOutputStream, InputStream, InputStream, InputStream, InputStreamReader, JarFile, JarInputStream, JarOutputStream, LineNumberInputStream, LineNumberReader, LogStream, MemoryCacheImageInputStream, MemoryCacheImageOutputStream, MLet, MulticastSocket, ObjectInputStream, ObjectOutputStream, OutputStream, OutputStream, OutputStream, OutputStreamWriter, Pipe.SinkChannel, Pipe.SourceChannel, PipedInputStream, PipedOutputStream, PipedReader, PipedWriter, PrintStream, PrintWriter, PrivateMLet, ProgressMonitorInputStream, PushbackInputStream, PushbackReader, RandomAccessFile, Reader, RMIConnectionImpl, RMIConnectionImpl_Stub, RMIConnector, RMIIIOPServerImpl, RMIJRMPServerImpl, RMIServerImpl, Scanner, SelectableChannel, Selector, ServerSocket, ServerSocketChannel, Socket, SocketChannel, SSLServerSocket, SSLSocket, StringBufferInputStream, StringReader,StringWriter,URLClassLoader, Writer, XMLDecoder, XMLEncoder, ZipFile,ZipInputStream, ZipOutputStream |
对于Android用户来说,只有编译工程的 minSdkVersion大于 19(Android 4.4)的时候才能生效。
|
1 |
try-with-resources is only supported if your minSdkVersion is set to 19 or higher. |
参考链接
使用HP Service Pack for ProLiant Gen8.1升级HP ProLiant MicroServer Gen8固件
家里使用了HP Gen8作为NAS服务器,对于iLO/BIOS来说,可以直接通过控制台升级。但是网卡/磁盘阵列的固件升级需要使用HP Service Pack for ProLiant(HP SSP)来升级。具体升级过程如下:
继续阅读使用HP Service Pack for ProLiant Gen8.1升级HP ProLiant MicroServer Gen8固件
国密算法
算法分类
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
bash切换zsh后.bashrc文件失效的解决方案
问题
- 从
bash切换到zsh后,发现原先bash下的bashrc文件配置都失效了(显示zsh: command not found字样,当然如果手动通过source FileName加载是可以的),macOS Catalina(10.15.5)已经默认切换到zsh,那么如何实现不用每次加载.bashrc文件就实现alias等便捷功能呢?
解决方案
- 使用系统级的
/etc/zshrc或/etc/zprofile - 使用用户级的
~/[X]bashrc或~/[X]profile
- 鉴于
/etc/zshrc里有较多zsh特性配置,而且默认全局加载,因此这里通过编辑用户级的profile并加载原先的bashrc(即Bash Shell下用户文件)来实现我们的需求
详细步骤
- 复制系统文件并修改权限
|
1 2 3 4 5 6 7 8 9 |
mu@xiaomudeMacBook-Pro ~ % cp /etc/zprofile ~/.zprofile mu@xiaomudeMacBook-Pro ~ % ll ~/.zprofile -r--r--r-- 1 mu staff 255 9 6 09:35 /Users/mu/.zprofile mu@xiaomudeMacBook-Pro ~ % chmod u+w ~/.zprofile #要实现自定义必须添加写权限,否则只有只读权限 mu@xiaomudeMacBook-Pro ~ % ll ~/.zprofile -rw-r--r-- 1 mu staff 255 9 6 09:35 /Users/mu/.zprofile |
- 追加自定义配置项,加载
Bash Shell的.bashrc文件
|
1 2 3 4 |
mu@xiaomudeMacBook-Pro ~ % cat .bashrc alias ll='ls -l' mu@xiaomudeMacBook-Pro ~ % echo "source ~/.bashrc" >> .zprofile |
- 测试
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
mu@xiaomudeMacBook-Pro ~ % ll #配置暂未生效 zsh: command not found: ll mu@xiaomudeMacBook-Pro ~ % source .zprofile #加载配置文件,使其立即生效;下一次打开终端Shell会话,将自动加载 mu@xiaomudeMacBook-Pro ~ % ll total 16 drwx------ 5 mu staff 160 8 23 14:38 Applications drwx------@ 4 mu staff 128 1 2 2019 Applications (Parallels) drwx------@ 4 mu staff 128 9 1 15:23 Desktop drwx------+ 20 mu staff 640 8 29 12:14 Documents drwx------@ 35 mu staff 1120 9 6 09:29 Downloads drwx------@ 85 mu staff 2720 8 30 11:05 Library drwx------+ 4 mu staff 128 8 20 20:17 Movies drwx------+ 8 mu staff 256 8 20 20:17 Music drwx------ 26 mu staff 832 9 6 09:28 Nextcloud drwx------ 3 mu staff 96 1 2 2019 Parallels drwx------+ 6 mu staff 192 8 20 20:01 Pictures drwxr-xr-x+ 4 mu staff 128 11 28 2018 Public drwxr-xr-x 4 mu staff 128 12 9 2018 PycharmProjects -rw-r--r-- 1 mu staff 811 12 15 2018 Untitled.ipynb -rw-r--r-- 1 mu staff 1578 12 29 2018 Untitled1.ipynb drwxr-xr-x 3 mu staff 96 8 25 16:08 VirtualBox VMs drwxr-xr-x 2 mu staff 64 1 25 2019 WeChatProjects |
参考链接
在macOS Catalina(10.15.5)上搭建Flutter开发环境
下载并安装目前最新的Android Studio 4.0,然后通过Android Studio 4.0安装Android SDK。
下载目前最新的flutter
|
1 2 3 4 5 6 7 |
$ cd ~ $ mkdir Android $ cd Android $ git clone -b stable https://github.com/flutter/flutter.git |
配置环境变量
|
1 2 3 4 5 6 7 8 9 10 11 12 |
$ export PATH=/Users/`whoami`/Android/flutter/bin:$PATH # android sdk目录,替换为你自己的即可,下面是Android Studio安装SDK的默认目录 $ export ANDROID_HOME="/Users/`whoami`/Library/Android/sdk" $ export PATH=${PATH}:${ANDROID_HOME}/tools $ export PATH=${PATH}:${ANDROID_HOME}/platform-tools $ export PUB_HOSTED_URL=https://pub.flutter-io.cn $ export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn |
上述环境变量,全部追加到 .bashrc 尾部
|
1 2 3 4 5 6 7 |
export PATH=/Users/`whoami`/Android/flutter/bin:$PATH # android sdk目录,替换为你自己的即可,下面是Android Studio安装SDK的默认目录 export ANDROID_HOME="/Users/`whoami`/Library/Android/sdk" export PATH=${PATH}:${ANDROID_HOME}/tools export PATH=${PATH}:${ANDROID_HOME}/platform-tools export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn |
如果不增加到.bashrc 尾部,则在 Android Studio 4.0 创建项目的时候,会非常慢,主要是网络问题。
必要的环境配置,依赖下载
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#对于 macOS Catalina 10.15.5 来说,由于Shell被替换成了ZSH,因此环境变量需要重新配置一下 $ cp /etc/zprofile ~/.zprofile $ chmod u+w ~/.zprofile $ echo "source ~/.bashrc" >> .zprofile $ flutter doctor $ flutter doctor --android-licenses $ sudo gem install cocoapods # 杀掉全部的dart进程,否则可能导致长时间无法创建项目的问题 # 任何时候,flutter相关卡住,貌似都可以这样操作 $ killall -9 dart |
macOS Catalina(10.15.5)用蓝牙PAN共享Wi-Fi上网
今天有需要共享上网进行抓包分析报文的情况。
研究了一下MacBook Pro(macOS Catalina(10.15.5))如何通过蓝牙PAN(Bluetooth PAN)来共享笔记本连接的Wi-Fi网络出来,让手机通过共享出来的蓝牙热点来上网的方法。
由于蓝牙PAN(Bluetooth PAN)本质属于局域网转发,起到一个简单网关的作用。因此我们需要设置蓝牙设备的IP地址跟需要共享的Wi-Fi网卡相同。
具体操作如下:
利用Ubuntu 18.04恢复群晖(Synology)NAS Raid1(DSM 6.x)硬盘数据
如果 Synology NAS 出现故障,则可以使用计算机和 Ubuntu live CD 轻松恢复其硬盘上存储的数据。确保 Synology NAS 硬盘上运行的文件系统是 EXT4 或 Btrfs,然后按照以下步骤恢复数据。此处我们以 Ubuntu 18.04 版本为例。
杭州集体户档案调档流程
如果单位能自己管理档案,并且要求转入,则在手机的 浙里办 上搜索 流动任意人事档案转出, 如下图: