ubuntu 机器快速配置 Docker
这个脚本会安装 docker 并开启 docker swarm
curl -o- -L https://gist.githubusercontent.com/hangox/e679464f35dc2a78920e6249a21d7958/raw/c5541e38979dca1e3e1e9704ad171ed2f0556fa1/ubunut-install-docker.sh | bash
没错,就是我
这个脚本会安装 docker 并开启 docker swarm
curl -o- -L https://gist.githubusercontent.com/hangox/e679464f35dc2a78920e6249a21d7958/raw/c5541e38979dca1e3e1e9704ad171ed2f0556fa1/ubunut-install-docker.sh | bash
今年年初,我把我电脑从 i5-7400 升级到 i9-9900K,也就是从 4 核心 4 线程最高 3.6 主频的 U 升级到 8 核心 16 线程最高主频 5.0 主频的U。
我把 i9 超频到全核心 5.0G
在工作中也用了一个多月了,说说我在使用的过程中感受到的提升吧,我其实经常进行 App 的打包去验证问题,我就以这个场景说明一下问题
运行命令
/gradlew clean
/gradlew :cc-start:assembleDebug --no-build-cache
新电脑用时
旧电脑用时
差了 42秒,别看这 42秒不重要,有时候验证一个问题,都是需要清洁构建,我曾经试过验证一个问题一天需要构建十几次,能省下不少时间。同时,因为打包并不能把新U所有的性能压榨出来,这个时候我是可以做别的工作的,但是旧的U是已经完全卡死了
接着我运行了更吃 CPU 的打包场景
在部分华为手机上启动,启动图会变成如下模样
而我们正常的启动图是这个模样
有意思的地方在于,这个包对应的提交,我们同时打了一个包名不一样的包,用于mtl测试,但是那个包完全没问题。
在调用 getLifecycle().addObserver()
的时候报出这样的错误
java.lang.IllegalArgumentException
at androidx.lifecycle.LifecycleRegistry.upEvent(SourceFile:279)
at androidx.lifecycle.LifecycleRegistry.forwardPass(SourceFile:293)
at androidx.lifecycle.LifecycleRegistry.sync(SourceFile:333)
at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:189)
访问链接 https://host/help
因为我的技术栈扩展的原因,导致我原本的 i5-7500
的台式机越来越不够用,决定攒一台速度比较快的黑苹果。
这篇文章主要是说了我在组这台电脑上的硬件和软件上的经验,希望可以帮到大家,毕竟也是很多前辈的文章才让我知道怎么做的。
放个图先
主要开始支持 Jetpack Compose
Jetpack Compose工具包提供了一种构建应用程序UI的现代化方法。该工具包还带来了Kotlin的所有优势,例如帮助您编写与Java完全可互操作的简洁且惯用的代码。
为了获得使用Jetpack Compose
进行开发的最佳体验,您应该使用最新版本的Android Studio 4.1。这是因为当您使用Android Studio通过Jetpack Compose开发应用程序时,您可以受益于智能编辑器功能,例如 New Project 模板和立即预览 Compose UI 的功能。
要了解更多信息并开始使用,请转到Jetpack Compose概述。
现在,在部署应用程序的调试版本时,将启用Java代码中的断言。由于Android运行时不支持在运行时启用断言(即,将等效的-ea
/ -enableassertions
标志传递给Java VM),因此应用程序中的断言以前没有任何作用。
现在,当您使用Android Gradle插件4.1.0-alpha01
及更高版本构建和部署应用程序的调试版本时,内置编译器(D8)会重写代码以在编译时启用断言,因此您始终使断言检查处于活动状态。
注意:此功能目前仅支持以Java编程语言编写的应用程序。对Kotlin的支持即将推出。
本部分介绍了Android Studio 4.1 Preview中的当前已知问题。
当您选择示例Java方法或跟踪Java方法 配置时,您可能会在Android Studio CPU Profiler中遇到“无法停止录制”错误。这些通常是超时错误,尤其是在idea.log
文件中看到以下错误消息时:
Wait for ART trace file timed out
与采样方法相比,超时错误对跟踪方法的影响更大,而对较短记录的影响则更长。作为临时的解决方法,尝试较短的记录以查看错误是否消失可能会有所帮助。
如果您在Profiler中遇到超时问题,请提交一个错误 ,其中包括设备的型号/型号以及来自idea.log
和logcat
的所有相关条目 。
Android Studio 4.1 Canary 1 的 Git 认证身份功能不能工作,任何需要认证的操作都不能进行,比如 push/pull,并将在以后的版本中修复。
解决方法是从命令行使用Git。
原文在这里
本部分简要介绍了 Android Studio 4.0 中的新功能和变更。
几乎所有内容都是来自于 android 4.0 feature 我只是做了部分更改
根据您的反馈,CPU Profiler 界面经过了全新改版,以提供更直观的工作流。显著变更包括:
此功能仍在开发中,因此请继续提供反馈。
已移除将注释处理进程分离到一项专门任务中的功能。此选项过去用于在纯 Java 项目中使用非增量注释处理器时维持增量 Java 编译;过去的启用方法是在 gradle.properties
文件中将 android.enableSeparateAnnotationProcessing
设为 true
,但这种方法不再起作用。
您应改为使用增量注释处理器来提升构建性能。
将 Android Studio 4.0 Canary 3 与 Android Gradle 插件 4.0.0-alpha03
及更高版本一起使用时,Build Speed 窗口可帮助您了解和诊断与构建流程有关的问题,如优化被停用和任务配置不当问题。将 Android Studio 4.0 Canary 3 及更高版本与 Android Gradle 插件 4.0.0-alpha03
及更高版本一起使用时,您可以按如下方式打开 Build Speed 窗口:
Build Speed 窗口将可能的构建问题组织在左侧的树中。您可以检查并点击每个问题,以在右侧的面板中调查其详细信息。当 Android Studio 分析您的构建时,它会计算决定构建时长的一组任务,并提供直观的图表来帮助您了解其中每项任务所产生的影响。您也可以展开 Warnings 节点来获取有关警告的详细信息。
Gradle 按任务的相互依赖性、项目结构和 CPU 负载来决定任务的执行,并按顺序或并行执行任务。对于给定的构建,Build Speed 窗口会突出显示决定当前构建时长的一组按顺序执行的任务。要缩短总体构建时间,最好首先解决这些突出显示的任务执行效率低下的问题。
请注意,对于您执行的每次构建,您可能会看到一组不同的任务决定了构建时长。例如,如果您对构建配置进行更改、通过一组不同的任务运行构建(如增量构建)或在不同的约束条件(如较重的 CPU 负载)下运行构建,则“Build Speed”窗口可能会突出显示对该构建的时长影响最大的一组不同的任务。由于这种变化,您可能希望在多次构建之间使用“Build Speed”窗口来不断缩短构建时长。
Multi Preview 是一款可视化工具,用于同时预览不同设备中及采用不同配置的布局,这样可帮助找出布局中的潜在问题。
您可以通过点击 IDE 窗口右上角的 Multi Preview 标签页来使用该功能:
有两个不同的配置集可供您选择,即“Pixel Devices”和“Project Locales”。要在这些配置集之间切换,请从“Multi Preview”窗口顶部的下拉列表中选择:
您可以使用更新后的实时布局检查器来调试布局,该工具可以在将应用部署到设备时提供应用界面的完整实时数据分析。
要打开一个布局检查器窗口,请依次转到 View > Tools Windows > Layout Inspector。除了与现有布局检查器相同的许多功能之外,实时布局检查器还包含如下功能:
只有在将您的应用部署到搭载 API 级别 29 或更高级别的设备上时,才能使用实时布局检查器。您还必须启用该功能,方法是依次转到 File > Settings > Experimental 并勾选 Enable Live Layout Inspector 旁边的框。
Jetpack Compose 工具包提供了一种用于构建应用界面的现代方法。此外,该工具包还融合了 Kotlin 的所有优势,如帮助您编写可完全与 Java 互操作的简洁而惯用的代码。
为了获得最佳 Jetpack Compose 开发体验,您应使用最新版本的 Android Studio 4.0。这是因为,当您搭配使用 Android Studio 和 Jetpack Compose 来开发应用时,可以从智能编辑器功能中受益,这些功能包括“新建项目”模板和立即预览 Compose 界面等。
要了解详情并开始使用,请转到 Jetpack Compose 概览。
Android Studio 现在支持使用多种 Java 8 语言 API,而无需为应用设置最低 API 级别。
通过一个称为“脱糖”的过程,Android Studio 3.0 及更高版本中的 DEX 编译器 D8 已经为 Java 8 语言功能(如 lambda 表达式、默认接口方法、try-with-resources 等等)提供了大量的支持。在 Android Studio 4.0 中,脱糖引擎经过扩展,能够使 Java 语言 API 脱糖。这意味着,您现在可以在支持旧版 Android 的应用中添加过去仅在最新 Android 版本中可用的标准语言 API(如 java.util.streams
)。
此版本支持下面一组 API:
java.util.stream
)java.time
的子集java.util.function
java.util.{Map,Collection,Comparator}
的最近新增内容java.util.Optional, java.util.OptionalInt
和 java.util.OptionalDouble
)以及对上述 API 很有用的一些其他新类java.util.concurrent.atomic
的一些新增内容(AtomicInteger
、AtomicLong
和 AtomicReference
的新方法)ConcurrentHashMap
(包含 Android 5.0 的问题修复)为了支持这些语言 API,D8 编译了一个单独的库 DEX 文件,其中包含缺失 API 的实现,并将其添加到您的应用中。脱糖过程会重新编写应用的代码,以便在运行时改用此库。
要启用对这些语言 API 的支持,请在模块的 build.gradle
文件中添加以下内容:
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4'
}
如果您遇到问题或希望支持其他 API,请告知我们,只需在我们的错误跟踪器中提交错误即可。
Android Gradle 插件现在支持 Kotlin DSL 构建脚本文件 (*.kts
)。与 Android Studio 一起使用时,某些 IDE 功能(如“Project Structure”对话框和构建脚本快速修复)现在也支持读取和写入 Kotlin 构建脚本文件。
Android Studio 现在可以在您打开 ProGuard 规则文件时提供智能编辑器功能,如语法突出显示、代码补全和错误检查。该编辑器还与 Android Studio 项目集成,以便为所有类、方法和字段提供完整的符号补全,并且包括快速导航和重构功能。
Android Studio 现在包含一个适用于 MotionLayout 布局类型的视觉设计编辑器,可让您更轻松地创建和预览动画。
Motion Editor 提供了一个简单的界面来操控 MotionLayout 库中的元素,该库是 Android 应用中动画的基础。在之前的版本中,创建和更改这些元素需要手动修改 XML 资源文件中的约束。现在,Motion Editor 支持开始状态和结束状态、关键帧、转换和时间轴,可以为您生成此 XML 文件。
注意:在使用 Motion Editor 之前,请务必在 build.gradle
文件中将 ConstraintLayout
依赖项设为版本 2.0.0-beta3
,如 MotionLayout 参考文档中所述。
要开始使用 Motion Editor,请执行以下操作:
Android Studio 将 ConstraintLayout 转换为 MotionLayout 后,也会将一个 Motion Scene 文件添加到包含您的 XML 文件的目录中。
MotionLayout
随后成为您的根布局,并且它会出现在 Motion Editor 界面中。布局已包含开始 ConstraintSet
、结束 ConstraintSet
以及从开始到结束的转换。
您可以使用概览图来选择 ConstraintSet
或 Transition
并在选择面板中选择组件。
然后,您可以修改开始或结束 ConstraintSet
的约束和属性,修改方式与修改 ConstraintLayout
一样。
如果您要在图中构建更多元素,可以使用创建图标来快速添加 ConstraintSet
、Transition
或 OnClick
/OnSwipe
手势。
要添加关键帧,请先点击 Transition 箭头:
然后,在 Transition 时间轴窗格中,点击右上角并选择 KeyPosition:
此操作会打开一个对话框,您可以从中设置关键帧的属性。
您还可以在属性面板中向转换添加 OnClick
和 OnSwipe
处理程序。
此操作会打开一个对话框,您可以从中设置点击操作的属性,如目标组件和拖动方向。
Motion Editor 支持在设计图面上预览动画。选择动画后,点击时间轴上方的 Play 图标 即可预览动画。
本部分介绍了 Android Gradle 插件 4.0.0 中包含的新功能和行为变化。
Android Gradle 插件 4.0.0-alpha05 引入了一种新方法来控制您要启用和停用的构建功能,如视图绑定、数据绑定和 Jetpack Compose。添加新功能后,默认情况下,这些功能处于停用状态。您随后可以使用 buildFeatures
块来仅启用所需的功能,它可以帮助您优化项目的构建性能。您可以在模块级 build.gradle
文件中为每个模块设置相应的选项,如下所示:
android {
// The default value for each feature is shown below. You can change the value to
// override the default behavior.
buildFeatures {
// Determines whether to generate a BuildConfig class.
buildConfig = true
// Determines whether to support View Binding.
// Note that the viewBinding.enabled property is now deprecated.
viewBinding = false
// Determines whether to support Data Binding.
// Note that the dataBinding.enabled property is now deprecated.
dataBinding = false
// Determines whether to generate binder classes for your AIDL files.
aidl = true
// Determines whether to support RenderScript.
renderScript = true
// Determines whether to support injecting custom variables into the module's R class.
resValues = true
// Determines whether to support shader AOT compilation.
shaders = true
}
}
您还可以为项目中的所有模块指定这些功能的默认设置,方法是在项目的 gradle.properties
文件中添加下面的一项或多项,如下所示。请注意,您仍然可以使用模块级 build.gradle
文件中的 buildFeatures
块来替换这些项目范围的默认设置。
android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=true
在以前的 Android Gradle 插件版本中,所有动态功能模块都只能依赖于应用的基础模块。使用 Android Gradle 插件 4.0.0 时,您现在可以添加依赖于其他功能模块的功能模块。也就是说,:video
功能可以依赖于 :camera
功能,后者依赖于基础模块,如下图所示。
:video
动态功能依赖于 :camera
功能,后者依赖于 :app
基础模块。
这意味着,当您的应用请求下载某个动态功能模块时,它也会下载该模块所依赖的其他功能模块。为您的应用创建动态功能模块后,您可以在模块的 build.gradle
文件中声明功能对功能的依赖性。例如,:video
模块声明对 :camera
的依赖性,如下所示:
// In the build.gradle file of the ':video' module.
dependencies {
// All dynamic feature modules must declare a dependency
// on the base module.
implementation project(':app')
// Declares that this module also depends on the 'camera'
// dynamic feature module.
implementation project(':camera')
...
}
此外,您还应在 Android Studio 中启用功能对功能的依赖性功能(例如,为了在修改运行配置时支持该功能),方法是从菜单栏中依次点击 Help > Edit Custom VM Options,并添加以下内容:
-Drundebug.feature.on.feature=true
Android Gradle 插件 3.6.0 弃用了功能插件 (com.android.feature
) 和免安装应用插件 (com.android.instantapp
),改为使用动态功能插件 (com.android.dynamic-feature
),以通过 Android App Bundle 构建和打包免安装应用。
在 Android Gradle 插件 4.0.0-alpha01 及更高版本中,完全移除了这些已弃用的插件。因此,要使用最新的 Android Gradle 插件,您需要迁移免安装应用以支持 Android App Bundle。通过迁移免安装应用,您可以利用 app bundle 的优势,并简化应用的模块化设计。
注意:要打开使用 Android Studio 4.0 中已移除的插件的项目,项目必须使用 Android Gradle 插件 3.6.0 或更低版本。
Android Studio 现在包含适用于 Kotlin 类的 Android 实时模板。例如,您现在可以输入 toast
并按 Tab 键来快速插入一个消息框。如需查看可用实时模板的完整列表,请从菜单栏中依次点击 File > Settings(或在 macOS 上,依次点击 Android Studio > Preferences),然后依次转到 Editor > Live Templates。
现在,当您依次转到 File > New > Fragment > Gallery 或在 Navigation Editor 中点击 Create new destination 时,会出现新的 Android Fragment 向导和新的 Fragment 模板。
Fragment 库向导。
本部分介绍了 Android Studio 4.0 预览版的当前已知问题。
如果您对操作按钮的 Run/Debug 组进行了自定义(例如,通过在 Settings 或 Preferences 窗口中的 Appearance & Behavior > Menus and Toolbars 下修改选项),那么在您重启 IDE 后,这些操作按钮可能会从工具栏中消失。这是 Android Studio 4.0 所基于的 IntelliJ 版本的已知问题(请参阅问题 IDEA-228450)。
要解决此问题,请还原您对这些按钮所做的任何自定义,具体操作步骤如下:
Android Studio 4.0 Canary 5 没有可用于之前发布的 Android Studio 4.0 Canary 版本的补丁程序。要安装 Android Studio 4.0 Canary 5,请从 Android Studio 下载页面进行下载。
从 Android Studio 4.0 Canary 5 开始,实时布局检查器和分析器无法在 Windows 上正常运行,从而导致出现以下错误消息:
transfer error: couldn't create file: Read-only file system.
要解决此问题,请升级到 Android Studio 4.0 Canary 7 或更高版本。
如果您使用的是 Android Studio 4.0 Canary 4 或更低版本,则可能会看到以下错误消息:
Application build has failed with an error (Could not find org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.60-eap-25)
要解决此问题,请更新到 Android Studio 4.0 Canary 5 或更高版本。
因为我的技术栈扩展的原因,导致我原本的 i5-7500
的台式机越来越不够用,决定攒一台速度比较快的黑苹果。
这篇文章主要是说了我在组这台电脑上的硬件和软件上的经验,希望可以帮到大家,毕竟也是很多前辈的文章才让我知道怎么做的。
放个图先
这是因为在 Kotlin
中,Field
生成的 Java
代码都是都是带 get
和 set
的,然后 Field
是要设置为 private
的,下面就是生成的代码
@Nullable
@Inject
private volatile DispatchingAndroidInjector androidInjector;
@Nullable
public final DispatchingAndroidInjector getAndroidInjector() {
return this.androidInjector;
}
public final void setAndroidInjector(@Nullable DispatchingAndroidInjector var1) {
this.androidInjector = var1;
}
这种情况我们有两种方法解决
增加 JvmField
@Inject
@JvmField
var androidInjector: DispatchingAndroidInjector<Any?>? = null
这样生成的代码就会变成
@Inject
@JvmField
@Nullable
public volatile DispatchingAndroidInjector androidInjector;
这样就完全没有问题了,但是这样会把属性暴露出去,不是很好。因为kotlin是没有包内属性的,你也改不了为包内属性。
set
方法为 Inject
以为 dagger
是支持注入方法的,直接标记属性的 setter 方法也能解决这问题,代码如下
@Volatile
@set:Inject
var androidInjector: DispatchingAndroidInjector<Any?>? = null
对应的 Java代码就会变成这样
@Nullable
private DispatchingAndroidInjector androidInjector;
@Nullable
public final DispatchingAndroidInjector getAndroidInjector() {
return this.androidInjector;
}
@Inject
public final void setAndroidInjector(@Nullable DispatchingAndroidInjector var1) {
this.androidInjector = var1;
}
这是一个比较好的实现,不会影响原有的访问域,代码编写也比较方便
这里有个小问题
如果你在 Android Studio 3.5到 3.6 编译这个代码,会报下面这个错误
An exception occurred: java.lang.IllegalArgumentException: not a > valid name:
Provider
但是,用命令行编译是没有问题的,所以我把 Android Studio 升级到 4.0,重新编译之后就没有这个问题。
上面没用,乖乖用 lateinit var
啥事都没有
R2
,R2
点击不能跳转到具体的布局,对于问题定位有很大的干扰条目 | ViewBinding | DataBinding |
---|---|---|
定位 | 代替 findViewById | 作为数据到界面显示的桥梁 |
是否需要更改布局 | 不需要 | 需要在最外围加上<layout> (可以自动生成) |
能否进行数据绑定 | 不能 | 可以 |
能否和LiveData ,ViewModel ,LifeCycle 联动 |
不能 | 可以 |
都是在 gradle 配置开关
ViewBinding
android{
viewBinding {
enabled = true
}
}
DataBinding
android{
dataBinding {
enabled = true
}
}
都是拿到 binding 对象,然后通过 binding
对象对 View
进行操作
private lateinit var binding: ResultProfileBinding
@Override
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
setContentView(binding.root)
}
可以直接看成 ViewBinding 是 DataBinding 的子集
ViewBinding
不需要对 xml 进行更改DataBinding
需要在 xml 最外层 加上 <layout>
这个根LiveData
和 ViewModel
进行联动(生命周期监听)View
的 XML 属性onClick
,onLongClick
这些 如果要把一个类的大部分方法移动到一个新的类上,比如把 A
类的方法大部分移动到一个新的 B
类上,建议是把 A
重命名为 B
,然后把需要剩下的方法放在新建的 A
类上。目的是让大部分的方法追踪到 A
中,这样当 A
上有别人的修改,就能直接同步过去,不会造成特别大的冲突。
需要注意,新建的
A
不能被 Git 识别为旧的A
,不然是会被追踪过去的。因为 Git 采用的是内容推断是否移动,如果你有比较大的修改,大概率不会被推断成旧的A
new File(sourceZipPath).eachFile() { file ->
println "开始处理文件 ${file.name}"
if (file.isFile()) {
if (file.name.endsWith(".apk")) {
// 为 apk 生成注释文件
def fileSize = String.format("%.2f", file.size() / 1024 / 1024)
comment.append("文件: ${file.name}\n")
.append("大小: ${fileSize} MB\n")
.append("MD5: ${file.getBytes().md5()}\n")
.append("\n")
}
zipFile.putNextEntry(new ZipEntry(file.name))
zipFile.write(file.getBytes())
zipFile.closeEntry()
}
}
println "注释信息为:\n $comment"
zipFile.comment = comment
zipFile.close()
因为只有 iOS 13
才开始支持键盘的浮动模式。如果不开启浮动模式的话,其实也可以,前提你能忍,就是会像下图那样占用半个屏幕
这样其实也有一个问题,就是容易误触。
开启方法很简单,看到大键盘,两个手指捏一下即可
然后我们就可以用笔愉快的玩耍了
讯飞,百度,搜狗都对比过,输入体验最好的还是苹 原生体验最好,不信可以自己体验一下。
ipad是支持120帧率的,这个东西就是为了让你在用笔输入的时候准备的,这样你就看不到笔输入带来的延时,但是也因为使用了高帧率所以用电也增加了很多
手写是没有笔输入快的,这点是肯定的。
下面的图上半部分是不是用 worker,下半部分使用 worker,因为并行的原因,使用 worker 之后明显快很多
但是显示总是残酷的,因为并不是所有的 task 都开启了 worker
,比如下面的 task c 就是没有开启 worker 的最后,task b 只能等待 task c 完成
使用 Closure
的时候因为不知道deleage 的对象是谁,所以没办法出现代码提示。在方法中可以这样写
static void compose(@DelegatesTo(DepAssemble.class) Closure closure) {
def depAssemble = new DepAssemble(closure.owner)
closure.delegate = depAssemble
closure()
}
加上 @DelegatesTo(DepAssemble.class)
即可,这样编辑器就知道怎么改 Dep 了
Google 出了一个 DiffUtils 用于分发 Adapter 修改数据,很好用,但是有个问题,如果你的数据是来自网络的没问题,因为每次通过 Gson 来解析都是一个新的对象,对象是不一样的。因此是用 Diff 是没问题的。如果对象来自自己构建,当 UI 中修改的时候一般都是直接修改对象,当进行 Diff 的时候这个对象已经被修改了,没法进行比较。
这里有个办法来对付这种情况,Adapter 缓存的是 Vm 的 toString 对象,通过比较 toString 是否一样即可,这样就能直接对比分发。当然 HashCode 也是可以
(02:23) 上下文菜单增加快速让 COntrainsLayout 中组件居中的菜单,其实就是以前你要拉两条线,现在点一下菜单就帮你把这两条线拉好了,总比没有好
item
的布局SimpleData
功能,自带几种图片集合,可以直接设置到 ImageView 预览上视频地址 https://www.youtube.com/watch?v=8rfvfojtRss&t=1686s
Google Play Service 在后台频繁运行导致的消耗(也是说,如果你选的 AVD 是没有 Google Play Service 的没有这个问题),其实这个是和手机的策略有关系的。默认情况下,在充电状态,后台运行的服务会更活跃,所以 Google Play Service 会消耗更多的 CPU 资源,如果改为非充电模式,后台就会消耗非常少的资源,它的修复方案也是这样,默认是非充电模式
带 Google 服务的 AVD 默认会在后台监听 OK Google
用于做唤醒,这个原本是由协处理器做的,模拟器上没有,所以非常消耗性能。因为大部分的人其实不需要麦克风功能,所以更改为麦克风默认关闭,修复了这个问题
(36:42) 增加杀毒软件检测,如果有杀毒软件频繁扫描 build 生成的文件,将会弹框提醒(杀毒软件的确是编译克星)
1.用 root 权限创建两个文件,也就是先执行 sudo su root
,分别为
/Library/LaunchDaemons/limit.maxfiles.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxfiles</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxfiles</string>
<string>200000</string>
<string>200000</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
/Library/LaunchDaemons/limit.maxproc.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxproc</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxproc</string>
<string>2048</string>
<string>2048</string>
</array>
<key>RunAtLoad</key>
<true />
<key>ServiceIPC</key>
<false />
</dict>
</plist>
2.加载两个配置文件
// 先卸载掉
sudo launchctl unload -w /Library/LaunchDaemons/limit.maxfiles.plist
sudo launchctl unload -w /Library/LaunchDaemons/limit.maxproc.plist
// 然后才能加载
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxproc.plist
#!/bin/sh
# These are the original gist links, linking to my gists now.
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxfiles.plist
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxproc.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxfiles.plist
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxproc.plist
sudo mv limit.maxfiles.plist /Library/LaunchDaemons
sudo mv limit.maxproc.plist /Library/LaunchDaemons
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
sudo chown root:wheel /Library/LaunchDaemons/limit.maxproc.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxproc.plist
https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c
Is there a fix for the “Too many open files in system” error on OS X 10.7.1?
更多内容参考这个极客学院教程写得很不错
如果需要改变 grape
用来下载库的目录,可以指定 grape.root
系统属性来改变默认配置(~/.groovy/grape)
。
groovy -Dgrape.root=/repo/grape yourscript.groovy
如果想查看 Grape 的工作内容,可以将 groovy.grape.report.downloads
设为 true
(比如将 -Dgroovy.grape.report.downloads=true
添加到 JAVA_OPTS 环境变量中),Grape 就能将下列信息打印在 System.error 中:
之前为了统一使用参数,都是直接弄一个 export GROOVY="groovy -Dgrape.root=${GLOBAL_CACHE_DIR}/grapes"
然后通过 $GROOVY
执行 groovy 脚本,不是很灵活。
现在可以通过 export JAVA_OPTS="-Dgroovy.grape.report.downloads=true -Dgrape.root=/Volumes/macOSE/hangox/Downloads/test/grapes"
来全局自定参数,运行的时候就能直接使用脚本运行,不需要自定义 Groovy 命令
直接使用 CliBuiler
def cli = new CliBuilder(usage: "运行脚本检查 dev 和 master 有没有同步")
cli.with {
pid longOpt: 'projectId', required: true, '需要 projectId ', type: String.class
pt longOpt: 'privateToken', required: true, '可以访问 gitlab api 的 token', type: String.class
}
def opt = cli.parse(args)
String projectId = opt.pid
String privateToken = opt.pt
nps 是一款轻量级、功能强大的内网穿透代理服务器。支持tcp、udp流量转发,支持内网http代理、内网socks5代理,同时支持snappy压缩、站点保护、加密传输、多路复用、header修改等。支持web图形化管理,集成多用户模式。
因为使用的是 docker 配置,nps 没有配置文件的情况下启动会崩溃,如果每次都复写配置文件,有些文件又是运行之后生成的,不能覆盖,只能写个脚本在启动的时候判断是否复制配置文件,脚本如下
#!/usr/bin/env bash
if test -e '/app/nps/conf/clients.json'
then
cp -r conf-temp/nps.conf conf
echo '覆盖配置'
else
cp -r conf-temp/. conf
echo '拷贝所有文件'
fi
ls /app/nps/conf/
./nps
有些非常老旧的项目构建方式不支持 maven,也就是没办法自动解决依赖 ,这个时候只能把所有相关的 Jar
和 aar
都下载给对方。
AAR
发布到 Mavan
仓库上WAR
打包插件,运行 WAR 作业,打包完成对于很多东西,开发时间不能确定,开发的时候又头疼的根本原因是对本质不了解。如果我对很多东西的本质好像对我对 Git 那么了解的话,那就当我操作的时候一点都不害怕,估计还有点小激动。
接下来的工作应该要对 Android 整个底层和 AndroidBuildTools 整个整个底层都走一遍
C与C++
Reative Native
对应Java
对应 Flutter
in
标明这个类是这个泛型的消费者,只进不出, 相当于 Java 的 ? super E
out
是什么out
标明这个类是这个泛型的生产者,只出不进,相当于 Java 的 ? extends E