美文网首页
命令行编译生成APK

命令行编译生成APK

作者: Parallel_Lines | 来源:发表于2018-11-27 21:17 被阅读0次

本文将介绍如何在Mac系统下命令行编译生成一个简单的Apk程序。

准备工作

配置环境变量

aapt、dx、android.jar等工具或jar包本文采用SDK-26版本。

为了在mac系统下方便调用命令,需要添加环境变量:

命令 默认目录
adb ~/Library/Android/sdk/platform-tools
aapt、dx ~/Library/Android/sdk/build-tools/26.0.2
android.jar ~/Library/Android/sdk/platforms/android-26/android.jar
sdklib-26.0.0-dev.jar ~/Library/Android/sdk/tools/lib/sdklib-26.0.0-dev.jar

这里只添加了adb、aapt、dx到环境变量中,jar包直接使用全路径调用。环境变量进入控制台如下配置:

//1.打开变量文件
cd ~
vim ~/.bash_profile
//2.增加如下变量
export PATH=${PATH}:~/Library/Android/sdk/platform-tools adb
export PATH=${PATH}:~/Library/Android/sdk/build-tools/26.0.2
//使用:wq!保存退出
//3.刷新变量文件
source .bash_profile
//4.重启控制台生效

创建项目

这里创建一个小型测试项目,用于生成apk。文件目录如下:

test-app
-- AndroidManifest.xml
-- gen
-- out
-- res
---- layout
------ activity_main.xml
---- mipmap-xxhdpi
------ ic_launcher.png
---- values
------ strings.xml
-- src
---- java
------ MainActivity.java

这里创建的文件目录完全是自定义的,你可以根据需要创建符合自己需求的目录结构。我这里的目录主要有如下用途:

目录 用途
gen 存放后续生成的R.java文件
out 存放后续生成的class、dex、apk文件
res 存放项目资源文件
src 存放代码文件

这里AndroidManifest.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dixon.test">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java代码如下:

package com.dixon.test;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="com.dixon.test.MainActivity">

    <TextView
        android:gravity="center"
        android:text="Hello My App"
        android:background="#FFFFFF"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

可以看出这只是一个单页面的简单项目,需要注意包名为com.dixon.test

命令行编译

为了方便操作,这里cd到项目根目录下。

生成R.java文件

1

aapt package -f -m -M AndroidManifest.xml -I ~/Library/Android/sdk/platforms/android-26/android.jar -S res/ -J gen/

aapt各参数意义如下:

参数 意义
-f 如果编译出来的文件已经存在,强制覆盖。
-m 使生成的包的目录放在-J参数指定的目录。
-J 指定生成的R.java的输出目录
-S res文件夹路径
-A assert文件夹的路径
-M AndroidManifest.xml的路径
-I 某个版本平台的android.jar的路径
-F 具体指定apk文件的输出

此时项目gen目录下会出现以下几级目录:

gen/com/dixon/test/R.java

正好对应包名+文件,其中R.java代码如下:

package com.dixon.test;

public final class R {
    public static final class attr {
    }
    public static final class layout {
        public static final int activity_main=0x7f030000;
    }
    public static final class mipmap {
        public static final int ic_launcher=0x7f020000;
    }
    public static final class string {
        public static final int app_name=0x7f040000;
    }
}

生成class文件

这段命令会将java代码(包括R.java)编译为class文件输出到out目录下。

2

javac -encoding GBK -bootclasspath ~/Library/Android/sdk/platforms/android-26/android.jar -d out/ gen/com/dixon/test/*.java src/java/*.java

命令执行完毕后,可以看到如下新生成目录:

out/com/dixon/test/xxx.class

生成dex文件

这段命令会将class文件转为dex文件。
需要注意的是:这里class目录只会识别包括包名在内的全文件路径。即--output的第二个参数不能为out/com/dixon/test,而应该是out/,否则会报路径错误。

3

dx --dex --output=out/classes.dex out/

打包资源文件

4

aapt package -f -M AndroidManifest.xml -S res/ -I ~/Library/Android/sdk/platforms/android-26/android.jar -F out/Test.ap_

生成apk

下面命令将生成apk文件,并将资源文件、dex文件加入到apk中。

5

java -cp ~/Library/Android/sdk/tools/lib/sdklib-26.0.0-dev.jar com.android.sdklib.build.ApkBuilderMain out/Test.apk -v -u -z out/Test.ap_ -f out/classes.dex 

过去可以使用apkbuilder生成apk,目前apkbuidler已经废弃并且不能再用了。
这里使用如上方式生成apk,命令行仍会提示过期,但是实测可用(2018.11.25)。
如果有哪位大神知道不过期的apk生成命令,欢迎留言!

签名

这里为方便,直接使用Android Studio自带的debug签名文件进行签名。

6

jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android out/Test.apk androiddebugkey

安装

经过上述步骤,就可以安装out/目录下生成的apk文件了。

adb install ~/Dixon-Project/test-app/out/Test.apk

可以看到这个apk文件只有12k不到。

截图.png

总结

本文只是很粗浅的利用命令行生成一个简单的apk,旨在初探apk的原理。

上述流程虽然走通了,但是在后续扩展的探索中,遇到了目前无法解决的问题:

我最初的AndroidManifest.xml是从一个项目中拷贝出来的,它设置了主题为AppTheme,其中AppTheme继承自Theme.AppCompat.Light.DarkActionBar,它来自support-v7包。

于是问题来了,我在第一步生成R.java的时候,控制台编译不通过并做如下提示:

res/values/styles.xml:4: error: Error retrieving parent for item: No resource found that matches the given name 'Theme.AppCompat.Light.DarkActionBar'.

res/values/styles.xml:8: error: Error: No resource found that matches the given name: attr 'colorAccent'.

res/values/styles.xml:6: error: Error: No resource found that matches the given name: attr 'colorPrimary'.

res/values/styles.xml:7: error: Error: No resource found that matches the given name: attr 'colorPrimaryDark'.

生成R.java作为第一步,找不到资源很正常,因为此时还没有引入support-v7包。于是我意识到生成R.java的命令行一定有引入jar包的参数。但是经过多方查询,目前只找到一个类似的命令:

aapt package -m -J gen/ -M AndroidManifest.xml -S res/ -I ~/Library/Android/sdk/platforms/android-26/android.jar -I ~/Dixon-Project/test-app/lib/appcompat-v7-27.1.1-sources.jar

这个命令亲测无效

如果有哪位大神知道解决方案麻烦告知,不胜感激!

参考文章:
https://www.jianshu.com/p/d2dc78eb7bd9
https://blog.csdn.net/zhangqiang_0/article/details/68068141
https://jingyan.baidu.com/album/14bd256e21b415bb6d26128b.html?picindex=2

相关文章

  • 命令行编译生成APK

    本文将介绍如何在Mac系统下命令行编译生成一个简单的Apk程序。 准备工作 配置环境变量 aapt、dx、andr...

  • Android App打包

    最后生成apk文件 ionic cordova build android ----命令行打包生成apk文件 2....

  • 反编译apk,修改登录成功

    要实现的功能是,登录成功。 打开Apk反编译工具,将上一篇中生成的apk拖入其中,点击 反编译apk。 将apk使...

  • 2018-08-24学习笔记

    手把手教你使用Android studio生成正式签名的APK文件 9.5.3 Android Apk 反编译 &...

  • android代码混淆详解

    1、前言 在对apk进行打包时,如果不对apk进行混淆和加固,生成的apk可以轻松的进行反编译,所以对apk代码进...

  • ndk编译生成so

    ndk-build编译生成so库 本文讲述使用Android 的ndk-build来编译生成so库,在命令行中编译...

  • APP测试总结

    一、安装、卸载测试 安装、卸载测试主要针对编译后源程序生成的APK安装文件。 主要测试点: 1.生成APK文件在真...

  • Android打包过程

    Android工程 --> 通过编译和打包 --> 生成了apk文件 --> 签名Signing --> 通过ad...

  • Android构建过程

    编译器会讲代码编译成Dex文件,然后打包器会将资源文件和Dex文件以及签名文件打包成apk文件,最后在生成apk之...

  • Android Studio编译输出apk文件修改文件名

    新建一个Android工程,默认编译会生成一个叫app-debug.apk或者叫app-release.apk文件...

网友评论

      本文标题:命令行编译生成APK

      本文链接:https://www.haomeiwen.com/subject/qygnqqtx.html