技术小黑屋

传音 Android 职位内推

如果你对如下职位感兴趣,请发送简历到我的邮箱 andrewallanwallace#gmail.com ,备注 技术小黑屋内推

基础信息

  • 工作地点:上海
  • 工作时间:965

iTerm2 设置无限向上滚动

在查看日志分析问题时,有时候无法回滚到更上面的日志内容,让人很是感到麻烦,其实这是iTerm2 做的限制,按照下图操作,即可设置无限回滚。

https://asset.droidyue.com/image/2021/05/unlimited_scroll_iterm2.png

Could Not Find org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0-release-764 问题解决

最近新创建的 Android Studio 项目,都报这样的问题。

问题日志

1
2
3
4
5
6
7
8
9
10
11
A problem occurred configuring root project 'TooLargeToolSample'.
> Could not resolve all artifacts for configuration ':classpath'.
   > Could not find org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0-release-764.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.5.0-release-764/kotlin-gradle-plugin-1.5.0-release-764.pom
       - https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.5.0-release-764/kotlin-gradle-plugin-1.5.0-release-764.pom
     Required by:
         project :

Possible solution:
 - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html

Coobox之 LastWinExecutor,后来居上执行器

在编程的业务场景中,有时候会有这样的情况。有一个文本输入框用来输入检索数据

  • 为了避免过多的网络检索,实现频率控制
  • 当且仅当距离上次输入字符500 毫秒后,才真正执行检索请求

国产远程控制软件 ToDesk 来了,特惠价 108 元起

无论是远程办公、机房维护,还是为朋友提供远程协助服务,一个好用的远程控制软件必不可少。

提到桌面远程控制软件,大家通常会想到国外的 TeamViewer。但它奇怪的判定方式和高昂的价格被诟病已久,由国人开发的 ToDesk 远程控制软件,或许更适合大家。

ToDesk 拥有国内海量 G 口宽带服务器加速,远程访问更稳定更流畅。软件功能也很齐全,不输 Teamviewer。上架数码荔枝价格更优惠,仅需 108 元起,新注册用户再享立减 5 元优惠,只需 103 元起。

CooBox 之 早鸟执行器,轻松控制频率处理

在处理编程场景时,我们有时候需要控制某些频率。比如一个用户疯狂地点击一个按钮,我们想要这样处理。

  • 在5秒之内,只处理第一个点击请求的内容

使用 CooBox 中的 EarlyBirdExecutor(早鸟执行器,早起的鸟儿有虫吃。^_^) 我们可以很便捷的实现该功能。

Coobox 之 App 前后台状态变化通知

前言:Coobox 是我们团队开源的 Android 开发工具库,https://github.com/secoo-android/coobox 欢迎大家 Star 和 Fork,以及集成使用。

在 Android 应用日常开发中,我们有时候需要判断应用处于前台还是后台,来进行一些状态更新或者资源处理等操作。而 Android 并未直接提供对应的检测方法,需要我们来实现。而实用的 CooBox 就集成了这一方面的工具代码。

Git 处理文件与 Revison 冲突问题

有一次,尝试使用git log 来查看某个分支(build.gradle)的历史提交时,遇到了这样的问题

1
2
3
4
git log build.gradle
fatal: ambiguous argument 'build.gradle': both revision and filename
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Android 抓取 ANR 日志终极办法

在 Android 开发中,有时会遇到 ANR,一旦出现 ANR 我们就需要拿到对应的trace 文件来分析并解决。本文将介绍两种获取 ANR 的方法。

第一种

直接查看/data/anr/traces.txt的内容,如下

1
adb shell cat  /data/anr/traces.txt

或者类似使用拷贝到电脑上查看,比如

1
2
adb shell cp /data/anr/traces.txt /sdcard
adb pull /sdcard/traces.txt ./

但是这种方法在某些手机上由于权限原因,无法进行,就需要了使用下面的方法了。

新版赤友 NTFS 助手来袭,速度优化仅需 20 元起

去年,一款 Mac 读写 NTFS 移动硬盘 / U 盘的国产工具:赤友 NTFS 助手,在 Mac 用户中流行起来。它凭借极高的性价比、易用的操作,获得了众多用户的青睐。

现在它迎来 3.0 版本的更新,带来了功能优化提升。售价还十分亲民,连同类产品的零头都不到。2020 年 5 月 19 日后购买赤友 NTFS 助手 2.0 的用户还可免费升级至 3.0 版,相当良心!

https://asset.droidyue.com/image/lizhi_io/ntfs/pic_1.png

3月特惠,Microsoft 365 一年仅需 89 元

去年四月 Office 365 升级为 Microsoft 365,云服务的普及让它逐渐成为主流,并带来了更多用户权益:

https://asset.droidyue.com/image/lizhi_io/office_365_21_03/image_1.png

始终获取最新功能、自带 1TB OneDrive 空间、还有各种模版以及 AI 辅助工具,每项功能都让办公操作变得轻松简单!

10年程序员都不一定搞清楚的文件路径

在 Java 中,文件是很常用的概念,这其中文件路径是一个很基础的内容,因为文件的创建,读取,写入和删除等操作都是依赖于文件路径的。但是你仔细看一下Java中 File的 API 你会发现有这样三个方法返回路径。

  • getPath(获取路径)
  • getAbsolutePath(获取绝对路径)
  • getCanonicalPath(获取规范路径)

URL中的 # 原来是这个意思

URL 是我们进行网络活动中很重要的概念,一个URL中可以包含域名,路径和参数等,

一个典型的 URL

1
https://www.example.com/fruits.html?from=google#apple

如何自定义一个 Gradle 任务

很多的项目是基于 gradle 构建,而且依托 gradle 的强大能力,我们可以实现更多的功能。比如像今天这样,我们会介绍如何创建一个自定义的 gradle 任务。

修改文件

  • (Android 项目)app 模块下的 build.gradle 为例

修复WebView资源未找到导致的崩溃问题

近期 应用新增了很多的崩溃,分析特征,发现崩溃集中在5.0-5.1.1系统上,崩溃的日志如下

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
50
51
52
53
54
55
56
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x2040003
at android.content.res.Resources.getText(Resources.java:318)
at android.content.res.VivoResources.getText(VivoResources.java:123)
at android.content.res.Resources.getString(Resources.java:404)
at com.android.org.chromium.content.browser.ContentViewCore.setContainerView(ContentViewCore.java:694)
at com.android.org.chromium.content.browser.ContentViewCore.initialize(ContentViewCore.java:618)
at com.android.org.chromium.android_webview.AwContents.createAndInitializeContentViewCore(AwContents.java:631)
at com.android.org.chromium.android_webview.AwContents.setNewAwContents(AwContents.java:780)
at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:619)
at com.android.org.chromium.android_webview.AwContents.<init>(AwContents.java:556)
at com.android.webview.chromium.WebViewChromium.initForReal(WebViewChromium.java:312)
at com.android.webview.chromium.WebViewChromium.access$100(WebViewChromium.java:96)
at com.android.webview.chromium.WebViewChromium$1.run(WebViewChromium.java:264)
at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.drainQueue(WebViewChromium.java:123)
at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue$1.run(WebViewChromium.java:110)
at com.android.org.chromium.base.ThreadUtils.runOnUiThread(ThreadUtils.java:144)
at com.android.webview.chromium.WebViewChromium$WebViewChromiumRunQueue.addTask(WebViewChromium.java:107)
at com.android.webview.chromium.WebViewChromium.init(WebViewChromium.java:261)
at android.webkit.WebView.<init>(WebView.java:554)
at android.webkit.WebView.<init>(WebView.java:489)
at android.webkit.WebView.<init>(WebView.java:472)
at android.webkit.WebView.<init>(WebView.java:459)
at com.tencent.smtt.sdk.WebView$a.<init>(WebView.java:2968)
at com.tencent.smtt.sdk.WebView.<init>(WebView.java:567)
at com.tencent.smtt.sdk.WebView.<init>(WebView.java:329)
at com.tencent.smtt.sdk.WebView.<init>(WebView.java:323)
at com.tencent.smtt.sdk.WebView.<init>(WebView.java:318)
at com.tencent.smtt.sdk.WebView.<init>(WebView.java:313)
at com.xxxx.webview.X5WebView.<init>(X5WebView.java:36)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1245)
at android.app.Activity.performStart(Activity.java:6099)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2367)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2466)
at android.app.ActivityThread.access$900(ActivityThread.java:175)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5418)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1037)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

终端下双重过滤筛选内容

很多时候,我们需要对文件内容进行查找,查找出包含某段字符串的文件,比如这样

我们使用这个命令可以查找包含Ruby字符的全部文件和行数。

1
2
3
4
5
6
7
8
source git:(master) grep  -E "Ruby" --exclude-dir={.git,lib,.gradle,.idea,build,captures}   . -R --color=always -n
./_posts/2014-09-08-learn-sqlite-in-a-very-fast-way.markdown:9:最近用Ruby写了一个七牛的demo参赛作品,使用了sqlite3,用到很多操作,利用假期的时间,简单做一个快速掌握SQLite命令的小入门。
./_posts/2013-09-07-issues-about-installing-octopress.markdown:6:categories: Github OctoPress Ruby RVM
./_posts/2016-04-10-jit-friendly-checker-for-android.markdown:117:###为什么用Ruby
./_posts/2016-04-10-jit-friendly-checker-for-android.markdown:118:  * 答:有了idea时很纠结,因为不确定用什么语言实现,尤其是在Python和ruby之间,为此问了不少同学,最后“一意孤行”决定用Ruby了,不喜欢Python的强制对齐,超级喜欢Ruby的字符串模板。Ruby很简单,很人性化,相信你会喜欢的。
./_posts/2014-09-22-weekly-script-add-prefix-to-mutiple-files-in-ruby.markdown:6:categories: Ruby, 效率, 每周1脚本
./_posts/2014-08-21-file-code-sinppets-in-ruby.markdown:3:title: "Ruby常用文件操作"
./_posts/2014-08-21-file-code-sinppets-in-ruby.markdown:6:categories: Ruby

十个超级实用的git命令

git无疑已经成为了大家代码版本控制最多的工具了,这其中有不少人是使用终端来进行操作git。这里列出一些超级实用的git脚本,希望可以对大家开发有所帮助。

建议大家讲下面的脚本内容,都保存成脚本,然后设置执行权限,将所在目录加入环境变量,这样使用起来更加方便。

用好 Require,check,assert,写好 Kotlin 代码

在编码的时候,我们需要做很多的检测判断,比如某个变量是否为null,某个成员属性是否为true,执行某个操作结果是否成功。比如像下面的这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var isDiskMounted = true

fun createNewFile(file: File?): Boolean {
    return if (isDiskMounted) {
        if (file != null) {
            file.createNewFile()
            if (file.exists()) {
                true
            } else {
                println("Create file($file) failed")
                false
            }
        } else {
            println("File($file) is null")
            false
        }
    } else {
        println("Disk is not mounted")
        false
    }
}