ERROR: Received close_notify during handshake

Android Studio GradleSync一直失败,提示:ERROR: Received close_notify during handshake

https://stackoverflow.com/questions/59408006/error-received-close-notify-during-handshake

说是ssl连接的问题,关闭防火墙再试一次,果然就好了。本地java版本1.8

Gradle是什么,可以参见Unity2018导出Android工程并自行生成apk 这篇文章

GradleSync的时候是在干什么,可以参见https://www.jianshu.com/p/24a38f8400cc


!!!!!!!!!!!!下面都是记录其他Android相关的内容了,跟标题无关

目录

MAC想查看本机的android sdk的详细信息

第一步 先找到android sdk的存放路径

第二步 再使用android manager查看sdk版本.

Gradle Sync提示或者错误

1.Gradle sync failed: Failed to find target with hash string 'android-27'

2.Android Studio is using this JDK location: which is different to what Gradle uses by default:

3.一直在sync project with gradle files

Unity-Android开发的几种调试模式

1.使用adb logcat 打印在手机上的运行的日志

2.Monitor界面化进行查看android手机上的日志

3.ddms.bat

4.Android Studio的打印面板

ADB工具

 

一些工具和概念

APKHelper工具

相关术语

查看手机cpu架构

android SDK vs JDK vs android  NDK

Android SDK

JDK

Android NDK

Android Studio的使用

新建项目以及构建以及测试

Project的项目结构模式

某模块下目录内容-app

相关的Gradle构建命令

1)MakeProject命令

2)Android Studio中内置的gradle命令

3) Gradle 中Task的使用

使用Android Studio建立JNI工程

AAR相关

AAR包文件结构

项目中引用AAR包

AAR包使用注意事项

APK的签名

签名和校验过程

apk中的签名相关文件——META-INF文件夹

APK的校验过程

apk的签名文件——keystore

1)Unity的默认证书keystore文件

2)gradle中指定keystore文件

3)androidstudio中

 

签名过程的代码实现

Android APK的反编译方法

方法一:命令行工具apktool、dex2jar、jd-gui

apktool工具:获得图片与XML资源

dex2jar工具:将classes.dex转换成jar文件

jd-gui工具:查看jar包中的Java代码

方法二,可视化的反编译工具androidkiller

方法三


MAC想查看本机的android sdk的详细信息

第一步 先找到android sdk的存放路径

方式一:通过unity 找到现在的androidsdk的存放路径如图所示:

 

方式二:通过androidstudio ,如图所示:

第二步 再使用android manager查看sdk版本.

方式一:通过命令行打开

通过第1步找到的sdk的路径,cd到那个路径下的tools目录下

然后输入 ./android sdk

会弹出android manager的界面-android manager界面介绍:https://www.cnblogs.com/kangjianwei101/p/5621238.html

方式二:通过android studio 打开 略


Gradle Sync提示或者错误

1.Gradle sync failed: Failed to find target with hash string 'android-27'

这是从网上下载下来的项目。
找到他的配置中使用的编译sdk是27。但是我本地的sdk是29所以修改为29即可,如下:

compileSdkVersion: 29,
buildToolsVersion: "29.0.2",

minSdkVersion : 21,
targetSdkVersion : 29,

按我的理解,compileSdkVersion 和  targetSdkVersion 最好是一样的。

 

2.Android Studio is using this JDK location: which is different to what Gradle uses by default:

Android Studio is using this JDK location:
I:\AndroidStudio\jre
which is different to what Gradle uses by default:
C:\Program Files\AdoptOpenJDK\jdk8u192-b12
Using different locations may spawn multiple Gradle daemons if
Gradle tasks are run from command line while using Android Studio.

(多个Gradle daemon,daemon)

 

修改jdk路径-file-project structure:

(所以androidstudio带了jdk) 

 

3.一直在sync project with gradle files

找不到停止sync的按钮,就直接关掉as重新打开过 


调试Android

1.使用adb logcat 打印在手机上的运行的日志

手机连上电脑,手机调成开发模式,使用adb命令查看看到连接上的设备

adb devices 

(把adb的路径存入PATH环境变量,就不用cd到adb所在的目录了,直接adb就可以了)

然后使用logcat命令,打印日志:(在手机上运行app,就能把产生的日志记录到out.txt中了)

指定 Unity 过滤器:

adb Logcat -s Unity > out.txt


或者不指定 Unity 过滤器:
adb Logcat > out.txt

 

辅助其他一些命令看输出(我一般是windows 安装了gitbash 在gitbash中输入命令):

也可以使用tail -f  out.txt命令把日志打印到控制台

打印出来其他的也可以使用grep xxx进程号 专门打印这个游戏的进程的东西,因为手机里面的日志能多,运行的app很多。

 

Android中的打印日志的api有如下:

Log.i(TAG, "onBind方法被调用!");

ADB工具

ADB(Android Debug Bridge)是Android SDK中的一个工具,如果你安装了androidsdk,就可以在platform-tools这个路径下找到这个工具:

设置adb的路径存入PATH环境变量,方便敲命令。

adb devices ——查看当前连接设备:
adb logcat > 33333.log  ——查看日志信息:

“-s”选项 : 设置默认的过滤器, 如 
我们想要输出 “System.out” 标签的信息, 就可以使用:

adb logcat -s System.out

我们想要输出 “Unity” 标签的信息, 就可以使用:

adb logcat -s Unity

进入linux命令行即手机终端命令,#代表已经root了,$代表没有root权限——查看设备否有root权限

adb shell

 

adb install xxxx.apk ——在电脑端安装apk,无需拷贝到手机上安装了。参数-r,重新安装,-s 安装到sd卡。
adb uninstall 包名(比如com.xxx.xxx)——卸载app,-k只删除程序,不删除所用数据与缓存目录
adb pull/push xxxx ——取出/发送手机中的文件
adb:reset adb / adb kill-server / adb start-server  —— 重启/杀死/启动adb

 

其他用到过以后再继续补充 https://blog.csdn.net/ezconn/article/details/85708000

 

2.monitor上查看android手机上的日志

C:\Android\android-sdk\tools\monitor.bat

双击一下运行就行了 下次试试 

 

3.ddms.bat

在sdk的目录下 tools目录下有一个ddms.bat的文件,可以双击打开这个文件,就能看到打印信息,但是这个能看到所有的打印信息,需要过滤一下,具体方法还没用过下次用下  下次试试 

(我本地的下载的sdk好像没有这个bat)

DDMS:(dalvik debug monitor service)安卓调试工具

 

4.Android Studio的打印面板

其实这个和第2种方法一样,只不过在使用的时候更方便


 

一些工具和概念

APKHelper工具

可以快速查看某个apk的版本号,build号等信息

 

相关术语

AVD: (android virtual machine):安卓虚拟设备,就是安卓的模拟器

ADT: (android development tools)安卓开发工具

DDMS:(dalvik debug monitor service)安卓调试工具

DX工具:将.class转换成.dex文件

 

查看手机cpu架构

https://blog.csdn.net/weixin_42229404/article/details/80865138?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

adb device  查看连接的设备,
adb -s 192.168.56.101:5555 shell (如果只有一个设备就 直接adb shell)  进入手机的shell设置模式,
        cat /proc/cpuinfo  查看手机CPU信息

Android系统目前支持以下七种不同的CPU架构:

  • ARMv5
  • ARMv7 (从2010年起),
  • x86 (从2011年起),
  • MIPS (从2012年起),
  • ARMv8MIPS64x86_64 (从2014年起),

以上 包含了3种CPU架构:

  • MIPS——厂商MIPS——指令集mipsmips64
  • ARM——厂商ARM——指令集armeabi(ARM v5)armeabi-v7a(ARM v7),arm64-v8aARM v8-ARM公司的首款支持64位指令集的处理器架构)
  • X86——厂商Intel——指令集x86x86_64

ARMv8指令集:

ARMv8架构,就是在MIPS64架构上增加了ARMv7架构中已经拥有的的TrustZone技术、虚拟化技术及NEON advanced SIMD技术等特性,研发成的。ARM是通过收购MIPS的形式得到了64位。

比如海思麒麟 960 处理器 是 cortex-A53 + cortex-A73,均是ARMv8-A构架的。

Cortex-A35、Cortex-A53、Cortex-A57、Cortex-A72——基于ARMv8-A架构
Cortex-A7、Cortex-A9、Cortex-A32、Cortex-A17——基于ARMv7-A 架构

64位处理器手机 vs 64位手机:

64位处理器手机:只要是处理器包含64架构位的,这种手机也许还运行不了64位程序,只是用来抢占市场,和32位手机比起来优势并不明显。
64位手机:它包含着64位处理器、64位标准系统、64位安卓虚拟机、以及64位程序。64位手机如果有app下有64位abi目录,就以64位运行,如果没有就以32位运行。

 

android SDK vs JDK vs android  NDK

 

Android SDK

(Android Software Development Kit):

android 软件开发工具包用来开发android的。

相当于安卓机器的操作系统,类似与windows操作系统,没有android sdk开发包的支持,就无法进行android应用开发,提供给你一个开发android应用的环境。

        与java的关系:为了能够使 Java 开发者快速转入 android应用的开发,所以仿照 Java API 重新进行了实现,因而大多数标准库中的资源都可以按照原来java开发的方式使用。

如何查看android sdk版本号:上面使用mac查看android sdk的版本号

 

JDK

java软件开发工具包。

这个包中提供了java语言的类库,也就是你要用java语言,那么电脑上必须装jdk。

unity中关于android的设置关于jdk和sdk的存放路径:

因为unity导出打包成android应用,就需要用到android sdk,安卓应用用java开发,java开发就需要底层的java类库,这些类库就被封装在JDK中。

查看版本号:

java -version

 

Android NDK

摘自 https://blog.csdn.net/huang_yx005/article/details/78780450

(Native Development Kit):NDK允许用户使用类似C / C++之类的原生代码语执行部分程序。Android程序运行在Dalvik虚拟机中。Android的SDK基于Java实现,所以基于Android SDK进行开发的第三方应用一般都使用Java语言,但这并不等同于“第三方应用只能使用Java”,也就是说我们还可以采用C/C++语言。

NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so(通过NDK编译C/C++生成的)和java应用一起打包成apk(AndroidPackage的缩写,Android安装包)。这些工具对开发者的帮助是巨大的。

NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。

NDK提供了一份稳定、功能有限的API头文件声明,Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。


Android Studio的使用

下载android studio https://developer.android.com/studio

安装好了以后马上启动

提示没有安装android sdk(android sdk 的具体介绍 在本篇文章 和 Unity2018导出Android工程并自行生成apk 搜就行了):

点击cancle,进入初次登陆配置界面,最后选择 默认推荐配置就行了,会给你下载android sdk。

新建项目以及构建以及测试

IDE下载安装好了,用一下。

选择新建一个项目,选择empty activity,填到最后第一次会开始下载gradle,gradle sync之类的。

选择empty activity会生成一个 MainActivity.java activity_main.xml

MainActivity.java:

package xdw.com;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivityextends AppCompatActivity {

@Override

    protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState); // 调用父类的方法

        setContentView(R.layout.activity_main);  // 加载布局资源文件 layout目录下 activity_main.xml

    }

}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 等一段时间,等gradle sync成功了以后,进行build apk (其实就是调用gradle 进行 build 的工作了):

build成功以后,就可以点击 Run--》Run “app”进行测试了(如果没有配置模拟机,点击Tools--》AVD Manager(andriod virtual device)进行配置) :

自己遍历一下多点点探索一下。

Project的项目结构模式

.gradle和.idea目录           ——是AS自动生成的文件,不用编辑。

app目录                            ——包含了代码和资源文件,开发是在这个目录下进行的。

gradle目录                       ——包含了gradle wrapper的配置文件。

.gitignore文件                   ——是用来将指定的目录或文件排除在版本控制外。

build.gradle文件               ——是项目全局的gradle构建脚本。

gradle.properties文件       ——是全局的gradle配置文件。

gradlew和gradlew.bat文件——是用来在在命令行界面执行gradle命令的,前者用于Linux或Mac系统,后者用于Windows系统。

HelloWorld.iml文件         ——是IDEA项目自动生成的文件,不需要更改。

local.properties文件       ——用于指定本机Android SDK路径,通常不用更改,除非本机的Android SDK位置发生变化。

settings.gradle文件        ——用于指定项目中所有引入的模块

加粗的都是跟gradle构建工具有关的配置。

 

某模块下目录内容-app

build——构建目录,包含编译时自动生成的文件

libs——依赖的包,用来存放第三方jar包。

src——开发大部分的东西都放在这个文件夹中

    androidTest——用来编写Android Test测试用例,可以对项目进行一些自动化测试。

    main

      ————————————————————————————————————————

      java——放Java文件

      assets目录,虽然这里没有,但是我们可以自己创建,也是存放资源文件的。

      raw目录:虽然这里没有,但是我们可以自己创建, 用于存放各种原生资源(音频,视频,一些XML文件等),我们可以通过openRawResource(int id)来获得资源的二进制流!其实和Assets差不多,不过这里面的资源会在R文件那里生成一个资源id而已。

      anim目录:动画有两种:属性动画和补间动画:animator:存放属性动画的XML文件;anim:存放补间动画的XML文件。

      res存放资源文件,包括图片、布局、字符串等。图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下。drawable 和 mipmap 都是图片资源 ,使用mipmap会在图片缩放在提供一定的性能优化。不同系统会根据屏幕分辨率来选择-hdpi,-mdpi,-xmdpi,-xxhdpi下的对应图片,存放只是大小和像素不一样的图片!原则是使用最接近的密度级别!另外如果你想禁止Android不跟随屏幕密度加载不同文件夹的资源,只需在AndroidManifest.xml文件中添加android:anyDensity="false"字段即可。(res下的资源通过资源id访问到对应的资源;assets下的资源通过AssetManager以二进制流的形式来读取。

                  ————————————————————————————————————————

            drawable 图像资源,存放各种位图文件,(.png,.jpg,.9png,.gif等)除此之外可能是一些其他的drawable类型的XML文件

            mipmap 也是图片资源 ,使用mipmap会在图片缩放在提供一定的性能优化。

            mipmap-hdpi:高分辨率,一般我们把图片丢这里

            mipmap-mdpi:**中等分辨率,很少,除非兼容的的手机很旧

            mipmap-xhdpi:超高分辨率,手机屏幕材质越来越好,以后估计会慢慢往这里过渡

            mipmap-xxhdpi:超超高分辨率,这个在高端机上有所体现

            layout 布局资源:该目录下存放的就是我们的布局文件,另外在一些特定的机型上,我们做屏幕适配,比如480*320这样的手机,我们会另外创建一套布局,就行:layout-480x320这样的文件夹。

            menu 菜单资源:在以前有物理菜单按钮,即menu键的手机上,用的较多,现在用的并不多,菜单项相关的资源xml可在这里编写,不知道谷歌会不会出新的东西来替代菜单了~

            value :demens.xml:定义尺寸资源;string.xml:定义字符串资源;styles.xml:定义样式资源;colors.xml:定义颜色资源;arrays.xml:定义数组资源;attrs.xml:自定义控件时用的较多,自定义控件的属性;theme主题文件,和styles很相似,但是会对整个应用中的Actvitiy或指定Activity起作用,一般是改变窗口外观的!可在Java代码中通过setTheme使用,或者在Androidmanifest.xml中为<application...>添加theme的属性!

demens:css配置资源
string:字符串资源
styles:style资源

            PS:你可能看到过这样的values目录:values-w820dp,values-v11等,前者w代表平板设备820dp代表屏幕宽度而v11这样代表在API(11),即android 3.0后才会用到的

                 ————————————————————————————————————————

      AndroidManifest.xml——配置文件,定义的四大组件都要在这里注册,权限的声明也在这里。
        ————————————————————————————————————————
test——用来编写Unit Test测试用例。

.gitignore——app模块中的指定目录或文件排除在版本控制外。

build.gradle——app模块Gradle构建脚本,指定构建相关的配置。

proguard-rules.pro——用于指定项目代码的混淆规则。

 

相关的Gradle构建命令

1)Build下的MakeProject

MakeProject其实是执行的BuildVariants配置的类型,如下图就是assembleDebug

2)Android Studio中内置的gradle命令

在AndroidStudio的最右侧,双击就执行了,同样可以在控制台的Build界面看到
assemble就是assembleDebugassembleRelease 这两个Task

3) Gradle 中Task的使用

官方文档 https://docs.gradle.org/current/dsl/org.gradle.api.Task.html

一个Task代表一个构建工作原子操作,例如编译 或者生成javadoc。
Gradle中,每一个待编译的工程都叫一个Project,每一个Project在构建的时候都包含一系列的Task。

Gradle把构建的步骤分成了一个一个的task,我们可以定义task Unity2018导出Android工程并自行生成apk 这篇文章,之前说的gradle文件中定义task)
比如一个Android APK的编译可能包含:

Java源码编译Task、

资源编译Task、

JNI编译Task、

lint检查Task、

打包生成APK的Task、

签名Task

 

下面就是一个自定义的简单的task 的一个例子:

task hello {
    println 'Hello world!'
}

// 语法
task myTask
task myTask { configure closure }  // 花括号就是一个closure

 

// <<符号是doLast的缩写 。
// 我们创建了一个Task对象,同时把closure做为一个action加到这个Task的action队列中,并且告诉它“最后才执行这个closure”。
// 一个Task包含若干Action。所以,Task有doFirst和doLast两个函数,用于添加需要最先执行的Action和需要和需要最后执行的Action。

task myType << { task action }   

 


// type: SomeType 指定Type,告诉Gradle这个新建的Task对象会从哪个基类Task派生。Gradle本身提供有Copy、Delete、Sync(直接到官网搜方法)等
task myTask(type: SomeType)  
task myTask(type: SomeType) { configure closure }

 

 

插件本身就是包含了若干Task的(见下文的 gradlew tasks)。

在AndroidStudio中的console台输入gradlew help ,执行help(即task task) :显示gradle版本号以及提示命令

G:\Project_Android>gradlew help

> Configure project :app
Hello world!

> Task :help

Welcome to Gradle 5.4.1.

To run a build, run gradlew <task> ...

To see a list of available tasks, run gradlew tasks

To see a list of command-line options, run gradlew --help

To see more detail about a task, run gradlew help --task <task>

For troubleshooting, visit https://help.gradle.org

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

 

在AndroidStudio中的console台输入gradlew tasks,执行tasks Task,可以查看有哪些可用的任务。太长不截图了。

每当我们在Android Studio点击 build,rebuild,clean菜单的时候,执行的就是一些gradle task.

基本的 task:

  • assemble:对所有的 buildType 生成 apk 包。
    (在Build tasks中,assemble - Assemble main outputs for all the variants.)
  • clean:移除所有的编译输出文件,比如apk
    (在Build tasks中,clean - Deletes the build directory.)
  • check:执行lint检测编译。
    (在Verification tasks中,check - Runs all checks.)
  • build:同时执行assemble和check命令
    (在Build tasks中,Assembles and tests this project.)
  • install:将编译后的apk 安装到连接的设备
  • uninstall:卸载apk

其中assemble用的比较多

默认的 assmeble 会依赖 assembleDebug 和assembleRelease,如果直接执行assmeble,最后会编译debug,和release 的所有版本出来。如果我们只需要编译debug 版本,我们可以运行assembleDebug。

如果执行gradlew assembleDebug4zj,就是编译buildType中定义的Debug4zj模式,即它可以结合构建类型(buildTypes)去创建task。
如果执行gradlew assembleBaiduDebug4zj 就会打出,buildType中定义的Debug4zj模式+productFlavors 中的定义的Baidu模式,即可以结合Build Variants(projectFlavors+buildTypes))来创建新的Task。

 

查看某个具体task的含义,比如sourceSets

G:\Project_Android>gradlew help --task sourceSets
> Configure project :app
Hello world!

> Task :help
Detailed task information for sourceSets

Path
     :app:sourceSets

Type
     SourceSetsTask (com.android.build.gradle.internal.tasks.SourceSetsTask)

Description
     Prints out all the source sets defined in this project.

Group
     Android

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

 

使用Android Studio建立JNI工程

Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分。JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性

由于Java是虚拟机语言(指需要被编译成虚拟机代码,由虚拟机执行的语言)容易被人反编译,一般核心代码以C/C++编写(将源代码编译为机器码,直接由CPU执行代码),然后把C/C++编写的核心代码编译为一个动态链接库,即文件后缀为".so"的ELF文件,以SO文件的形式供上层JAVA代码调用,以保证安全性。

JNI——Java Native Interface,Native即C/C++,即Java层和Native层的相互调用。

java平台提供了JNI标准(Java Native Interface),建立JNI工程使得Java调用C/C++的函数。

Google为Android的原生开发提供了开发者工具NDK(Native Development Kit),用来编译C/C++项目。ndk编译C/C++源码生成.so文件,ndk还可以讲so文件和java文件一起打包成apk。

java层如何调用native层函数的:

简单一点的:https://www.jianshu.com/p/186954700766

更加详细的:https://bbs.pediy.com/thread-224672.htm
 

AAR相关

在AndroidStudio中,选择新增Module,有新增Android library和Java library,两者的区别Android library Module是生成aar文件,Java library Module生成jar包。

1.首先创建一个 Android library Module.
2.等待 Gradle 构建完毕, 就可以在项目名称/模块名称/build/outputs/aar/中找到这个库项目的 AAR 文件了。
3.如果修改了代码,也可以通过 Build > Make Project 的方式重新生成文件。

AAR包文件结构

AAR 文件的文件扩展名为 .aar,一份 aar 文件其实就是一份 zip 包,和 jar 不同的是,它将一些资源文件、第三方库文件、so 文件(C++)等等都打包在内,而代码文件编译后压缩在classes.jar中。
解压以后aar必然包含以下内容:
/AndroidManifest.xml
/classes.jar
/res/
/R.txt

此外,根据打包的 Library Module 情况不同,打包出来的 AAR 文件也可能包含以下内容:
/assets/
/libs/名称.jar
/jni/abi 名称/名称.so(其中 abi 名称 是 Android 支持的 ABI 之一)
/proguard.txt
/lint.jar

项目中引用AAR包

当其他 Module引用了引用了aar的library module时,也需要在他的build.gradle中加入存放的路径声明。

即如果当前Module需要一个aar包内容(直接还是间接包含),不论aar包是不是在当前Module中,都需要在build.gradle中声明它所在的路径。如果项目中这样的Module比较多,可以在录项目的根build.gradle将所有包含aar包的模块名列出,这样不论是本Module或其他Module都不需要单独配置路径了:

allprojects {   
        repositories {       
                jcenter()       
                google()       
                flatDir {           
                        dirs "../moudle-A/libs,../moudle-B/libs,../moudle-C/libs".split(",")       
                }   
        }
}

AAR包使用注意事项

  1. 使用 Android Studio 打包出来的 AAR ,不会将其依赖的三方库打包进去。

  2. 如果是应用模块(application)引用aar,那么其 minSdkVersion 必须大于或等于 Library Module(aar) 中定义的。AAR 作为相关应用模块的一部分编译,因此,库模块中使用的 API 必须与应用模块支持的平台版本兼容,所以 AAR 中的 minSdkVersion 要尽量的设置低一点。

  3. 资源合并问题。如果 aar 中有资源文件,集成过程中,很容易出现资源冲突,例如两个相同名字的图片什么的。可以 library Module 的 build.gradle 中设置资源前缀resourcePrefix,起的是约束作用,不会自动帮你修改资源的名称。如果我们没有加上前缀,就会报错!

android {
  resourcePrefix "<前缀>"
}

    4. aar 不能使用 assets 原始资源(虽然好像aar解压出来是有assets目录, 但是里面是空的,不知道有没有不是空的例子)


APK的签名

保证了apk包里的文件不能被随意替换。

拿到一个apk包后,如果想要替换里面的一幅图片,一段代码, 或一段版权信息,想直接解压缩、替换再重新打包,是不可能的。需要重新签名才可以。

 

签名和校验过程

校验Verification

1.提取数据data部分,通过一个hash函数加密算法,计算出一个固定长度的hash值,假设其值为A(数字摘要)。

2.提取签名signature部分,通过一个公钥进行解密,得到假设其值为B

3.比较这两个值A值是否和B值一致。如果一致就是通过校验了。

 

上面最主要的两个东西就是加密算法 和 公钥 ,这两个都存在证书Certificate的。证书Certificate签名signature部分都是在签名过程中加上的。数字证书Certificate是身份认证机构(Certificate Authority)颁发的,包含了以下信息:

1)证书颁发机构,证书颁发机构签名,证书绑定的服务器域名,证书版本、有效期——用来确保APK来源是可靠的值得信任的。

2)签名使用的加密算法(非对称算法,如RSA),公钥——下图的Hash<-->Signature之间的加密解密过程。

3) 等等

 

apk中的签名相关文件——META-INF文件夹

apk中个解压出来查看

① MANIFEST.MF:

它的内容是 APK 包中每个文件的名字及每个文件的 SHA1 哈希摘要。

可以通过文本软件打开 MANIFEST.MF,里面列出了apk中所有的文件,以及它们的sha1摘要,摘要字符串是通过base64编码的。

验证,先计算某文件的sha1值,然后base64转成字符串:

windows下cmd计算sha1

certutil -hashfile filename sha1

计算出来的值转base64,通过在线网页转http://tomeko.net/online_tools/hex_to_base64.php

 

② CERT.SF:

这里不一定是CERT.SF,也可能BDMOBILE.SF、NETDISK_.SF等,总之是SF文件。

它保存的是刚刚生成的MANIFEST.MF文件的SHA1 哈希摘要,以及 MANIFEST.MF 文件中每一个条目的SHA1哈希摘要。每一个条目的意思是比如下面是MANIFEST.MF 文件中的一个条目:

Name: AndroidManifest.xml

SHA1-Digest: wOpZJOZ+h0foJSKvIu0yeh8s4pg=

把这个保存到新的文件中(后面要有两个换行符),然后再计算这个文件的sha1摘要,就得到了对应的一个CERT.SF的条目:

Name: AndroidManifest.xml

SHA1-Digest: tbGwGWbAeb3kPk8MYkyk1MQ6kUY=

③ CERT.RSA:这个文件保存了 APK 包的签名和证书的公钥信息。

是二进制文件。

这个文件保存了签名者的证书信息,以及对CERT.SF文件(第② 步)的签名。

整个apk签名是在apk中写入一个“指纹”。指纹写入以后,Apk中有任何修改,都会导致这个指纹无效,Android系统在安装Apk进行签名校验时就会不通过,从而保证了安全性。

 

APK的校验过程

上面说的是签名过程,接下来看apk安装过程是怎样进行签名校验的。校验过程和签名过程刚好相反:

1.首先校验cert.sf文件的签名

计算cert.sf文件的摘要,与通过签名者公钥解密签名得到的摘要(通过cert.rsa得到的签名以及公钥,计算出摘要)进行对比,如果一致则进入下一步;(防止篡改cert.sf)

2.校验manifest.mf文件的完整性

计算manifest.mf文件的摘要,与cert.sf主属性中记录的摘要进行对比,如一致则逐一校验mf文件各个条目的完整性;(防止篡改manifest.mf)

3.校验apk中每个文件的完整性

逐一计算apk中每个文件(META-INF目录除外)的摘要,与mf中的记录进行对比,如全部一致,刚校验通过;(防止篡改apk内容)

4.校验签名的一致性

如果是升级安装,还需校验证书签名是否与已安装app一致。(如果把apk内容和签名信息一同全部篡改这相当于对apk进行了重新签名,在此apk没有安装到系统中的情况下,是可以正常安装的,这相当于是一个新的app;但如果进行覆盖安装,则证书不一证,安装失败。)

apk的签名文件——keystore

我们在对Apk签名时并没有直接指定私钥、公钥和数字证书,而是使用keystore文件。这些信息都包含在了keystore文件中,也就是相当于一个签名文件了。

keystore文件是一个密钥库,也就是说它可以存储多对密钥和证书。keystore的密码是用于保护keystore本身的,一对密钥和证书是通过alias(key别名)来区分的。

ps:keystore文件可以使用AndroidStudio或者其他一些生成比如Androidkiller,或者keytool命令行。

设置了keystore以后,打包后的apk就会包含了签名相关信息——META-INF文件夹

 

1)Unity的默认证书keystore文件

unity没有设置过证书打出来的apk也是包含签名的。
查看在playersetting里选择了Use Existing Keystore,默认选的是unsigned(debug)的。

那证书文件在哪里呢?windows下是在:C:\Users<用户名>.Android\debug.keystore。mac机也是在\Users<用户名>.Android下不要默认是隐藏文件夹(用command+shift+.显示出来就能看到)

 

使用keytool工具在控制台输入查看该密钥的信息(这个key的密码是:android

keytool -list -keystore debug.keystore

keytool -list -v -keystore xxx.keystore -storepass 密码

ps:keytool 是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。

(在JDK 1.4以后的版本中都包含了keytool 这一工具,它的位置为%JAVA_HOME%\bin\keytool.exe)

Java KeyStore 生成方式(后面会介绍keytool工具,jdk自带的keytool):

【生成】证书库
keytool -genkey -v -keystore strange.keystore -alias strange -keyalg RSA -keysize 2048 -validity 10000

【查看】证书库
keytool -list -v -keystore  {path2jks,证书的路径}  -storepass “pass"

keytool -genkeypair  生成证书命名
-alias dishui    别名
-keyalg "RSA"   加密方式
-keystore "name"  输出的证书名
-storepass 123456  密码

2)gradle中指定keystore文件

gradle会指定签名文件配置:

signingConfigs {

    debug {

        keyAlias 'e'

        keyPassword ''

        storeFile file('e.keystore')

        storePassword ''

    }

}

3)androidstudio中

 

签名过程的代码实现

具体过程可参考apksigner源码

public static void main(String[] args) {
    ......
    //生成MANIFEST.MF文件,遍历apk的所有文件,计算除META-INF目录下的
    //.SF/.RSA/.DSA文件外所有文件的摘要。
    JarEntry je;
    Manifest manifest = addDigestsToManifest(inputJar);
    // MANIFEST.MF
    je = new JarEntry(JarFile.MANIFEST_NAME);
    je.setTime(timestamp);
    outputJar.putNextEntry(je);
    manifest.write(outputJar);

    // 生成CERT.SF文件
    je = new JarEntry(CERT_SF_NAME);
    je.setTime(timestamp);
    outputJar.putNextEntry(je);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    //计算MF文件摘要,及MF相应条目的摘要
    writeSignatureFile(manifest, baos);
    //计算SF文件的摘要
    byte[] signedData = baos.toByteArray();
    outputJar.write(signedData);

    // 生成CERT.RSA
    // 对SF文件的摘要(signedData)进行签名,将证书信息一同写入RSA文件中
    je = new JarEntry(CERT_RSA_NAME);
    je.setTime(timestamp);
    outputJar.putNextEntry(je);
    writeSignatureBlock(new CMSProcessableByteArray(signedData),
    publicKey, privateKey, outputJar);
    outputJar.close();
    ......
}

Android APK的反编译方法

在apk中的AndroidManifest.xml是经过压缩的,可以通过AXMLPrinter2工具解开,具体命令为:

java -jar AXMLPrinter2.jar AndroidManifest.xml

Android模拟器中提供了一个dex文件的反编译工具,dexdump。

用法为首先启动Android模拟器,把要查看的dex文件用adb push上传的模拟器中,然后通过adb shell登录,找到要查看的dex文件,执行dexdump xxx.dex。(没试过)

方法一:命令行工具apktool、dex2jar、jd-gui

https://blog.csdn.net/jw_66666/article/details/51930808 这篇文章最后有上述工具的下载地址

apktool工具:获得图片与XML资源

反编译工具在apktool目录下,解压得到3个文件:aapt.exe,apktool.bat,apktool.jar

将需要反编译的APK文件放到该目录下,打开命令行界面 ,定位到apktool文件夹,输入以下命令:

apktool.bat d XXXX.apk foldernameAAA

在foldername下面就是反编译完成的,其中的xml都是正常显示不是乱码的,跟直接改zip解压出来的不一样。

  • 1):运行上述命令如果出现以下错误

Exception in thread “main” brut.androlib.AndrolibException: Could not decode arsc file

Apktool的bug使用其他版本的Apktool,我在使用apktool_2.3.3.jar中遇到了这个问题,使用如apktool_2.3.1.jar是好的,如果你也遇到了这个问题不妨换个Apktool版本试一下。apktool下载地址https://ibotpeaches.github.io/Apktool/

  • 2):将反编译完的文件重新打包成apk,比如修改了某些东西

输入apktool.bat b test(你编译出来文件夹)便可。新的apk会生成在dist文件夹里。

apktool.bat   b foldernameAAA
  • 3):重新打包的apk需要重新签名

签名工具在auto-sign目录下,把apk放到下面(AAA.apk是输入apk,BBB.apk是签名以后的输出apk)

java -jar signapk.jar testkey.x509.pem testkey.pk8 AAA.apk BBB.apk

其中.pem和.pk8都是证书相关的。也可以用keytool工具自行制作一个证书进行签名。

dex2jar工具:将classes.dex转换成jar文件

反编译dex在dex2jar和jd-gui目录下

首先将要反编译的APK后缀名改为.rar或则 .zip,并解压,得到其中的classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的classes.dex放到之前解压出来的工具dex2jar文件夹内,

再在命令行下定位到dex2jar.bat所在目录,输入

dex2jar.bat classes.dex:

可以看到在该目录下会生成一个classes_dex2jar.jar的文件。

jd-gui工具:查看jar包中的Java代码

打开工具jd-gui文件夹里的jd-gui.exe,用该工具打开之前生成的classes_dex2jar.jar文件,便可以看到源码了。

如果是被混淆(https://blog.csdn.net/fengyuzhengfan/article/details/39187989)过的代码,类文件名称以及里面的方法名称都会以a,b,c....之类的样式命名。

用这个工具查看unity提供的android插件classes.jar
C:\unity5\Unity**Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes\classes.jar其中的UnityPlayer类和UnityPlayerActivity可以看看:

image.png

image.png

 

另外有一篇关于mac的:反编译Android APK详细操作指南[ApkTool,dex2jar,JD-GUI] for Mac

https://blog.csdn.net/fengyuzhengfan/article/details/80286704

使用AndroidKiller反编译源码,修改后重新打包签名记录:
https://blog.csdn.net/u013440413/article/details/103726317
AndroidKiller编译CreateProcess error=206 文件名扩展太长:
https://blog.csdn.net/undiif123/article/details/88096631

 

方法二,可视化的反编译工具androidkiller

https://blog.csdn.net/iamlegendary/article/details/79468400

使用androidkiller看反编译,其中的smali文件夹中内容,其实就是classes.dex反编译过来的smali文件

如果要看java源码,那么就跟方法一中通过dex2jar,然后gui去看jar的原始代码。


一个简单的例子,可以看到app的组件情况

一个简单的例子,可以看到app的组件情况

 

方法三

Android 中的拿来主义(编译,反编译,AXMLPrinter2,smali,baksmali)!

https://blog.csdn.net/Android_Tutor/article/details/5724435

其中smali和baksmali下载不到。

大概就是通过直接改后缀解压,然后AXMLPrinter2可以查看其中乱码的xml。

baksmali 用来将classes.dex反编译成 .smali

smali用来将 .smali 打包成 classes.dex

对反编译以后的包进行修改进行二次打包以后,需要进行签名才能使用。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ivy_0709

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值