亢奋猫 发布的文章

通过使用该工具我们可以轻松调试iOS或macOS的系统推送,我们只需要准备一个证书,准备设备token,就可以直接和 apns 通信并发送推送信息。通常我们可以用次工具判断证书是否正确配置。

Pusher

OS X and iOS application and framework to play with the Apple Push Notification service (APNs)

osx1.png

什么是注解 (Annotation)

注解其实就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相对应的处理。

为什么要用注解

注解可以给类、方法上注入信息。

常见注解

java.lang包下存在着5个基本的Annotation,其中有2个Annotation我们是非常常见的了。

@Overried

@Overried是告诉编译器要检查该方法是实现父类的,可以帮我们避免一些低级的错误。

比如当我们写了@Overried之后,我们在实现equals()方法的时候,把euqals()打错了,那么编译器就会发现该方法并不是实现父类的,于是就会给予错误。

@Deprecated

该注解也非常常见,Java在设计的时候,可能觉得某些方法设计得不好,为了兼容以前的程序,是不能直接把它抛弃的,于是就设置它为过时。

自定义注解

我们自定义的注解是可以带成员变量的,定义带成员变量的注解叫做元数据Annotation

public @interface MyAnnotation {
    String username();
}

使用注解

// 注解拥有什么属性,在修饰的时候就要给出相对应的值
@MyAnnotation(username = "kangfenmao")
public void add() {}

读取注解

@MyAnnotation(username = "kangfenmao")
public void add() {
  MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
  String username = annotation.username();
}

总结

注入对象的步骤:

  1. 得到想要注入的对象属性
  2. 通过属性得到注解的信息
  3. 通过属性的写方法将注解的信息注入到对象上
  4. 最后将对象赋给类。

注解其实就是两个作用:

  1. 让编译器检查代码
  2. 将数据注入到方法、成员变量、类上

如果没有响应注解内容,注解可以说是没有实用价值。让注解真正发挥作用,主要就在于注解处理方法。

JDK 常用注解

  1. 基本 Annotation 在 lang 包下,用于常用于标记该方法,抑制编译器警告等
  2. 元 Annotaion 在 annotaion 包下,常用于修饰其他的 Annotation 定义

升级 macOS 10.15.6 后,发现 php 版本号已经升级到了 php7.3

运行 php -v

PHP 7.3.11 (cli) (built: Jun  5 2020 23:50:40) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies

问题

但是比较坑的是默认没有安装 zip 扩展,而 Laravel 是需要 ext-zip 扩展包的:

composer global require laravel/installer

QQ20200901-170526@2x.png

brew 安装 [email protected]

brew update
brew install [email protected]
brew link [email protected] --force

必须要使用 force

编译安装 [email protected]

本文不再展开,参考这篇文章:https://segmentfault.com/a/1190000022699382

查考资料

discussions.apple.com
install-ext-zip-for-mac

我们在使用 function base component 的时候可以使用 useParams 来获取参数, 类似这样:

const { id } = useParams()

当我们使用 class base component 的时候该如何写好类型呢?

先说结论

import { RouteComponentProps } from 'react-router';

// example route
<Route path="/products/:name" component={ProductContainer} />

interface MatchParams {
    name: string;
}

interface Props extends RouteComponentProps<MatchParams> {
}

查看源代码

// from typings
export interface RouteComponentProps<P> {
  match: match<P>;
  location: H.Location;
  history: H.History;
  staticContext?: any;
}

export interface match<P> {
  params: P;
  isExact: boolean;
  path: string;
  url: string;
}

当我们升级 package.json 包后,容易出现下面的错误:

npm WARN [email protected] requires a peer of [email protected]>= 4.12.1 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @typescript-eslint/[email protected] but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @typescript-eslint/[email protected] but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected] but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected] but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]^5.0.0 || ^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]>=6.1.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected] - 6.x but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]^3 || ^4 || ^5 || ^6 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of [email protected]^1.8.18 but none is installed. You must install peer dependencies yourself.

audited 2211 packages in 7.724s

69 packages are looking for funding
  run `npm fund` for details

found 4992 low severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

问题分析

package-lock.json 中锁定的包版本和新的包依赖的版本有冲突,所以 npm 不知道如何处理这些冲突。

解决办法

rm package-lock.json && rm -rf node_modules/ && npm install

注意⚠️

任何版本升级都可能产生新的问题,建议充分测试后才能上线运行

版本信息

react native: 0.62.2
react-native-apk-manager: ^1.1.0

错误摘要

java.lang.RuntimeException: Package manager has died at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:156)

错误信息

java.lang.RuntimeException: Package manager has died
    at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:139)
    at com.superhao.react_native_apk_manager.ApkManagerModule.isAppInstalled(ApkManagerModule.java:210)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
    at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
    at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
    at android.os.Looper.loop(Looper.java:148)
    at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
    at java.lang.Thread.run(Thread.java:818)
Caused by: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(Binder.java:503)
    at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:2272)
    at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:134)
    ... 11 more
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(Binder.java:503)
    at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:2272)
    at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:134)
    at com.superhao.react_native_apk_manager.ApkManagerModule.isAppInstalled(ApkManagerModule.java:210)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
    at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
    at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
    at android.os.Looper.loop(Looper.java:148)
    at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
    at java.lang.Thread.run(Thread.java:818)

设备分布

image

问题解决

re: https://github.com/1556173267/react-native-apk-manager/issues/6

  1. 需要避免同时多个线程调用 getPackageInfo,这样容易导致内存溢出 (主要解决方案)
  2. 避免获取过多 package 信息,如下所示
pm.getPackageInfo("com.tencent.mm", PackageManager.GET_ACTIVITIES);
// 修改为 👇
pm.getApplicationInfo("com.tencent.mm", PackageManager.GET_META_DATA);

参考文档

Android 获取 PackageInfo 引发 Crash 填坑
Package Manager Died
Android Package manager has died with TransactionTooLargeException
分析 Package manager has died

最近遇到了很多停更的 github 仓库,作者已明显放弃了维护。当我们需要修改软件包源代码的时候,就麻烦了。如果自己 fork 后发布重新发布新包,维护成本比较高。对于这种情况,更高效的办法是通过打 patch 的方式来修正软件包的代码。

下面介绍一下具体的实现办法:

为单个文件生成补丁

复制源文件,并修改复制后的文件内容,然后运行 diff 命令:

diff -up path/to/source.ext path/to/source.copy.ext > filename.patch

这条命令会产生类似如下的输出, 你将它重定向到一个文件中, 这个文件就是patch.

patch.png

参数详解:
-u 显示有差异行的前后几行(上下文), 默认是前后各3行, 这样, patch中带有更多的信息
-p 显示代码所在的c函数的信息

为多个文件生成补丁

diff -uprN path/to/source/ path/to/source_copy/ > patch

这条命令对比了 path/to/source/ 和 path/to/source_copy/ 两个目录下的所有源码差异.

参数详解:

-r 递归地对比一个目录和它的所有子目录(即整个目录树).
-N 如果某个文件缺少了, 就当作是空文件来对比。如果不使用本选项, 当diff发现旧代码或者新代码缺少文件时, 只简单的提示缺少文件。如果使用本选项, 会将新添加的文件全新打印出来作为新增的部分。

打补丁

我们将所有生成的 patch 文件放到 patches 目录后就可以使用脚本批量打补丁了。

#/bin/bash

# patch all file in patches dir
for i in $(find ./patches -name '*.patch');
do
  patch -N -p0 < $i > /dev/null 2>&1 &
done