精华内容
下载资源
问答
  • 1、APK编译主要分以下几步: 编译资源文件

    1、APK编译主要分以下几步:

    编译资源文件:

    主要负责编译XML,图片等一些资源文件。通过aapt工具,生成resources.arsc索引和res文件夹,同时aapt工具还负责把所有的资源文件生成二级制文件,以便程序访问。

    编译java源代码:

    通过javac编译,把所有的.java文件生成.class文件

    生成Dex文件:

    通过dx工具,把所有的.class文件统一生成可供Dalvik虚拟机运行的.dex文件。

    生成APK文件:

    通过apkbuilder把dex和资源文件打包,生成APK文件


    2、反编译

    利用系统的dexdump -d classes.dex > test.txt,这种形式只是生成了smali语言的文档,作用不大。

    apktool+dex2jar+jd_gui来反编译

    (1)首先在http://code.google.com/p/android-apktool/downloads/list

    下载两个文件:apktool1.4.3.tar.bz2 apktool-install-windows-r04-brut1.tar.bz2

    (2)把两个文件夹里的jar包和apktool.bat放到SDK的platform-tools文件夹里。

    (3)命令行执行apktool d E:\XX.apk test,这样就会生成test文件夹,里面的XML格式文件就是源文件。

    (4)下载dex2jar工具,把XX.apk直接解压得到的classes.dex文件放到该文件夹底下,命令行定位到该文件夹,执 行dex2jar classes.dex。结果就会生成一个jar包

    (5)利用工具jd_gui,导入jar包就能看到源代码


    展开全文
  • android apk编译时间获取

    千次阅读 2016-12-01 23:57:08
    android apk编译时间获取本方法只适用于使用android 源码编译环境。有时候我们需要在android应用上获取apk的编译时间,但java编译并不像C、C++那样有相应的宏可以在代码中读取到编译时间。我们可以利用android源码...

    android apk编译时间获取

    本方法只适用于使用android 源码编译环境。

    有时候我们需要在android应用上获取apk的编译时间,但java编译并不像C、C++那样有相应的宏可以在代码中读取到编译时间。我们可以利用android源码编译-linux环境来获取编译时间,然后把获取的时间写到android apk的raw文件中,这样apk启动后就可以通过读取raw文件中的时间来获取编译时间。
    Android源码编译apk需要写Android.mk文件,Android.mk文件中可以执行shell命令,利用shell命令获取编译时的时间并且写入到apk资源文件夹res/raw/下的文件即可。

    Android.mk:

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    #这里就是把date命令格式化输出到资源文件res/raw/date下的###
    $(shell date "+%Y-%m-%d %H:%M:%S" > $(LOCAL_PATH)/res/raw/date)
    LOCAL_MODULE_TAGS := optional
    ##end#####
    
    LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
    
    LOCAL_PACKAGE_NAME := MiptFactoryTest
    LOCAL_CERTIFICATE := platform
    
    LOCAL_OVERRIDES_PACKAGES := Home
    
    include $(BUILD_PACKAGE)
    
    include $(CLEAR_VARS)
    
    include $(BUILD_MULTI_PREBUILT)

    java中通过下面函数读取raw文件获取编译时间:

    public String getBuildTime(){
            String content = null;
            Resources resources=mContext.getResources();
            InputStream is=null;
            try{
                is=resources.openRawResource(R.raw.date);
                byte buffer[]=new byte[is.available()];
                is.read(buffer);
                content=new String(buffer);
                Log.i(TAG, "read:"+content);
            }
            catch(IOException e)
            {
                Log.e(TAG, "write file",e);
            }
            finally
            {
                if(is!=null)
                {
                    try{
                        is.close();
                    }catch(IOException e)
                    {
                        Log.e(TAG, "close file",e);
                    }
                }
            }
           return content;
        }
    展开全文
  • APK编译流程-详解AAPT

    2019-09-03 14:52:47
    APK编译流程-详解AAPT aapt2 aapt2(Android Asset Packageping Tool)是用来 编译和打包 app资源文件的构建工具。aapt2 解析、索引并将资源编译成适合Android 平台的二进制格式. aap2将资源文件的编译分为2个步骤: ...

    APK编译流程-详解AAPT

    aapt2

    aapt2(Android Asset Packageping Tool)是用来 编译和打包 app资源文件的构建工具。aapt2 解析、索引并将资源编译成适合Android 平台的二进制格式.

    aap2将资源文件的编译分为2个步骤:

    编译阶段:
    解析资源文件并生成扩展名为.flat的中间二进制文件

    **链接阶段: **
    将编译阶段生成的所有中间文件(资源表、二进制XML文件和处理过的PNG文件)合并到一个APK中,此外在此资源还可以生成其他辅助文件,如R.java文件和ProGurad规则文件。 此时生成的APK文件并不包含DEX文件。

    aapt只有一个编译过程,aapt2将资源编译分为2个部分可以实现资源文件的增量编译。

    aapt2 使用示例

    dump

    可以使用dump命令查看apk文件内的resouces信息

    aapt2 dump <xx.apk>
    

    编译命令

    compile: 编译res文件夹下的资源文件生成 flat文件

    aapt2 compile --dir <res-path> -o res.zip  -v
    

    参数含义:
    –dir :资源文件路径,编译整个文件夹下的资源文件
    -o: 指定文件
    -v: verbose logging

    增量编译,及只重新编译变化的资源文件

    aapt2 compile <file-path> -o <outputPath>
    

    参数含义:
    -o:因为这里是指定文件编译,所以-o 标识flat文件保存的文件夹

    链接命令

    link: 链接资源文件 及AndroiedManifest.xml 生成只包含资源的apk文件,并生成R类

    aapt2 link res.zip \
    -I ~/Library/Android/sdk/platforms/android-28/android.jar \
    --java package/ \
    --manifest app/src/main/AndroidManifest.xml \
    -o res.apk -v
    

    编译过程中,可能出现 style/Theme.AppCompat.Light.DarkActionBar not found.这是因为,我们引用的第三方库的资源并没有被编译,因此出现资源找不到的问题。而使用gradle 编译时,会合并所有资源统一进行编译,因此不会出现类型问题.
    此时,可将对第三方资源的引用去除,改为只用使用android sdk内的资源,比如将主题改为 
    <style name=“AppTheme” parent=“android:Theme.Holo.Light.DarkActionBar”>

    aapt2 产物解析

    aapt2编译后的apk文件包含哪些内容:

    image.png

    一个完整的aapt2编译后的压缩文件应该包含以下资源

    1.res文件夹内的图片及xml资源(只包含图片、布局) 
    2.assets文件夹
    3.二进制AndroidManifest.xml
    4.资源索引表 resources.arsc
    5.R类文件

    Demo中使用的资源不包含 assets 文件,在实际开发过程,在link 阶段,可以通过-A指定assets路径。

    R类文件

    在aapt的编译过程中,除了assets资源外,其他的资源(string、color、layout等)都会被赋予一个资源ID.
    资源的ID常量值保存在R类文件中供在开发阶段使用。

    /* AUTO-GENERATED FILE. DO NOT MODIFY.
     *
     * This class was automatically generated by the
     * aapt tool from the resource data it found. It
     * should not be modified by hand.
     */
    
    package com.hellobike.androidbuildintroduce;
    
    public final class R {
      public static final class color {
        public static final int colorAccent=0x7f010000;
        public static final int colorPrimary=0x7f010001;
        public static final int colorPrimaryDark=0x7f010002;
      }
      public static final class drawable {
        public static final int ic_launcher_background=0x7f020001;
        public static final int ic_launcher_foreground=0x7f020002;
      }
      public static final class layout {
        public static final int activity_main=0x7f030000;
      }
      public static final class mipmap {
        public static final int ic_launcher=0x7f040000;
        public static final int ic_launcher_round=0x7f040001;
      }
      public static final class string {
        public static final int app_name=0x7f050000;
      }
      public static final class style {
        /**
         * Base application theme.
         */
        public static final int AppTheme=0x7f060000;
      }
    }
    

    id组成

    资源Id为16进制8位 int值,组成为ppttdddd,前2位表示packageId,第3-4位表示资源类别(resouceTypeId),后4位标识该资源类别下的资源ID(resouceId)。

    其中系统的packageID为[01-7f)之间,应用程序的packageId默认为7f。 typeId 没有明细的映射关系,Id的值的分配为aapt2在处理过程中 根据资源类别被处理的先后从1开始递增1分配。resouceId同理,不过是从0开始递增的

    aapt2中资源ID分配的源码

    resources.arsc文件详解

    在开发阶段,我们可以通过aapt生成的R类中的id 引用具体的资源,而 resources.arsc文件是一个资源索引表,供在程序运行时根据id索引到具体的资源。这里我们不分析运行时索引资源的过程,只分析reousce.arsc中的内容结构。

    直接去分析二进制的resources.arsc会比较困难,这里开发者可以借助AS 自带的Anaylyze Apk来分析 resouces.arsc中的内容。开发者可以直接将一个apk文件拖到AS中,AS会自动使用Anaylyze Apk工具打开

    image.png

    结合aapt2工具的源代码,可以看出资源索引表的内容大概包含以下部分

    1.ResouceTablePackage
    红色圈选的部分列出了这个资源索引表包含的package,一般一个应用只会有一个package,并且这个package的id默认为7f.

    class ResourceTablePackage {
     public:
      Maybe<uint8_t> id;
      std::string name;
    
      std::vector<std::unique_ptr<ResourceTableType>> types;
    
      ResourceTablePackage() = default;
      ResourceTableType* FindType(ResourceType type);
      ResourceTableType* FindOrCreateType(const ResourceType type);
    
     private:
      DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
    };
    
    

    2.ResourceTableType
    一个package关联很多resouceTypes,比如你的应用下包含了xml、stirng、layout、则这里就会有对应的type,每个type之下关联所属类型的ResouceEntry

    /**
     * Represents a resource type, which holds entries defined
     * for this type.
     */
    class ResourceTableType {
     public:
      /**
       * The logical type of resource (string, drawable, layout, etc.).
       */
      const ResourceType type;
    
      /**
       * The type ID for this resource.
       */
      Maybe<uint8_t> id;
    
      /**
       * Whether this type is public (and must maintain the same
       * type ID across builds).
       */
      Symbol symbol_status;
    
      /**
       * List of resources for this type.
       */
      std::vector<std::unique_ptr<ResourceEntry>> entries;
    
      explicit ResourceTableType(const ResourceType type) : type(type) {}
    
      ResourceEntry* FindEntry(const android::StringPiece& name);
      ResourceEntry* FindOrCreateEntry(const android::StringPiece& name);
    
     private:
      DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
    };
    
    

    3.Entry
    一个ResourceEntry就是一个资源项,一个资源项根据不同的配置可能会有不同的值,比如string entry可以设置多国语言,layout entry可以根据设备分辨率设置不同的布局
    **

    /**
     * Represents a resource entry, which may have
     * varying values for each defined configuration.
     */
    class ResourceEntry {
     public:
      /**
       * The name of the resource. Immutable, as
       * this determines the order of this resource
       * when doing lookups.
       */
      const std::string name;
    
      /**
       * The entry ID for this resource.
       */
      Maybe<uint16_t> id;
    
      /**
       * Whether this resource is public (and must maintain the same entry ID across
       * builds).
       */
      Symbol symbol_status;
    
      /**
       * The resource's values for each configuration.
       */
      std::vector<std::unique_ptr<ResourceConfigValue>> values;
    
      explicit ResourceEntry(const android::StringPiece& name) : name(name.to_string()) {}
    
      ResourceConfigValue* FindValue(const ConfigDescription& config);
      ResourceConfigValue* FindValue(const ConfigDescription& config,
                                     const android::StringPiece& product);
      ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config,
                                             const android::StringPiece& product);
      std::vector<ResourceConfigValue*> FindAllValues(const ConfigDescription& config);
      std::vector<ResourceConfigValue*> FindValuesIf(
          const std::function<bool(ResourceConfigValue*)>& f);
    
     private:
      DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
    };
    
    

    4.ResouceConfigValue
    reouceConfigValue即资源项具体的值。
    **

    class ResourceConfigValue {
     public:
      /**
       * The configuration for which this value is defined.
       */
      const ConfigDescription config;
    
      /**
       * The product for which this value is defined.
       */
      const std::string product;
    
      /**
       * The actual Value.
       */
      std::unique_ptr<Value> value;
    
      ResourceConfigValue(const ConfigDescription& config, const android::StringPiece& product)
          : config(config), product(product.to_string()) {}
    
     private:
      DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
    };
    

    另外也可以使用aapt2命令查看resouces.arsc文件的具体内容

    aapt2 dupms <xx.apk>
    

    这里我直接将输出内容保存到txt中,并使用sublime查看

    aapt2 dumps <xx.apk> >> ./outputs.txt
    

    image.png

    可以看到输出的内容和我们在AS中看到的内容其实是一样的,只不过这里是文本格式标识,结构采用缩进的方式。

    总结

    1. Android开发中,我们使用的R类 由aapt工具生成,
    2. AndroidManifest文件会被优化被转换成二进制格式存储
    3. aapt工具生成arsc文件是android apk资源文件的索引表
    展开全文
  • Android 获取APK编译时间

    千次阅读 2017-08-15 17:31:27
    由于项目中,需要显示APK编译的时间,方便用户知道APK时什么时候更新的。用手动的方式的话,经常会忘记!现在知道AS在build.gradle中可以定义变量,在此记录一下。在build.gradle定义时间变量:defaultConfig { .......

    由于项目中,需要显示APK编译的时间,方便用户知道APK时什么时候更新的。用手动的方式的话,经常会忘记!现在知道AS在build.gradle中可以定义变量,在此记录一下。

    在build.gradle定义时间变量:

    defaultConfig {
    ....
    buildConfigField "String", "BUILD_TIME", getDate()
    }
    String getDate() {
        Date date = new Date();
        return date.format("yyyy-MM-dd hh:mm:ss", TimeZone.getTimeZone("UTC"));
    }
    ...

    然后在代码中获取BUILD_TIMESTAMP的值:

    String buildTime = BuildConfig.BUILD_TIME
    展开全文
  • APK编译流程-DEX文件

    千次阅读 2019-09-03 14:54:13
    APK编译流程-DEX文件 DEX 文件是什么 我们知道,虽然我们的应用程序一般由java编写,但最终由Dalivk虚拟机执行的并不是java字节码,而是dalivk字节码。 class字节码最终被编译成class文件,而dalivk 字节码最终被...
  • 原文地址:apk编译/反编译工具baksmali和smali用法作者:elshellsmali:An assembler/disassembler for Android's dex format smali 下载地址:http://code.google.com/p/smali/downloads/list 用法如下:首先把...
  • apk编译/反编译工具baksmali和smali用法

    千次阅读 2015-08-14 18:39:02
    apk编译/反编译工具baksmali和smali用法 (2012-12-08 13:55:41) 转载▼ 标签: 下编 所在 文件夹 工具 杂谈 分类:Android smali:Anassembler/disassembler for Android's dexformat smali 下载地址:...
  • apk 编译和反编译

    2014-03-14 23:20:08
    最近做一个用应需要用到apk编译和反编译,网上各种搜博客,但疼无比,但是终于还是完成了。 还是先上博客把。 优秀的博客:  1.点击打开链接 补充: 文章的第二部分:jar文件转为dex文件里面 dx和...
  • apk项目是如何编译的? 总结: 我们可以通过mm showcommands命令查看编译过程。今天下载了小米的Notes,便签,没有Android.mk...接下来我们就按顺序看看apk编译过程中的流程。 1、首先编译项目下的资源文件,生成R.java
  • Android程序apk编译、打包、签名

    千次阅读 2012-06-19 17:59:18
    今天花了几个小时,并在网上查资料,终于把apk编译签名打包整个流程弄清楚了。 PS:因为android程序一共有三种方式完成编译打包任务,参看连接:Android编译,打包、签名详细教程 我采用的是在Eclipse+ADT方式下,...
  • 本文基于AOSP-7.1.1-R9源码分析,源码可以参见build/+/android...对于刚开始接触系统开发的开发者来说,经常会使用如下命令编译apk或者系统固件。source build/envsetup.sh; lunch make -j8 or mmm packages/app/S...
  • APK编译反编译相关

    2013-09-16 18:52:32
    APK编译 http://blog.csdn.net/ithomer/article/details/6727581 http://my.eoe.cn/sandking/archive/19772.html 一.反编译源代码 $ mv a.apk a.zip //解压a.zip生成classes.dex...
  • android apk编译打包过程

    万次阅读 2018-01-22 14:30:59
    Android安装包的后缀都是.apkapk是Android Package的缩写。 解压apk文件后包含AndroidManifest.xml、assets目录、classes.dex(还可能有 classes2.dex,classes3.dex...classesN.dex)、lib目录、META-INF目录、res...
  • 例如自定义名称+当前时间来命名: android { ... android.applicationVariants.all { variant -> variant.outputs.all { outputFileName = "Test-${releaseTime()}.apk" } } } def r...
  • Android Apk编译的apk安装失败解决

    千次阅读 2018-07-05 10:16:34
    一: 如果直接拷贝到手机进行安装 提示...2. adb install (apk在PC上的路径/)*.apk (将apk文件上传到了模拟器自带操作系统的data/app目录下了) 3. Android模拟器界面中浏览打开apk应用程序 如需了解其它问题方法 :  ...
  • 今天有同事问我使用Android Killer 将apk编译出错,心里想着这得是有dex验证?结果报错信息如下: 显然不是dex验证,不过看报错信息,应该和kotlin有关,初步猜想反编译后破坏了其协程加载机制. 简单了解了下...
  • 总结记录下这两天的主要学习成果,其中借鉴了网上很多资料,终于成功打包出测试apk文件并运行。 准备知识挺多的(也是自己太菜了): 1.Android中apk与dex的区别 1. *.apk文件 APK是Android Package的...
  • 转自:《Android Studio动态自定义编译输出的apk文件名》 android { ... android.applicationVariants.all { variant -&amp;gt; variant.outputs.all { outputFileName = &quot;${variant....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,120
精华内容 8,048
关键字:

apk编译