通通不可说

生命永远充满希望

0%

Android开发中,不可避免的可能会引用到外部so文件,设置一个项目中可能需要引用多个不同的外部so文件。因为不同的引入库中so文件的目录可能不同,导致打包后生成的项目lib目录中的目录结构是不同的外部so文件目录的合集。可能会出现armeabi/armeabi-v7a/arm64-v8a/x86/mips等,一般情况下,armeabi应该是有的,当此三个目录下的文件可能不同时,在某些特定机型下很可能会出现UnsatisfiedLinkError

原因在于不同的机型CPU结构不同导致搜寻不同的目录下面的包,而由于外部库不同的so文件目录可能armeabi下还有a、b so文件,而x86下可能只含有a。例如一个应用armeabi下有liba.solibb.so,arm64-v8a下有liba.so这样的应用装在arm64的设备上,当代码掉到加载libb.so时就会有上面的异常出现,即便是armeabi下有此so,系统也不会去寻找,原因是这个apk中已经有arm64的目录了。

此时解决方案如下:

在build.gradle中添加如下内容

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi'
        }
    }
}

这样生成的apk中就只包含armeabi下的so文件,而不包含其他架构的目录,这样系统会采取兼容模式,加载armeabi下的so文件。

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.1'
    }
}
apply plugin: 'com.android.application'

allprojects {
    repositories {

    }
}

dependencies {
    compile fileTree(include: '*.jar', dir: 'libs')
}

repositories{
    flatDir {
        dirs 'libs'
    }
}

android {
    compileSdkVersion 23
    buildToolsVersion "24.0.0"

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}

一、 在github上下载工具 https://github.com/getfatday/keytool-importkeypair 将工具在Linux环境下解压或者解压后Copy到Linux下,运行如下命令

keytool-importkeypair -k android/debug.keystore -p android -pk8 android/platform.pk8 -cert android/platform.x509.pem -alias androiddebugkey

二、 1 把pk8转换成pk12格式

openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt

2 生成pk12的密钥问文件

openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name androiddebugkey

3 生成keystore

keytool -importkeystore -deststorepass android -destkeypass android -destkeystore debug.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass android -alias androiddebugkey

所有需要传递或接收的 Activity 不允许设置singleInstance,或只能设为标准模式,否则在部分手机上系统将在 startActivityForResult()后直接返回Activity.RESULT_CANCELED,但在某些手机是正常的。

1.proxychains-ng安装

1
2
3
4
5
6
git clone https://github.com/rofl0r/proxychains-ng.git
cd proxychains-ng/
./configure --prefix=/usr/local/proxychains --sysconfdir=/etc
sudo make
sudo make install
sudo make install-config

2.proxychains-ng配置

1
2
3
4
sudo vim /etc/proxychains.conf
#将socks4 127.0.0.1 9095改为自己的代理端口
socks5 127.0.0.1 1080 //1080改为你自己的端口
sudo cp /usr/local/proxychains/bin/proxychains4 /usr/local/bin/proxy

3.proxychains-ng使用

1
proxy wget http://www.baidu.com

示例脚本

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
apply plugin: 'com.android.application'

def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

android {
compileSdkVersion 21
buildToolsVersion '21.1.2'

defaultConfig {
applicationId "com.boohee.*"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"

// dex突破65535的限制
multiDexEnabled true
// 默认是umeng的渠道
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"]
}

lintOptions {
abortOnError false
}

signingConfigs {
debug {
// No debug config
}

release {
storeFile file("../yourapp.keystore")
storePassword "your password"
keyAlias "your alias"
keyPassword "your password"
}
}

buildTypes {
debug {
// 显示Log
buildConfigField "boolean", "LOG_DEBUG", "true"

versionNameSuffix "-debug"
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.debug
}

release {
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"

minifyEnabled true
zipAlignEnabled true
// 移除无用的resource文件
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release

applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 输出apk名称为boohee_v1.0_2015-01-15_wandoujia.apk
def fileName = "boohee_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}

// 友盟多渠道打包
productFlavors {
wandoujia {}
_360 {}
baidu {}
xiaomi {}
tencent {}
taobao {}
...
}

productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:21.0.3'
compile 'com.jakewharton:butterknife:6.0.0'
...
}

操作系统:ubuntu 14.04
一.安装需要工具

1
sudo apt-get install autoconf libtool libsysfs-dev

二.制作交叉编译工具链
1.下载NDK,并配置NDK环境变量为NDK的安装路径
2.根据NDK里docs文档里的standalone-toolchain.html来抽取交叉编译的环境。
3.配置SYSROOT环境变量:

1
SYSROOT=$NDK/platforms/android-19/arch-arm //android-19是你的android开发版本所定

4.然后运行命令:

1
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-19 --install-dir=/tmp/my-android-toolchain

/tmp/my-android-toolchain是你交叉编译环境的复制路径。最好别放在tmp目录里,因为重启机子就立即消失了。这个新生成的文件 夹即是你的交叉编译环境
5.配置PAHT和CC环境变量:

1
2
export PATH=/tmp/my-android-toolchain/bin:$PATH
export CC=arm-linux-androideabi-gcc

三.下载curl并编译

1
2
3
4
5
6
7
git clone https://github.com/curl/curl.git
cd curl
mkdir build
autoreconf -i
./configure --host=arm-linux --enable-cross-compile --enable-threaded-resolver --disable-shared --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-manual --enable-proxy --enable-ipv6 --enable-cookies --enable-symbol-hiding --disable-versioned-symbols --disable-soname-bump --disable-sspi --disable-ntlm-wb --prefix=`pwd`/build
make
make install

在模块的build.gradle中填入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

javadoc {
options {
encoding "UTF-8"
charSet 'UTF-8'
author true
version true
splitIndex true
noDeprecated true
setMemberLevel(JavadocMemberLevel.PUBLIC)
links "http://docs.oracle.com/javase/8/docs/api"
}
}

下面还有一个可能更好使

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
android.libraryVariants.all { variant ->
task("generate${variant.name}Javadoc", type: Javadoc) {
title = "$name $version API"
source = variant.javaCompile.source
ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
classpath = files(variant.javaCompile.classpath.files, ext.androidJar)
options {
links("http://docs.oracle.com/javase/8/docs/api/");
linksOffline("http://d.android.com/reference", "${android.sdkDirectory}/docs/reference");
encoding "UTF-8"
charSet 'UTF-8'
author true
version true
splitIndex true
noDeprecated true
setMemberLevel(JavadocMemberLevel.PUBLIC)
}
failOnError false
exclude '**/BuildConfig.java'
exclude '**/R.java'
}
}

示例build.gradle文件如下。

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
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
}
}
apply plugin: 'com.android.application'

allprojects {
repositories {
//maven { url "https://jitpack.io" }
}
}

dependencies {
compile fileTree(include: '*.jar', dir: 'libs')
//compile(name: 'MPChartLib-release', ext: 'aar')
compile 'com.android.support:support-annotations:24.2.1'
}

repositories{
flatDir {
dirs 'libs'
}
}

android {
compileSdkVersion 23
buildToolsVersion "24.0.0"

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}

// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')

// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}