写好一个Android模块,比如说一个自定义控件或某个功能的sdk,然后开放出来给别人使用,就得通过某种方式把源码提供给对方。常见的打包方式有:

一、直接给源码,由开发者把代码加入到自己的工程中
该方式主要是些开源的小控件,功能比较简单也不涉及商业机密,所以独乐乐不如众乐乐。开源的自定义控件基本以这种形式发布。

如果自定义控件用到资源文件,也可以由开发者手工将资源文件加入到自己的工程,当然需要修改代码中R文件的import路径。代码+资源文件都加入到工程,代表例子有瀑布流网格控件StaggeredGridView(package名为com.etsy.android.grid),还有滚轮控件WheelView(package名为kankan.wheel.widget)等等。

二、直接给源码工程,由开发者把该工程作为一个引用库加入到自己的工程中
有时候某个开源控件的规模不小,不但代码文件很多,连资源文件都不少,如果直接加入到工程的代价就比较大。不但要改很多路径,而且后期维护也不方便,所以这时往往把开源工程作为library引用到自己工程。具体操作步骤为:右击自己的工程,选择Properties,在弹出窗口的左侧菜单中选择Android,然后在右下方Library区域点击Add按钮,在弹出的小窗中选择要引用的开源工程,点击OK再OK,接着就可在自己工程使用开源库的API了。

这种形式的好处是:开源工程代码和资源文件都无需修改,并且不会与自己工程的文件相混淆。该形式的代表例子有下拉刷新框架pulltorefresh(package名为com.handmark.pulltorefresh.library),以及滑动菜单框架slidingmenu(package名为com.jeremyfeinstein.slidingmenu.lib)等等。

三、把源码打成jar包,由开发者把jar包加入到自己工程的libs目录
直接给源码的方式不利于保护知识产权,并且直接给源码也不方便管理版本,开发者用的时候很可能遇到这样那样的bug。基于以上种种考虑,把源码打成jar包,其实对开发者来说更方便使用。jar打包的具体步骤为:右击要打包的工程,选择Export,在弹出窗口中选择“Java”——“JAR file”,点击Next,然后在新弹窗中勾选src目录,注意res目录是无法打包的,接着点击Browser按钮选择jar包的保存路径,最后点击Finish按钮,等待片刻打包好的jar包便生成完毕。
大部分的java工具都是以jar包的形式发布的,如fastjson、httpmime、zxing等等。

但是jar包方式无法打包res目录,使得layout、values、drawable目录下的xml文件都打包不了。不过有个例外,就是assets目录也是可以打包进jar的。所以如果代码中有用到图片或是文本文件,可以把图片与文本文件放入assets目录,就能一块打包了。当然代码中若要读取图片与文本文件的内容,得借助于AssetManager,具体用法参见《Android开发笔记(二十五)assets目录下的文件读取》。
联合把src和assets打成jar包,该形式的代表例子有百度地图SDK。

四、给出一个库工程,但是src部分打成jar包,由开发者在自己工程中引用该库工程
现在有种情况,我们开发了一个APP,可是客户要求把该APP集成到别的APP中,作为另一个APP的一个频道。因为res目录下文件众多,实在是不可能打成jar包,同时由于商业机密也不能开放src源码,我们就想到一个办法,还是给对方一个库工程,只是src目录打成jar包放到库工程的libs目录。该方式说起来简单,做起来却是麻烦多多,主要问题出在R文件上。由于打成jar包时,原工程中每个资源的资源id都已生成并写死在jar里面,可是对方工程引用库工程时,会重新生成一份库工程的R文件,那么jar包里的资源id就跟R新文件里的资源id不一样,因此总是扔出id找不到空指针的异常。

要解决R文件冲突的问题,基本思路是利用反射机制,预先定义好每个资源的名称,然后在运行过程中动态根据资源名称去找资源id。为了尽可能减少代码修改量,预先定义的资源名称列表保存在R.java中,这样只需批量更改各java源码中R的import路径,无需更改资源id的使用方法。另外在每个Activity启动时都要注入反射用到的Context,下面是通过反射查找资源id的代码例子:

import android.app.Application;
import android.content.Context;//根据资源的名字获取其ID值
public class MResource {public static Application app;//根据名称获取IDpublic static int getIdByName(Context context, String className, String name) {String packageName = context.getPackageName();Class r = null;int id = 0;try{r = Class.forName(packageName + ".R");Class[] classes = r.getClasses();Class desireClass = null;for (int i = 0; i < classes.length; ++i) {if (classes[i].getName().split("\\$")[1].equals(className)) {desireClass = classes[i];break;}}if (desireClass != null)id = desireClass.getField(name).getInt(desireClass);} catch (Exception e) {e.printStackTrace();}return id;}//获取ID数组   public static int[] getIdsByName(Context context, String className, String name) {String packageName = context.getPackageName();Class r = null;int[] ids = null;try {r = Class.forName(packageName + ".R");Class[] classes = r.getClasses();Class desireClass = null;for (int i = 0; i < classes.length; ++i) {if (classes[i].getName().split("\\$")[1].equals(className)) {desireClass = classes[i];break;}}if ((desireClass != null) && (desireClass.getField(name).get(desireClass) != null) && (desireClass.getField(name).get(desireClass).getClass().isArray()))ids = (int[])desireClass.getField(name).get(desireClass);} catch (Exception e) {e.printStackTrace();}return ids;}public static int getId(String type, String name) {int id = MResource.getIdByName(MResource.app, type, name);return id;}}

下面是R文件的代码例子:

public final class R {public static final class id {public static final int action_settings = MResource.getId("id", "action_settings");
}public static final class layout {public static final int action_web_activity = MResource.getId("layout", "action_web_activity");
}}

点此查看Android开发笔记的完整目录

Android开发笔记(六十八)工程库打包相关推荐

  1. Android开发笔记(十八)书籍翻页动画PageAnimation

    前面几节的动画都算简单,本文就介绍一个复杂点的动画--书籍翻页动画.Android有自带的翻页动画ViewPager,不过ViewPager只实现了平移效果.即便使用补间组合动画或者属性动画,也只是把 ...

  2. Android开发笔记(十六)秋千摇摆动画SwingAnimation

    上节博主介绍了AlphaAnimation和淡入淡出动画的使用,其实AlphaAnimation只是四种补间动画中的一种.那么为了加深对其他补间动画的理解,我想说说旋转动画RotateAnimatio ...

  3. Android开发笔记(十五)淡入淡出动画TransitionDrawable

    说到淡入淡出动画,可能大家会想到补间动画里面的AlphaAnimation,不过这个深浅动画只能对透明度做渐变效果,也就是只能对一个图形做深浅的颜色变换.如果我们想要从A图片逐渐变为B图片,也就是要实 ...

  4. Android开发笔记(十二)测量尺寸与下拉刷新

    尺寸测量的配置 控件宽和高的设置方式 大家知道,自定义视图的目的就是要在屏幕上显示期望的图案,那在绘制图案之前,我们得先知道这个图案的尺寸(如宽多少高多少). 一般在xml中给控件的宽和高有三种赋值方 ...

  5. Android开发笔记(九十八)往图片添加部件

    添加圆角 添加圆角的功能,要用到Canvas类的drawRoundRect方法,即把画布裁剪成指定的圆角矩形. 下面是给图片添加圆角的效果截图: 下面是给图片添加圆角的代码片段: public sta ...

  6. Android开发笔记(十九)底部标签栏TabBar

    底部标签页实现思路 现在的APP,大多在页面底部显示标签栏Tabbar,用于切换不同栏目的页面.Tabbar起源于iOS,iOS的Tabbar自动位于页面下方,可是Android搬过来的时候做了改动, ...

  7. Android开发笔记(十四)圆弧进度动画CircleAnimation

    一个好看的APP,都有不少精致的动画效果.熟练运用各种动画技术,可让我们的APP灼灼生辉.Android在技术上把动画分为了三类,分别是帧动画FrameAnimation.补间动画TweenAnima ...

  8. Android开发笔记(一百八十七)利用估值器实现弹幕动画

    如今上网看电影电视越发流行了,追剧的时候经常看到视频上方数行评论向左边飘去,犹如子弹那样飞快掠过,这些评论文字因此得名"弹幕".弹幕评论由正在观看的网友们即兴发表,故而连绵不绝从画 ...

  9. 配置库用户_GEE学习笔记 六十八:【GEE之Python版教程二】配置Python开发环境

    这一篇内容主要讲解两部分内容,第一部分是本地python开发环境的配置,第二部分是GEE的python开发环境配置.我这里做的所有的操作都是在我的Mac电脑上做的,Windows上操作类似,如果有不清 ...

  10. pip升级python版本_GEE学习笔记 六十八:【GEE之Python版教程二】配置Python开发环境...

    这一篇内容主要讲解两部分内容,第一部分是本地python开发环境的配置,第二部分是GEE的python开发环境配置.我这里做的所有的操作都是在我的Mac电脑上做的,Windows上操作类似,如果有不清 ...

最新文章

  1. 拉丁法谚讲习1-24 【ZZ】
  2. 【Oracle】函数简介与入门
  3. ajax跨域请求.json文件,使用JSONP对JSON文件进行跨域Ajax请求
  4. ASP.NET+AJAX简单的文体编辑器
  5. 软件工程练习:模块化,单元测试,回归测试,TDD
  6. 程序员的毕业设计,时隔一年,仍感觉头秃
  7. 对于树分治算法的初步理解
  8. logback error 分开存日志
  9. 《A.I.爱》王力宏与人工智能谈恋爱 邀李开复来客串
  10. TQ2440实现触摸屏和qt图形 解决segmentation fault
  11. 什么?你的私钥泄漏了?
  12. win8 不显示计算机,Win8电脑插上U盘不显示盘符怎么办?
  13. MPQ文件系统优化(续)
  14. Unity不规则碰撞
  15. mysql菜鸟教程 文档_mysql菜鸟教程
  16. mmkv原理,Android多进程从头讲到尾,成功定级腾讯T3-2
  17. 投顾风向|各方节前无心恋战 等到节后或有“红包”行情
  18. 研华微型计算机biso,研华主板bios设置方法
  19. NVIDIA NeMo 简介——教程和示例
  20. 手机热点中的AP频段2.4GHz和5.0GHz有什么区别?

热门文章

  1. 吴恩达《机器学习》第十七章:大规模机器学习
  2. 吴恩达CNN卷积神经网络第二周作业Keras Tutorial
  3. 8、QuickExec命令行的使用
  4. java入门申请,《java入门如此简单》——基础知识1
  5. form和ajax同时提交吗,form表单提交与ajax消息传递
  6. php 读写excel 网络错误,谁用过PHPExcel,导出的文件报“无法读取的内容”错误
  7. 实战中的Agile开发
  8. EMC-- DFC --Sessions and Session Managers
  9. php 页面拖动改变大小,鼠标拖动改变DIV等网页元素的大小的实现方法
  10. bt解析 开源 java_开源一个BT客户端:BitWave