技术小黑屋

使用 Flutter SDK 中的 Dart SDK

由于 Flutter 是基于 Dart 的UI开发框架,在 Flutter SDK 中是包含了 Dart SDK的。

一般 Dart 的sdk 的路径为 your_flutter_dir/bin/cache/dart-sdk 将上面的 your_flutter_dir 替换为本机真实的路径即可。

比如: /Users/xxx/Documents/bin/flutter/bin/cache/dart-sdk

Edge 浏览器 复制 URL 问题解决

微软的 edge 浏览器作为第二浏览器在使用,目前发现唯一不好的,就是复制链接的时候,内容不对。

我的预计是复制网址本身,而不是标题和网址等内容,想要实现这一需求,也很简单。

步骤:

Preferences –> Share, Copy and Paster –> URL copy & paste format default 选择 Plain Text 即可。

iTerm2 (Mac Terminal) 清空当前屏幕内容

对于经常使用终端的开发者,清空当前屏幕的内容,我们可以使用clear

clear 清空屏幕内容,大多数情况下会满足我们的需求,但是某些场景下还是会有一些问题。

  • 向上滑动,还是能够看到之前的终端内容。
  • 比如我们搜索当前屏幕中的字符,clear 之前的内容还是会被清理掉

Kotlin Kapt Error: Identifier Expected 问题记录

在工作中,小伙伴说他遇到了一个 kapt的问题,在使用 gradle 构建的时候出现了如下的错误。

1
2
3
4
5
6
7
Kapt worker classpath: []
/Users/androidyue/Documents/SecooComponentMaster/module-xxxx/build/tmp/kapt3/stubs/debug/com/xxxxx/xxxxx/util/PlayerCommandStateManager.java:7: error: <identifier> expected
    private static final java.util.Map<java.lang.String, com.xxxxxx.xxxxxxx.util.const.PlayerCommandState> recordMap = null;
                                                                                    ^/Users/androidyue/Documents/xxxxxxx/module-xxxxxx/build/tmp/kapt3/stubs/debug/com/xxxxx/xxxxxx/util/PlayerCommandStateManager.java:7: error: <identifier> expected
    private static final java.util.Map<java.lang.String, com.xxxxxx.xxxxxxxx.util.const.PlayerCommandState> recordMap = null;
                                                                                                            ^/Users/androidyue/Documents/xxxxxxx/module-xxxxxx/build/tmp/kapt3/stubs/debug/com/xxxxx/xxxxxxx/util/PlayerCommandStateManager.java:7: error: <identifier> expected
    private static final java.util.Map<java.lang.String, com.xxxxxx.xxxxxxx.util.const.PlayerCommandState> recordMap = null;

对应的实际代码为

1
2
3
object PlayerCommandStateManager {
    private val recordMap = mutableMapOf<String, PlayerCommandState>()
}
1
2
3
4
5
6
7
8
9
10
package com.secoo.gooddetails.util.const

enum class PlayerCommandState {
    PAUSE_BY_USER,
    PAUSE_NORMAL,
    PLAY,
    INITIAL,
    ENDED,
    IDLE
}

Gson NoClassDefFoundError 问题解决

最近升级了gson到 2.8.6(2.8.7),结果发生了崩溃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
E AndroidRuntime: FATAL EXCEPTION: PushConnectivityManager
E AndroidRuntime: Process: io.rong.push, PID: 11278
E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/gson/Gson;
E AndroidRuntime:  at io.rong.push.rongpush.RongPushCacheHelper.cacheRongPushIPs(RongPushCacheHelper.java:44)
E AndroidRuntime:  at io.rong.push.core.PushNaviClient.connect(PushNaviClient.java:152)
E AndroidRuntime:  at io.rong.push.core.PushNaviClient.connectToNavi(PushNaviClient.java:93)
E AndroidRuntime:  at io.rong.push.core.PushNaviClient.getPushServerIPs(PushNaviClient.java:85)
E AndroidRuntime:  at io.rong.push.rongpush.PushConnectivityManager.connectToNavi(PushConnectivityManager.java:398)
E AndroidRuntime:  at io.rong.push.rongpush.PushConnectivityManager.access$200(PushConnectivityManager.java:34)
E AndroidRuntime:  at io.rong.push.rongpush.PushConnectivityManager$DisconnectedState.processMessage(PushConnectivityManager.java:234)
E AndroidRuntime:  at io.rong.push.common.stateMachine.StateMachine$SmHandler.processMsg(StateMachine.java:966)
E AndroidRuntime:  at io.rong.push.common.stateMachine.StateMachine$SmHandler.handleMessage(StateMachine.java:789)
E AndroidRuntime:  at android.os.Handler.dispatchMessage(Handler.java:110)
E AndroidRuntime:  at android.os.Looper.loop(Looper.java:219)
E AndroidRuntime:  at android.os.HandlerThread.run(HandlerThread.java:67)
E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.gson.Gson" on path: DexPathList[[zip file "/data/app/com.xxxxx-GXNVWX-EHV4m1HU42XJIgw==/base.apk"],nativeLibraryDirectories=[/data/app/com.xxxxx-GXNVWX-EHV4m1HU42XJIgw==/lib/arm, /data/app/com.xxxxx-GXNVWX-EHV4m1HU42XJIgw==/base.apk!/lib/armeabi-v7a, /system/lib, /hw_product/lib]]
E AndroidRuntime:  at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:209)
E AndroidRuntime:  at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
E AndroidRuntime:  at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
E AndroidRuntime:  ... 12 more

如何在 Android Studio(北极狐) 下增加仓库声明

最近升级了 Android Studio,变成了 Arctic Fox 的版本了。于是当我们新建一个项目的时候,尝试添加一个新的仓库声明。

打开工程根目录下的 build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ProtoPie 无代码原型工具恢复上架,享荔枝半价优惠,仅需 429 元

ProtoPie 是一款界面美观、功能强大的无代码原型工具,支持 macOS 与 Windows 双平台。轻松组合即可制作交互动效,摆脱代码束缚。

它能够帮助设计师,无需编程快速地制作出高保真交互原型。还能实时在手机上演示,使原型能够在更多的场景下被使用。

https://asset.droidyue.com/image/2021/08/%E5%9B%BE1.png

ProtoPie 现与数码荔枝再度合作重新上架,官网原价 859 元,现在仅需 429 元。通过 [合作伙伴] 专属链接,下单就能享受 5 折特惠价,新注册用户再享 5 元立减优惠:马上购买


Ubuntu下 /usr/lib/* 内容恢复

有一次处理 Ruby 的版本问题,删除了/usr/lib/ruby文件夹,然后导致了ruby 出现各种问题。

那么怎么解决呢,重做系统,其实大可不必。在 Ubuntu 下使用这个方法即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
raw_pkgs = `dpkg --get-selections`.split("\n")
need_reinstall = []

path="/usr/lib/ruby"

raw_pkgs.each do |x|
    pkg = x.split(" ")[0]
    if `dpkg -L #{pkg}`.include? path
        puts "-> #{pkg} has files in #{path}"
        need_reinstall << pkg
    end
end
puts "\nYou need to reinstall #{need_reinstall.size} packages:"
puts "\tsudo apt-get install --reinstall " + need_reinstall.join(" ")

Gcc-6 G++-6 无法安装问题解决

在 Ubuntu 20.04 安装gcc-6和g++-6 遇到这样的问题

1
2
3
4
5
6
7
8
9
10
11
sudo apt-get install gcc-6 g++-6 -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package gcc-6 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

Package g++-6 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

TransactionTooLargeException 问题分析与解决

在处理 App 崩溃时,有一种崩溃问题着实难以解决,甚至是令人挠头。比如像是今天将讨论的TransactionTooLargeException。下面就是该异常出现时的 stacktrace 信息。

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
java.lang.RuntimeException: Adding window failed
at android.view.ViewRootImpl.setView(ViewRootImpl.java:548)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
... 16 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

在上面的 stacktrace 中 我们 没有找到任何应用相关的代码信息,这让解决这类问题变得更加棘手。

Curl 设置代理,看这篇就够了

curl 是一个很有名的处理网络请求的 类Unix 工具。出于某种原因,我们进行网络请求,需要设置代理。本文讲全面介绍如何为 curl 设置代理。

设置代理参数

基本用法

1
-x, --proxy [protocol://]host[:port]

Android WebView 获取网页源码 实践与问题解决

出于某些场景需要,有时候,我们需要从 WebView 获取源码,本文将简单介绍如何从 WebView 中获取源码,以及遇到的问题的分析和总结。

获取源码的方法

  • WebView 没有提供直接获取网页源码的方法
  • 我们需要使用Javascript 的方法来获取源码,具体的核心代码如下
1
2
3
4
function() {
    var content = document.getElementsByTagName('html')[0].innerHTML;
    return '<html>' + content + '</html>';
})

传音 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>...]'