日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

直接在apk中添加资源的研究

發(fā)布時(shí)間:2023/12/2 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 直接在apk中添加资源的研究 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文?http://blog.votzone.com/2018/05/12/apk-merge.html

之前接手過一個(gè)sdk的開發(fā)工作,在開發(fā)過程中有一個(gè)很重要的點(diǎn)就是盡量使用代碼來創(chuàng)建控件,資源文件最好放到assets目錄下,如果必須使用res資源,需要通過?getResources().getIdentifier("activity_splash","layout", getPackageName())?這種方式來獲取資源id,而不能直接通過R文件獲取。

今天就來研究一下這個(gè)問題。

一、lib項(xiàng)目中r文件中資源唯一標(biāo)志為static變量

一般的app項(xiàng)目中自動(dòng)生成的R文件為常量,而在library項(xiàng)目中為變量。根據(jù)Android官方文檔,在android 14 之后添加的這一特性,之前編譯后的lib項(xiàng)目中是常量,之后的為static 變量。 目的是為了在資源沖突時(shí)能夠修改資源唯一值。 如圖在library項(xiàng)目中,自動(dòng)生成的R文件如下

有一個(gè)需要關(guān)注的點(diǎn)是R文件是java 代碼,在build時(shí)會(huì)生成.class文件并添加到dex中。 因?yàn)镽文件中的常量值僅僅受編譯器控制,在lib發(fā)布之后添加到j(luò)ar包中的.class并不會(huì)受到當(dāng)前編譯器的影響。而通常lib發(fā)布之后要給第三方使用。

看一下反編譯后的apk

反編譯后查看mylib 下對(duì)應(yīng)的R文件smali代碼,可見其值又被設(shè)置為final(常量)了。 因此我們可以知道編譯器在生成apk時(shí)雖然沒有l(wèi)ib的java代碼可以重置和修改,但是在將jar轉(zhuǎn)化為dex時(shí)可以轉(zhuǎn)換為常量。 轉(zhuǎn)化為常量后并不影響其使用, 如圖在lib中使用layout資源的反編譯代碼

我們可以看出使用靜態(tài)常量可以在生成apk時(shí)動(dòng)態(tài)修改其指定的值。

如果是常量,編譯后v0的值將直接使用常量值,這樣修改R.class文件中的值將沒有意義。例如在app中反編譯后代碼如下:

二、從反編譯后代結(jié)構(gòu)中查看資源對(duì)應(yīng)問題

可以看到,反編譯后的代碼與我們寫的java代碼基本是一一對(duì)應(yīng)的,那么問題來了,Android是怎么通過一個(gè)id值來找到需要的資源呢?通過分析Android源碼我們當(dāng)然可以找出過程,但是分析apk反編譯后的結(jié)構(gòu)可以給我們更直接的思路。

在res/values/文件夾下有個(gè)public.xml文件,其中每行有三對(duì)值,分別為type、name、id?通過分析我們可以直接得出結(jié)論:?public.xml中的對(duì)應(yīng)關(guān)系直接關(guān)系到哪個(gè)id找那個(gè)資源。

三、添加資源

Unity3d和cocos2d引擎有自己一套方式來添加資源id,假如我們自己搞一個(gè)游戲,又想為其添加一些java代碼和資源該怎么操作?

根據(jù)之前的分析我們可以設(shè)計(jì)如下測(cè)試方案

  • 假定我們要添加代碼的apk為targetapp,我們編寫一個(gè)叫mergelib的apk,然后將mergelib中資源和代碼添加到targetapp中。
  • 在編寫mergelib時(shí),使用?getResources().getIdentifier("activity_splash","layout", getPackageName())?的方式獲取資源id;
  • 通過apktool反編譯代碼,將資源文件復(fù)制到要加入的目標(biāo)apk中;
  • 將mergelib的public.xml文件中需要的資源項(xiàng)添加到targetapp中;
  • 編譯并簽名測(cè)試。
  • 根據(jù)如上實(shí)驗(yàn)我們可以確定這樣的操作是可行的。測(cè)試流程如下:

    需要的資源:

    • targetapp- 目標(biāo)app, 在這里代表游戲
    • mergelib- 要將其中包含資源的代碼合并進(jìn)去
      mergelib 中對(duì)資源通過getIdentifier()的方式使用: 例如設(shè)置啟動(dòng)頁Activity中的ContentView的設(shè)置
    int id = getResources().getIdentifier("activity_splash","layout", getPackageName());
    setContentView(id);

    我們的目標(biāo):為targetapp添加一個(gè)啟動(dòng)頁,啟動(dòng)頁代碼在mergelib中編寫。

    執(zhí)行流程

  • 修改targetapp中AndroidManifest.xml文件?
    1) 將SplashActivity 的聲明添加進(jìn)去?
    2) 修改啟動(dòng)Activity

  • 復(fù)制需要的代碼進(jìn)入targetapp:?
    復(fù)制mergelib中SplashActivity的代碼并修改啟動(dòng)MainActivity的啟動(dòng)代碼 如圖

  • 復(fù)制資源
    1) 將res/anim 下alpha.xml復(fù)制到target
    2) 將res/layout 下 spalsh.xml復(fù)制到target 下

  • 修改ids?
    將 res/values/ids.xml 中多出來的行復(fù)制到 對(duì)應(yīng)ids.xml文件中

    如圖, 本例中僅有一個(gè)id 即ImageView的id, 因此將該行復(fù)制到targetapp 中對(duì)應(yīng)的ids.xml文件中即可 位置不重要

  • 修改public.xml文件 mergelib Splash中用到了?anim,?layout,?id, 并且間接用到了?mipmap,因此這些對(duì)應(yīng)的值都需要添加到targetapp。觀察public.xml的文件結(jié)構(gòu),可以發(fā)現(xiàn)如下特點(diǎn):?
    1) 所有同類型(type相同)的id連續(xù)?
    2) 同類型的id 前4字節(jié)相同, 如下圖 anim 的前四字節(jié)0x7f01 與 attr 不同

    3) 所有id唯一?
    根據(jù)以上三個(gè)特點(diǎn),我們將多出來的id添加到target為了保證唯一且方便修改,我們做了如下替換(右側(cè)為target)

  • 一切就緒,編譯并安裝

  • 四、工具化處理public.xml的替換過程

    上述手動(dòng)測(cè)試僅僅只有一個(gè)資源id的情況,假如我們加入了一個(gè)support包或者其他一些包含資源的包,那么資源數(shù)量將會(huì)增加到幾百個(gè),這樣的話手動(dòng)添加肯定是不行的,我們需要一個(gè)腳本工具來實(shí)現(xiàn)。

    腳本接收兩個(gè)public.xml格式的文本,并輸出一個(gè)合并版本。 其中targetapp中的id值是不可變得,在遇到id沖突時(shí),我們改變mergelib的public.xml。

    1) 復(fù)制mergelib的public文件為mergeid.xml?

    2) 復(fù)制target app 的public 并命名為oriid.xml


    3) 將mergeid.xml 和oriid.xml 放到RIDreset.py同目錄下, 運(yùn)行py腳本

    ?

    4) 出現(xiàn) oriid.xml_ 文件, 即生成的合并文件

    案例及腳本

    https://github.com/votzone/DroidCode/tree/master/VotAndroid/Mergeapp

    轉(zhuǎn)載于:https://www.cnblogs.com/fog2012/p/apk_merge.html

    總結(jié)

    以上是生活随笔為你收集整理的直接在apk中添加资源的研究的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。