从Android Studio迁移到IntelliJ,从Gradle2升级到Gradle5.4.1,JNI NDK的配置更新

IntelliJ IDEA,是java编程语言开发的集成环境,在业界被公认为最好的java开发工具之一。参考其官网:https://www.jetbrains.com/idea/。

其实不只是Java,同家公司的Android Studio、PHPStorm、WebStorm、PyCharm、RubyMine的功能,它都有,不就是插件嘛!所以,最近把Android Studio、PHPStorm、WebStorm、PyStorm全部干掉了,所有项目都用IntelliJ来开发。

因为IntelliJ的各种插件都比较新,所以,顺带把Android的各种编译工具和环境更新到相对新的版本,也就有了如下采坑总结,记录一下。

1.gradle.properties

#gradle:3.0.1  studio3.0 之前用
#android.useDeprecatedNdk=true
#gradle:3.0.1  studio3.0 之后用
#android.deprecatedNdkCompileLease=1511832698813
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

2.根目录下的:build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        maven{url 'http://maven.aliyun.com/nexus/content/groups/public/'}
        google()
//        jcenter {
//            url "http://jcenter.bintray.com/"
//        }
    }
    dependencies {
//        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.mob.sdk:MobSDK:+'
        classpath 'com.mob.sdk:MobSDK-Impl:2018.0710.1743'

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

allprojects {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
        maven {
            url 'https://dl.bintray.com/youzanyun/maven/'
        }
    }
}

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

3.library目录下的:build.gradle

apply plugin: 'com.android.library'

android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    lintOptions {
        abortOnError false
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

}

4.子项目的build.gradle


android {
    dexOptions {
        preDexLibraries = false
        javaMaxHeapSize "4g"
    }

    externalNativeBuild {
        ndkBuild {
            path "src/main/jni/Android.mk" // 设置所要编写的c源码位置,以及编译后so文件的名字
        }
    }

    compileOptions {
        encoding = "UTF-8"
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    signingConfigs {

        release {
            keyAlias '***'
            keyPassword '***'
            storeFile file('../***')
            storePassword '***'
        }
    }
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

    compileSdkVersion 28

    defaultConfig {
        applicationId "com.threeti.huimapatient"
        multiDexEnabled true
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 800
        versionName "8.0.0"

        // 下面这段是老版本的写法,不需要了
//        ndk {
//            moduleName "JniAES"
//            ldLibs "log", "z", "m"
//            abiFilters "armeabi-v7a", "x86"
//        }
        // 使用ndkBuild工具
        externalNativeBuild {
            ndkBuild {
                //指定 Application.mk 的路径
                arguments "NDK_APPLICATION_MK:=src/main/jni/Application.mk"
                //指定生成哪些平台的 so 文件
                //abiFilters "armeabi-v7a", "armeabi"
                //生成多个版本的so文件
                abiFilters "armeabi-v7a", "x86"
                //cFlags 和 cppFlags 是用来设置环境变量的, 一般不需要动
                cFlags "-DTEST_C_FLAG1", "-DTEST_C_FLAG2"
                cppFlags "-DTEST_CPP_FLAG2", "-DTEST_CPP_FLAG2"
                //cppFlags ""
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.release

            applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "YOURAPPNAME_release_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk"
                }
            }
        }
    }

    sourceSets {
        main {
            jni.srcDirs = ['src/main/jni','src/main/jni/']
            jniLibs.srcDir 'src/main/libs'
        }
    }

    // Specifies the flavor dimensions you want to use. The order in which you
    // list each dimension determines its priority, from highest to lowest,
    // when Gradle merges variant sources and configurations. You must assign
    // each product flavor you configure to one of the flavor dimensions.
    flavorDimensions "default"//,"mode","version","api"

    productFlavors {
        xiaomi { // Assigns this product flavor to the "mode" flavor dimension.
            dimension "default"
        }
        yingyongbao { // Assigns this product flavor to the "mode" flavor dimension.
            dimension "default"
        }
        huawei { // Assigns this product flavor to the "mode" flavor dimension.
            dimension "default"
        }

        // 这里需要这个配置是因为,我们上面虽然建立了渠道,但是并没有处理Manifest里面的meta-data信息。
        productFlavors.all { flavor ->
            flavor.manifestPlaceholders = [UMENG_CHANNEL: name] //动态地修改AndroidManifest中的渠道名
        }
    }
    useLibrary 'org.apache.http.legacy'
}

repositories {
    flatDir {
        dirs 'libs'
    }
    mavenCentral()
}


dependencies {
    implementation 'in.srain.cube:ultra-ptr:1.0.11'
    implementation files('libs/universal-image-loader-1.9.3.jar')
    implementation (name: 'alipaySdk-15.6.8-20191021122455-noUtdid', ext: 'aar')
    ...
}

5.对应的android.mk

LOCAL_PATH := $(call my-dir)

# Builds a dylib out of test.cpp
# 会清除很多 LOCAL_XXX 变量,不会清除 LOCAL_PATH,基本上是固定的,不需要去动
include $(CLEAR_VARS)
# 需要构建模块的名称,会自动生成相应的 libNDKSample.so 文件,每个模块名称必须唯一,且不含任何空格
LOCAL_MODULE := JniAES
# 包含要构建到模块中的 C 或 C++ 源文件列表
LOCAL_SRC_FILES := KeyValue.c
# 指定这个模块里会用到哪些原生 API,详见:https://developer.android.google.cn/ndk/guides/stable_apis.html
LOCAL_LDLIBS := -llog
# 帮助系统将所有内容连接到一起,固定的,不需要去动
include $(BUILD_SHARED_LIBRARY)

6.对应的Application.mk

# https://developer.android.com/ndk/guides/application_mk.html
# 选择不同的 ABI,多个使用空格作为分隔符,全部是all
APP_ABI := all # armeabi-v7a x86
# 指定要使用的运行时
APP_STL := system

参考:

https://developer.android.com/ndk/guides/android_mk

https://www.cnblogs.com/webor2006/p/9999063.html

http://wuxiaolong.me/2017/12/27/AndroidNDK/

Android安卓上用代码实现设置圆角radius的颜色背景

Android经常会使用shape来定制一些View的背景,可以修改View的背景颜色,形状等属性。一般情况下,shape都是在xml文件里面实现,比如:

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#1d3c80" />
    <corners android:radius="@dimen/dim30" />
</shape>

继续阅读“Android安卓上用代码实现设置圆角radius的颜色背景”