0%

Android错误集

刷机教程

常规错误

1
2
3
dl.google.com:443 failed to respond
Could not resolve com.android.tools.build:gradle:4.0.1
Could not resolve all artifacts for configuration ':classpath'
  • 上面错误,主要是目标文件不可以访问,原因有:在整个的repositories内找不到对应版本的目标文件,或者是网络无法访问到目标服务器.

Android-studio 3.1 error: style attribute ‘android:attr/keyboardNavigationCluster’ not found.

1
2
error: style attribute 'android:attr/keyboardNavigationCluster' not found.
Message{kind=ERROR, text=error: style attribute 'android:attr/keyboardNavigationCluster' not found., sources=[/home/michael/.gradle/caches/transforms-1/files-1.1/design-27.1.1.aar/e3f34410f8f84b1f2b297174f475b194/res/values-v26/values-v26.xml:3:5-6:13], original message=, tool name=Optional.of(AAPT)}
解决方案
  • 修改app下的 build.gradle
  • dependences 里改成 implementation 'com.android.support:appcompat-v7:27.1.0'
  • 同时修改成compileSdkVersion 26,targetSdkVersion 26,要大于等于26的版本.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
android {
compileSdkVersion 27
buildToolsVersion "27.0.3" // not needed since com.android.tools.build:gradle:3.0.0

defaultConfig {
minSdkVersion 14
targetSdkVersion 26
}

[...]

dependencies {
[...]
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
[...]
}

}

吐血的Gradle sync failed.

1
2
3
4
5
6
7
[...]
Gradle Daemon started in 950 ms
Gradle Daemon started in 909 ms
Gradle Daemon started in 848 ms
Gradle Daemon started in 875 ms
Gradle Daemon started in 871 ms
[...]
  • 并且使用的内存一直不断上升,它不会因为使用内存过多而被内核Kill掉,内存用完之后就是使用硬盘Swap,直接卡死,如果恢复响应后,在Event log里必然显示下面信息:
1
Gradle sync failed: The first result from the daemon was empty. Most likely the process died immediately after connection
  • Gradle同步失败:管道无效,问题在于,Gradle守护进程会尝试使用IPv4而非IPv6.

  • 下面是我的一个取巧的方法.Android Studio打开工程时,它就自动Gradle Build时,在终端里用下面命令Kill掉.

1
2
3
4
~$ which jps
/fullpath/jdk1.8.0_112/bin/jps

~$ jps | grep "Gradle" | awk '{print $1}' | xargs kill -9
  • 通过终端去到工程目录下,使用gradlew build.
1
2
3
4
5
6
7
8
9
10
11
12
~$ ./gradlew build

[...]
BUILD SUCCESSFUL in 7s
1 actionable task: 1 executed

// 编译并打Debug包
~$ ./gradlew assembleDebug

// 编译并打Release的包
~$ ./gradlew assembleRelease

  • 如果在终端运行上面的命令,还是出现如下的错误, 是与IDE里的端终显示同一类的错误.
1
2
3
4
5
6
7
8
Starting a Gradle Daemon (subsequent builds will be faster)
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
Starting a Gradle Daemon, 2 busy Daemons could not be reused, use --status for details
Starting a Gradle Daemon, 3 busy Daemons could not be reused, use --status for details
Starting a Gradle Daemon, 4 busy Daemons could not be reused, use --status for details
Starting a Gradle Daemon, 5 busy Daemons could not be reused, use --status for details
Starting a Gradle Daemon, 6 busy Daemons could not be reused, use --status for details
[.....]
  • 现在来记录解决这个问题步骤,代理肯定是配置的,最优先配置使用工程目录下的gradle.properties,其次用户目录也有一个同名文件:
1
2
~$ ls ~/.gradle
caches daemon gradle.properties kotlin-profile native notifications workers wrapper
  • 根据上面终端提示use --status for details,可以打开~/.gradle/daemon/<gradle version>/daemon-xxx-out.log查看细节,如果里面包含如下行:
1
2
3
4
[...]
[DEBUG] [org.gradle.launcher.daemon.bootstrap.DaemonStartupCommunication] Completed writing the daemon greeting. Closing streams...
[ERROR] [org.gradle.internal.remote.internal.inet.TcpIncomingConnector] Cannot accept connection from remote address /192.168.1.100.
[...]
  • 并且,如果本机系统有开启IPv6,上面的无法连接可能是Gradle同步失败:管道无效,问题在于,Gradle 守护进程会尝试使用IPv4而非IPv6.设置Shell环境变量:export _JAVA_OPTIONS="-Djava.net.preferIPv6Addresses=true"再运行./gradlew assembleRelease尝试.gradle用户配置如下:
1
2
3
4
5
6
7
8
9
~$ cat ~/.gradle/gradle.properties
[...]
org.gradle.parallel=true
org.gradle.daemon=true
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=8123
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=8123
systemProp.https.nonProxyHosts=127.0.0.1|localhost|192.168.1.100
  • 把工程里的gradle/wrapper/gradle-wrapper.properties里的distributionUrl可以指成网络位置,也可以指定本地位置,如:distributionUrl=file\:///home/fullpath/sdkman/archives/gradle-6.4.1.zip. 如果是指定了本地的位置后,在File -> Project Structure -> Project --> Gradle Version就会是空,这里就保持为空,不要选择,如果选择了一项,它就会重写distributionUrl为官网的网络位置, 同时要确保指向本地位置版本的Gradle要与Bash Shell内指定是同一个版本.Gradle的版本兼容性,参考Android Gradle plugin release notes
  • 还有一个问题是,设置Android-Studiograldew使用同一个gradle实例,可以参考这里.
  • 解决方法 2:在Android Studiovmoptions文件中,将-Djava.net.preferIPv6Addresses=true行更改为-Djava.net.preferIPv6Addresses=true.
  • 最终该问题在Android Studio 3.6.3版本中配置Gradle Plugin 3.6.3Gradle 5.6.4,并通过Ctrl+Alt+S --> Build,Execution,Deployment --> GradleUse Gradle from设置成Specified location选择本地的SDKMAN安装目录的下gradle/5.6.4,上述设置后,再把所有的(工程|用户)gradle.properties加上这一行:org.gradle.jvmargs=-Djava.net.preferIPv6Addresses=true -Djava.net.preferIPv6Stack=true, 先在Bash shell运行一次./gradlew build后,再去到IDE时好像同步文件就正常了.
1
2
3
4
5
6
7
8
9
Build #AI-192.7142.36.36.6392135, built on April 14, 2020
Runtime version: 1.8.0_212-release-1586-b4-5784211 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Linux 5.5.13-20200327-lcy
GC: ParNew, ConcurrentMarkSweep
Memory: 1246M
Cores: 4
Registry: ide.new.welcome.screen.force=true
Non-Bundled Plugins: com.google.services.firebase`
  • 最终确定可能是系统里设置了iptables -t nat -A POSTROUTING -j MASQUERADE造成的,参考这里
  • 命令行(bash)里使用./gradlew build可以正常编译,在android studio里还是问题如故,因为命令行里读到了环境变量export _JAVA_OPTIONS="-Djava.net.preferIPv6Addresses=true". 因此需要修改android studio的启动脚本,它本身就是用脚本android-studio/studio.sh启动,在该脚本里添加上述的变量,就能正常使用了。

Android系统源码AOSP 下载.

同步源码

配置环境

1
2
3
4
~$ mkdir ~/bin
~$ PATH=~/bin:$PATH
~$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
~$ chmod a+x ~/bin/repo

下载源码

1
2
3
~$ mkdir Android-AOSP && cd Android-AOSP
~$ repo init -u https://android.googlesource.com/platform/manifest
~$ repo sync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
~$ cat .repo/manifests.git/config
[core]
repositoryformatversion = 0
filemode = true
[filter "lfs"]
smudge = git-lfs smudge --skip -- %f
process = git-lfs filter-process --skip
[remote "origin"]
#url = https://android.googlesource.com/platform/manifest
url = https://aosp.tuna.tsinghua.edu.cn/platform/manifest
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
remote = origin
merge = refs/heads/master
  • 我最终是改成清华大学镜像同步完成.2020-03-16同步完成后,目录体积显示是93G.后来对比了官方https://android.googlesource.com/device/与本地device目录,好像少了一些设备目录,比如:htc,samsung是没有看到的.

验证Git标记

  • 输入gpg --import后粘贴下面的PGP密钥数据.
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
~$ gpg --import
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV
lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7
8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD
u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z
wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq
/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5
jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4
MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9
b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv
aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k
cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX
gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI
2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl
QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up
hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk
C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX
LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+
OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M
pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s
KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb
N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA
vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo
G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ
hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l
EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=
=Wi5D
-----END PGP PUBLIC KEY BLOCK-----
EOF
  • 测试验证tag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
~$ cd device/generic/mini-emulator-arm64
~$ git tag -v android-5.0.0_r1
object 743dd408af5c662761bafc05eacdb18ade88cf3a
type commit
tag android-5.0.0_r1
tagger The Android Open Source Project <initial-contribution@android.com> 1415119682 -0800

Android 5.0.0 release 1
gpg: Signature made Wed 05 Nov 2014 12:48:02 AM CST
gpg: using DSA key E8AD3F819AB10E78
gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 4340 D135 70EF 945E 8381 0964 E8AD 3F81 9AB1 0E78

Android Material组件

Android图标资源

  • 参考链接:

  • 之前开发时,还去不同网站上去下载图标下来,放到app/src/main/res/drawable或者是``app/src/main/res/icons内,其实使用[Image Asset Studio](https://developer.android.com/studio/write/image-asset-studio)是最方便的.它可以满足各种类型的图标创建,包括自适应图标.还可以使用[Android-Iconics](https://github.com/mikepenz/Android-Iconics),它集成多个图标资源在一起,比如:FontAwesome`.

导入PNG图标

  • Project窗口中,选择Android视图,右键点击res文件夹,然后依次选择New > Image Asset.Icon Type可以选:启动器图标,操作栏和标签页图标,通知图标.
  • 选中Asset TypeClip Art时,点击下方的Clip Art就会弹出一个内置的图标列表,选择一个图标编辑后,按完成就会提示,保存到app/src/main/res/drawable下面.
  • 选中Asset TypeImage时,下面的Path可以选择一个本地位置的PNG文件,可以先把material-design-icons同步下来,再通过该步骤编辑导入到工程去.
  • 也可以手动复制自定义的PNG文件放到工程里的app/src/main/res/drawable.

导入SVG图标

  • Project窗口中,选择Android视图,右键点击res文件夹,然后依次选择New > Vector Asset.
  • 选中Asset TypeClip Art时,点击下方的Clip Art就会弹出一个内置的图标列表,选择一个图标编辑后,按完成就会提示,保存到app/src/main/res/drawable下面.
  • 选中Asset TypeLocal file(SVG,PSD)时,下面的Path可以选择一个本地位置的矢量文件,可以先把material-design-icons同步下来,再通过该步骤编辑导入到工程去.
  • 也可以手动复制自定义的SVG文件放到工程里的app/src/main/res/drawable.

使用Android Material Design Icon Generator插件


谢谢支持