工作笔记

环境

硬件: MacBook Pro 2017
OS: macOS Mojave
Android: Android Studio3.2, Java8, MVP, Retrofit
iOS: Xcode12, Swift5, Storyboard, Alamofire

纯粹是个人的工作笔记,随时更新。

Issue

Android

Button 自带阴影的底部被截

在 Button 的父级控件中设置:

android:clipChildren="false"
android:clipToPadding="false"

EditText 抢夺初始焦点

父级控件内增加 <requestFocus />

华为手机不输出 Log

拨打电话界面输入 *#*#2846579#*#*,进入后台设置界面打开日志显示

debug 包正常,release 包闪退 bug

神奇的问题,记录下解决过程。

一开始尝试打印日志(正式包打印日志需要设置 app.gradlebuildTypes.releasebuildConfigField "Boolean", "LOGGING", "false")debuggable true),看到的是 NPE。

因为闪退处包含解析 assets 中的 json 的步骤,以为是正式包没有成功解析文件,但捕捉了所有 null 后还是闪退。

再次对比 debug 和 release 的区别:

buildTypes {
    release {
        signingConfig signingConfigs.release
        buildConfigField "Boolean", "LOGGING", "false"
        debuggable false
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }

    debug {
        signingConfig signingConfigs.release
        buildConfigField "Boolean", "LOGGING", "true"
        debuggable true
        minifyEnabled false
    }
}

签名是一样的(因为很多第三方 SDK 不能设置调试用签名),日志应该没有影响,只剩下 debuggable 和 minifyEnabled(代码混淆)。

尝试给 debug 包增加混淆设置后成功复现,总算确定问题点,但还是没搞懂跟混淆有什么关系。

最后是发现一个 Bean 类的 package 写错了(因为是复制的网络代码),这个写错了居然也能编译通过的吗,而且不混淆就不报错,就离谱。

MVP 框架,页面关闭后 Presenter 没有解绑

突然发现有个 Presenter 在页面关闭后没有解绑,到了别的页面还在触发事件,就报了错。查了一会发现是原来的基础框架写的有问题。

原来的写法(不是我写的):

public class BaseActivity<T extends IBasePresenter> extends AppCompatActivity { 
    protected T mPresenter;
    ...
}

public abstract class SwipeBackActivity<T> extends BaseActivity {
    protected T mPresenter;
    ...
}

后面这个泛型继承完全写错了,所以 BaseActivity 的解绑并没有影响到子类的 mPresenter,正确写法应该是这样:

public abstract class SwipeBackActivity<T extends IBasePresenter> extends BaseActivity<T> {
    ...
}

泛型继承这种 Java 基础也是忘得差不多了,这么久才发现也是有点尴尬。

iOS

捕捉 UIImagePickerController 下拉返回事件

问题:

UIImagePickerControllerDelegate 中只有选择图片和点击取消事件,而没有下拉返回事件。而进入 UIImagePickerController 前我会使原界面进入 loading 状态,于是下拉返回后依然在 loading 状态。

解决:

参考

注:Swift 没有匿名内部类

class X: UIAdaptivePresentationControllerDelegate {

    func presentPicker() {
        let picker = UIImagePickerController()
        picker.presentationController?.delegate = self
    }

    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
        //TODO: 取消 loading
    }

}

模拟器模拟两点点击

按住⌥:显示两点,位置以模拟器中心点中心对称
按住⇧⌥:固定两点相对位置

似乎不能模拟三点或更多点

防止同时 push 多个 VC

参考

class BaseNC: UINavigationController, UINavigationControllerDelegate {

    var pushing = false

    override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = nil
        self.delegate = self
    }

    // MARK: UINavigationControllerDelegate
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        self.pushing = false
    }

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        if self.pushing {
            //拦截
            return
        } else {
            self.pushing = true
            super.pushViewController(viewController, animated: true)
        }
    }

}

单纯地在 push 动画过程中拦截掉其他 push,如果确实需要快速 push 多个 VC 可能会误拦截。
我想了一下我好像没有快速 push 多个 VC 的情况所以就用上了,结果上线之后还真有某个跳转到第三方页面的页面误拦截了,所以不推荐使用。

这个问题扩展开来是重复点击的问题,Rx 的 throttleFirst 操作符是解决方案之一。

XCode 上传包失败问题

Mac 的邮件 App 里连接 Gmail 需要在系统设置里开启 SOCKS 代理,参考 知乎

networksetup -setsocksfirewallproxy "USB 10/100/1000 LAN" localhost 1086

不过 XCode 上传包也用的 SOCKS 协议,而且代理后会上传失败,所以需要暂时关闭 SOCKS 代理。
当然包上传失败还有很多原因。

XCode 实机调试安装 App 失败

报错:Xcode: Could not locate device support files

  1. iPhoneOSDeviceSupport 下载对应手机 iOS 系统版本
  2. 将下载的压缩包放到 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
  3. 重启 XCode,再次 Run

另外 iOS 14 最低需要 XCode 12。

使 ScrollView 包含 iphoneX 底部

if #available(iOS 11.0, *) {
    scrollView.contentInsetAdjustmentBehavior = .never
}

macOS

macOS 的 VSCode 中输入法候选框会跨屏

在左边的屏幕打字打到右边的时候,候选框就有时会跳到外接屏上,不是什么大问题,但有点难受。一开始以为是输入法的问题,然后发现好像主要是 VSCode 的问题,计算的候选框位置不太对。网上没找到什么有效的解决方案,有人在 VSCode 上提了 issue 但也没解决。

最后想到个 workaround,把屏幕排列改成上下排列可以解决,外接屏在上面(在下面的话在主屏下方输入还是会跨屏),就是菜单栏没以前那么好点了。
因为我只在主屏用 VSCode 所以不用考虑外接屏用 VSCode 的问题。

笔记

Android

ScaleType

ScaleType

apk 重新签名

jarsigner -digestalg SHA1 -sigalg MD5withRSA -verbose -keystore [your_key_store_path] -signedjar [signed_apk_name] [usigned_apk_name] [your_key_store_alias]

然后输入密钥密码

your_key_store_path:您密钥所在位置的绝对路径
signed_apk_name:签名后安装包名称
usigned_apk_name:未签名的安装包名称
your_key_store_alias:密钥的别名 就是你自己创建的 .keystore 文件

DPI

  • L DPI (120 DPI),图标大小为 36 x 36 px
  • M DPI (160 DPI),图标大小为 48 x 48 px
  • H DPI (240 DPI),图标大小为 72 x 72 px
  • XH DPI (320 DPI),图标大小为 96 x 96 px
  • XXH DPI (480 DPI),图标大小为 144 x 144 px
  • XXXH DPI(640 DPI),图标大小为 192 x 192 px

iOS

CocoaPods

Podfile:

pod 'AFNetworking'                 //不显式指定依赖库版本,表示每次都获取最新版本
pod 'AFNetworking', '~>0'          //高于0的版本,写这个限制和什么都不写是一个效果,都表示使用最新版本
pod 'AFNetworking', '~> 0.1.2'     //使用大于等于0.1.2但小于0.2的版本
pod 'AFNetworking', '~>0.1'        //使用大于等于0.1但小于1.0的版本
pod 'AFNetworking', '2.0'          //只使用2.0版本
pod 'AFNetworking', '= 2.0'        //只使用2.0版本
pod 'AFNetworking', '> 2.0'        //使用高于2.0的版本
pod 'AFNetworking', '>= 2.0'       //使用大于或等于2.0的版本
pod 'AFNetworking', '< 2.0'        //使用小于2.0的版本
pod 'AFNetworking', '<= 2.0'       //使用小于或等于2.0的版本
pod 'AFNetworking', :git => 'http://gitlab.xxxx.com/AFNetworking.git', :branch => 'R20161010'  //指定分支 
pod 'AFNetworking',  :path => '../AFNetworking'  //指定本地库

命令:

  • 安装新库:pod install
  • 检查可更新库:pod outdated
  • 全部更新:pod update
  • 全部更新(不升级 pod 的 spec 仓库):pod update --verbose --no-repo-update
  • 指定更新:pod update [libName]

NSURLError(URL 加载错误码)

enum : NSInteger {
    NSURLErrorUnknown = -1,
    NSURLErrorCancelled = -999,
    NSURLErrorBadURL = -1000,
    NSURLErrorTimedOut = -1001,
    NSURLErrorUnsupportedURL = -1002,
    NSURLErrorCannotFindHost = -1003,
    NSURLErrorCannotConnectToHost = -1004,
    NSURLErrorNetworkConnectionLost = -1005,
    NSURLErrorDNSLookupFailed = -1006,
    NSURLErrorHTTPTooManyRedirects = -1007,
    NSURLErrorResourceUnavailable = -1008,
    NSURLErrorNotConnectedToInternet = -1009,
    NSURLErrorRedirectToNonExistentLocation = -1010,
    NSURLErrorBadServerResponse = -1011,
    NSURLErrorUserCancelledAuthentication = -1012,
    NSURLErrorUserAuthenticationRequired = -1013,
    NSURLErrorZeroByteResource = -1014,
    NSURLErrorCannotDecodeRawData = -1015,
    NSURLErrorCannotDecodeContentData = -1016,
    NSURLErrorCannotParseResponse = -1017,
    NSURLErrorAppTransportSecurityRequiresSecureConnection = -1022,
    NSURLErrorFileDoesNotExist = -1100,
    NSURLErrorFileIsDirectory = -1101,
    NSURLErrorNoPermissionsToReadFile = -1102,
    NSURLErrorDataLengthExceedsMaximum = -1103,
    NSURLErrorSecureConnectionFailed = -1200,
    NSURLErrorServerCertificateHasBadDate = -1201,
    NSURLErrorServerCertificateUntrusted = -1202,
    NSURLErrorServerCertificateHasUnknownRoot = -1203,
    NSURLErrorServerCertificateNotYetValid = -1204,
    NSURLErrorClientCertificateRejected = -1205,
    NSURLErrorClientCertificateRequired = -1206,
    NSURLErrorCannotLoadFromNetwork = -2000,
    NSURLErrorCannotCreateFile = -3000,
    NSURLErrorCannotOpenFile = -3001,
    NSURLErrorCannotCloseFile = -3002,
    NSURLErrorCannotWriteToFile = -3003,
    NSURLErrorCannotRemoveFile = -3004,
    NSURLErrorCannotMoveFile = -3005,
    NSURLErrorDownloadDecodingFailedMidStream = -3006,
    NSURLErrorDownloadDecodingFailedToComplete = -3007,
    NSURLErrorInternationalRoamingOff = -1018,
    NSURLErrorCallIsActive = -1019,
    NSURLErrorDataNotAllowed = -1020,
    NSURLErrorRequestBodyStreamExhausted = -1021,
    NSURLErrorBackgroundSessionRequiresSharedContainer = -995,
    NSURLErrorBackgroundSessionInUseByAnotherProcess = -996,
    NSURLErrorBackgroundSessionWasDisconnected = -997
}
  • -1: 未知的错误
  • -999: 请求被取消
  • -1000: 请求的 URL 错误,无法启动请求
  • -1001: 请求超时
  • -1002: 不支持的 URL Scheme
  • -1003: URL 的 host 名称无法解析,即 DNS 有问题
  • -1004: 连接 host 失败
  • -1005: 连接过程中被中断
  • -1006: 同 -1003
  • -1007: 重定向次数超过限制
  • -1008: 无法获取所请求的资源
  • -1009: 断网状态
  • -1010: 重定向到一个不存在的位置
  • -1011: 服务器返回数据有误
  • -1012: 身份验证请求被用户取消
  • -1013: 访问资源需要身份验证
  • -1014: 服务器报告 URL 数据不为空,却未返回任何数据
  • -1015: 响应数据无法解码为已知内容编码
  • -1016: 请求数据存在未知内容编码
  • -1017: 响应数据无法解析
  • -1018: 漫游时请求数据,但是漫游开关已关闭
  • -1019: EDGE、GPRS 等网络不支持电话和流量同时进行,当正在通话过程中,请求失败错误码
  • -1020: 手机网络不允许连接
  • -1021: 请求的 body 流被耗尽
  • -1100: 请求的文件路径上文件不存在
  • -1101: 请求的文件只是一个目录,而非文件
  • -1102: 缺少权限无法读取文件
  • -1103: 资源数据大小超过最大限制

SSL errors:

  • -1200: 安全连接失败
  • -1201: 服务器证书过期
  • -1202: 不受信任的根服务器签名证书
  • -1203: 服务器证书没有任何根服务器签名
  • -1204: 服务器证书还未生效
  • -1205: 服务器证书被拒绝
  • -1206: 需要客户端证书来验证 SSL 连接
  • -2000: 请求只能加载缓存中的数据,无法加载网络数据

Download and file I/O errors:

  • -3000: 下载操作无法创建文件
  • -3001: 下载操作无法打开文件
  • -3002: 下载操作无法关闭文件
  • -3003: 下载操作无法写文件
  • -3004: 下载操作无法删除文件
  • -3005: 下载操作无法移动文件
  • -3006: 下载操作在下载过程中,对编码文件进行解码时失败
  • -3007: 下载操作在下载完成后,对编码文件进行解码时失败

iOS 系统版本分布统计

其他

macOS

禁止关盖睡眠

禁止关盖睡眠:sudo pmset -b sleep 0; sudo pmset -b disablesleep 1
恢复关盖睡眠:sudo pmset -b sleep 5; sudo pmset -b disablesleep 0

截图

⇧⌘+3 抓取/截取全屏
⇧⌘+4 然后用鼠标框选则抓取该区域的截图
⇧⌘+4 然后按 ⎵ 则抓取软件窗口

文章