posts - 79, comments - 75, trackbacks - 0, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

公告

Android的apk编译和第三方jar包的使用

Posted on 2012-01-13 22:11 sinojelly 阅读(...) 评论(...) 编辑 收藏
Android的apk编译和第三方jar包的使用
 
eclipse增加 User Library方式,如果该.jar不在eclipse项目目录下,则不会打包进Apk。
这也许就是android.jar为何不会被打包到apk中的原因。
 
参见如下文章:
 
Android笔记34:命令行打包编译.apk 包含第三方.jar 的方法 
 
2011-09-11 00:20:12| 分类: android笔记 | 标签:命令行 打包 apk jar 第三方 |字号 订阅
**中秋节真是个假期~,从凌晨1点直接睡到下午3点,睡了14个小时累积的疲劳一扫而空脑袋也好使了..
 
之前受托研究个挺好玩的项目..细节不说了,我在实现的时候卡在怎样脱离eclipse而能将项目源码编译成.apk上
 
发现网上有现成答案的,参考了以下这篇
http://jojol-zhou.iteye.com/blog/729254
 
虽然原作者是针对较早期的 Android 1.5(API-3)写的,但原理和用法相同。
 
用到的路径和工具包括(容我偷个懒直接把部分的批处理内容直接cp出来了):
SET WORK_SPACE=E:\code\autopack_demo
SET PKG_PATH=com\xxx\apk\autopack_demo
SET JAVA_SPACE=D:\Progra~2\Java\jdk1.6.0_21\bin
SET ANDROID_SPACE=E:\android-sdk-windows
SET JAVAC=%JAVA_SPACE%\javac.exe
SET AAPT=%ANDROID_SPACE%\platform-tools\aapt.exe
SET DX=%ANDROID_SPACE%\platform-tools\dx.bat
REM 输出的路径
SET OUT_FOLDER=...
SET OUT_CLASS_FOLDER=...
 
依葫芦画瓢写批处理试运行,发现卡在一个问题上:项目中部分的功能模块引用了第三方的 jar 里的类
 
在编译的时候报错,
javac 时凡事引用到jar的类的地方都报出了 class not found 之类的错误
gen/R.java 里也提对象不匹配 还有一大堆的东西
 
按着错误提示一个一个来解决,按照打包的流程
 
1. 先解决生成 R.java 这个环节
 
这里预先我把第三方的3rd.jar复制到了项目文件夹的 lib/ 下,然后再批处理里定义为
-------------------------------------------------------------------------------------------
SET THIRD_JAR=%WORK_SPACE%\lib\3rd.jar
 
REM 以下这行命令生成 R.java
%AAPT% package -m -J %GEN_FOLDER% -M %WORK_SPACE%\AndroidManifest.xml -S %RESOURCE_FOLDER% -I %ANDROID_JAR% -I % THIRD_JAR%
-------------------------------------------------------------------------------------------
在命令最后加上了 -I % THIRD_JAR%,这样有关 R.java 的报错消失了
 
2. javac 的错误提示..这里是把 .java 编译成 .class 提示找不到第三方的包
那么在原命令行略作修改 最后添加上 -classpath %THIRD_JAR% 这个引用参数,问题解决
 
 
 
再编译没有报错,把其他资源文件也打包进apk最后加上签名~生成了apk,好像成功咯
安装到手机里,运行,程序崩溃了... Android笔记34:命令行打包编译.apk 包含第三方.jar 的方法 - 恶 - 早衰男的巢
 
看DDMS 输出地日志~~ 问题还是在于第三方的类..not found ... 呃,不是已经编译通过了吗
 
回头看看那个apk文件,的确太小.. 没有包含那个jar 
 
做逆向研究... 看看从eclipse 编译出来的apk(104kb)和我打包出来的(26kb)到底差别在哪里...
把apk文件当做zip解压~看见尺寸的差异在于 classes.dex 这个文件
!原来问题在这里...
 
生成dex文件是用 %DX% 查了下 % DX% --help 用法,找到了解决问题的最后一步
 
3. 输出dex时把第三方的jar包含在内
在 dx --help里说的很明白了:
-------------------------------------------------------------------------------------------
E:\android\android-sdk-windows\platform-tools>dx --help
usage:
  dx --dex [--debug] [--verbose] [--positions=<style>] [--no-locals]
  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] [--no-strict]
  [--keep-classes] [--output=<file>] [--dump-to=<file>] [--dump-width=<n>]
  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] [--core-library]
  [--num-threads=<n>] [<file>.class | <file>.{zip,jar,apk} | <directory>] ...
    Convert a set of classfiles into a dex file, optionally embedded in a
    jar/zip. Output name must end with one of: .dex .jar .zip .apk. Positions
    options: none, important, lines.
  dx --annotool --annotation=<class> [--element=<element types>]
  [--print=<print types>]
  dx --dump [--debug] [--strict] [--bytes] [--optimize]
  [--basic-blocks | --rop-blocks | --ssa-blocks | --dot] [--ssa-step=<step>]
  [--width=<n>] [<file>.class | <file>.txt] ...
    Dump classfiles, or transformations thereof, in a human-oriented format.
  dx --junit [-wait] <TestClass>
    Run the indicated unit test.
  dx -J<option> ... <arguments, in one of the above forms>
    Pass VM-specific options to the virtual machine that runs dx.
  dx --version
    Print the version of this tool (1.6).
  dx --help
-------------------------------------------------------------------------------------------
 
在原先写的 dx 指令最后加上 jar的完整路径 也就是 %THIRD_JAR% 就ok了
%DX% --dex --output=%OUT_FOLDER%\classes.dex %OUT_CLASS_FOLDER% %THIRD_JAR%
 
 
再把编译打包签名的顺序重新做一遍~生成的apk运行一切正常!
或许不是个什么大不了值得做笔记的一个专题,只是老衲java底子如此脆弱不堪..
但之前数天在 度娘、谷哥、有盗和有病 四个知名包打听都寻遍了皆一无所获
在技术论坛发帖提问也纯引来围观无人能解
我想不通是这个问题真的不值一提还是国内的编程开发风气已经浮躁到量产我这种白菜的地步..但愿不是后者。
 
-搁笔-
 
 
[Android]命令行编译APK
(2010年04月18日) 发表于 ChinaUnix
 
手动编译你的apk,可以让资源目录不命名为res, 你能够命名任何你想要的名字。
 
你可以在以下目录发现ant脚本: <SDK_HOME>\platforms\android-1.5\templates\android-rules.xml
 
第一步: 产生R文件以及包资源
aapt package -f -M ${manifest.file} -F ${packaged.resource.file} -I ${path.to.android-jar.library} -S ${android-resource-directory} [-m -J ${folder.to.output.the.R.java}]
 
 
第二步:编译java源文件以及R.java文件
use javac
 
 
第三步:将classes文件转化成Dalvik自节码
use dx.bat
dx.bat –dex –output=${output.dex.file} ${compiled.classes.directory} ${jar files..}
 
第四步:创建未签名的apk
use apkbuilder
 
apkbuilder ${output.apk.file} -u -z ${packagedresource.file} -f ${dex.file}
 
or
 
apkbuilder ${output.apk.file} -u -z ${packagedresource.file} -f ${dex.file} -rf ${source.dir} -rj ${libraries.dir}
 
-rf = resources required for compiled source files?
-rj = resources required for jar files
 
第六步: 产生一个key
use keytool
 
第七步骤: 对APK进行签名
use jarsigner
 
jarsigner -keystore ${keystore} -storepass ${keystore.password} -keypass ${keypass} -signedjar ${signed.apkfile} ${unsigned.apkfile} ${keyalias}
 
 
第八步: 发布
use adb
adb -d install -r ${signed.apk}
 
Inspecting your APK file:
 
aapt list -v latest.apk
 
Open questions:
1. Can you include more than one dex file in the apk?
2. Can you have dex file named other than classes.dex in the apk?
3. Does an apk have to have a packaged resource?
 
 
android 打包第三方jar包
 June 30th, 2011 Charlie
android, android 打包外部jar文件 android 打包外部包, android 打包第三方jar
 
android项目开发时会用到第三方提供的jar包,通常情况下按照eclipse导入jar包的方法(选择项目,右键点击Build Path,Build Path–>Add Libraries–>User Library–>Next–>User Libraries–>New–>Add JARs,选择第三方的jar包),就可以将jar包导入到项目。
 
根据这样的打包方式时,eclipse导入jar包后,eclipse编译器也能识别,即项目不会因为缺少jar包而报错,但是运行android程序的时候却没有找到包而报错了。APK文件也很小,也就是jar包并没有打包到APK文件中。
 
在android项目中找到.classpath文件并打开,文件代码如下:
view plaincopy to clipboardprint?
 
    <?xml version="1.0" encoding="UTF-8"?> 
    <classpath> 
    <classpathentry kind="src" path="src"/> 
    <classpathentry kind="src" path="gen"/> 
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> 
    <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/box2d"/> 
    <classpathentry kind="output" path="bin"/> 
    </classpath> 
 
发现eclipse导入包操作后,写入了这行代码
 
<classpathentry kind=”con” path=”org.eclipse.jdt.USER_LIBRARY/box2d”/>
 
这行代码应该是eclipse内部识别的,并不会打包到模拟器上,所以运行到模拟器上找不到相应的jar包。
 
为了在android内部能找到jar包,于是在android项目内新建一个lib文件夹,将jar包放在lib文件夹内。
并将上面的那行代码删除,添加一行代码:
 
<classpathentry kind=”lib” path=”lib/jbox2d-2.0.1-full.jar”/>
 
jbox2d-2.0.1-full.jar是lib文件下的jar包,可添加多个jar包。
 
即最终修改代码为:
view plaincopy to clipboardprint?
 
    <?xml version="1.0" encoding="UTF-8"?> 
    <classpath> 
    <classpathentry kind="src" path="src"/> 
    <classpathentry kind="src" path="gen"/> 
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> 
    <classpathentry kind="lib" path="lib/jbox2d-2.0.1-full.jar"/> 
    <classpathentry kind="output" path="bin"/> 
    </classpath> 
 
最后刷新eclipse项目,会发现项目bin目录的APK文件大小增大,说明APK文件已经包含jar包文件,重新clean项目并运行即可。