一周小结(二)——说说jar包那些事儿

    “天高云淡,望断南飞雁。不到长城非好汉,屈指行程二万。六盘山上高峰,红旗漫卷西风。今日长缨在手,何时缚住苍龙?”——《清平乐·六盘山》。假期里把《中国诗词大会》从头看到尾,最后发现要论诗词的气势,作者绝对是数一数二的。新的一年,第一篇博文就选这首诗吧,愿在新的一年里,能够早日“缚住苍龙”!

    在做项目的时候,很多人都想把自己写的Module或者Libs或者Utils分享出来,一来可以在其他项目中方便用到之前写的东西,二来可以帮助提高效率。其中一个常用的办法就是采用jar包,jar包具有占用空间比较小,传输速度快,不易丢失文件等优点。

1、生成jar包

    生成jar包,首先要对Module的build.gradle进行修改。

    第3步,在main目录下创建assets文件夹,用于存放需要打包的资源文件,比如图片等;并将其放入assets文件夹中。当然,如果没有需要打包的资源文件,则直接跳过此步骤。

     第4步,向android内添加方法代码,但是在实际过程中发现直接添加到最外面也可以。不需要打包资源文件的代码如下:

    task makeJar(type: Copy) {
        //删除存在的
        delete 'build/libs/myjar.jar'
        //设置拷贝的文件
        from('build/intermediates/bundles/debug/')
        //打进jar包后的文件目录
        into('build/libs/')
        //将classes.jar放入build/libs/目录下
        //include ,exclude参数来设置过滤
        //(我们只关心classes.jar这个文件)
        include('classes.jar')
        //重命名
        rename ('classes.jar', 'myjar.jar')
    }

    makeJar.dependsOn(build)

    需要打包资源文件的代码如下:

    def SDK_BASENAME = "TestSdk";
    def SDK_VERSION = "_V1.0";
    def sdkDestinationPath = "build";
    def zipFile = file('build/intermediates/bundles/release/classes.jar')

    task deleteBuild(type: Delete) {
        delete sdkDestinationPath + SDK_BASENAME + SDK_VERSION + ".jar"
    }

    task makeJar(type: Jar) {
        from zipTree(zipFile)
        from fileTree(dir: 'src/main',includes: ['assets/**'])//将assets目录打入jar包
        baseName = SDK_BASENAME + SDK_VERSION
        destinationDir = file(sdkDestinationPath)
    }

    makeJar.dependsOn(deleteBuild, build)

    注意jar包的生成目录。 

    此时jar包中的代码访问jar包assets文件夹中的文件的方式需要进行修改。输出Bitmap时应该为:

BitmapFactory.decodeStream(context.getClass().getClassLoader().getResourceAsStream("assets/" + "previous.png"))

    输出Drawable时应该为:

new BitmapDrawable(BitmapFactory.decodeStream(ctx.getClassLoader().getResourceAsStream("assets/" + "person.png")))

    第5步,生成jar包。点击屏幕右侧的Gradle,找到makeJar并双击即可。

    常见报错:(1)生成过程中,可能会由于代码中有switch-case语句和R.id.×××结合使得程序报错,只需将switch-case语句改为if-else语句即可。选中“switch”,按下Alt+Enter,选择replace with if-else即可。 (2)Error:与元素类型 "item" 相关联的 "name" 属性值不能包含 '<' 字符——不必理会,再试一次即可!

    最后,jar包生成成功!

2、jar包的合并

    遗憾的是,当一个项目有多个模块时,我们并不能将整个工程生成一个jar包导出,而只能一个一个地生成多个jar包。这样就使得新的项目需要进入jar包的数量很多,给以后的其他工作造成麻烦。这个困难可以采用合并jar包的方式来解决。多个jar包合并成一个jar包是使用Apache的Ant,它是一个基于Java的生成工具。这个工具的全名是another neat tool,可以到官网(https://ant.apache.org/bindownload.cgi)下载。

    下载好了之后接下来就是解压和配置环境变量。

    在命令框中输入ant 如果提示如下就表示你已经安装成功了

    C:\Users\user>ant
    Buildfile: build.xml does not exist!
    Build failed

    接下来开始使用。注意:ant默认运行build.xml文件,这个文件到目前为止是不存在的 需要我们创建。如果不想命名为build.xml,运行时可以使用 ant -buildfile test.xml 命令指明要运行的构建文件。build.xml 文件的格式如下:

<?xml version="1.0" encoding="utf-8"?>
<project
    name="lzg_dlna"
    basedir="D:\Android\android_tool\ant_test"
    default="makeSuperJar" >
 
    <target
        name="makeSuperJar"
        description="description" >
 
        <jar destfile="lzg_dlna.jar" >
        <zipfileset src="cdi-api.jar" />
        <zipfileset src="http-2.2.1.jar" />
        <zipfileset src="httpclient-4.2.2.jar"/>
        <zipfileset src="httpcore-4.2.3.jar" />
        <zipfileset src="javax.annotation_1.0.jar" />
        <zipfileset src="javax.inject.jar" />
        <zipfileset src="javax.servlet-3.0.0.v201103241009.jar" />
        <zipfileset src="jetty-client-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-continuation-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-http-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-io-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-security-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-server-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-servlet-8.1.9.v20130131.jar" />
        <zipfileset src="jetty-util-8.1.9.v20130131.jar" />
        <zipfileset src="seamless-http-1.0-alpha2.jar" />
        <zipfileset src="seamless-util-1.0-alpha2.jar" />
        <zipfileset src="seamless-xml-1.0-alpha2.jar" />
        <zipfileset src="slf4j-api-1.6.1.jar" />
        <zipfileset src="slf4j-jdk14-1.6.1.jar" />
        </jar>
    </target>
 
</project>

    其中,name  : 表示的是你即将合成的jar包的名字 可以随便写;basedir :  表示你存放jar包的目录(D:\Android\android_tool\ant_test这个目录下放的是你当前需要合并的所有jar 和build.xml文件)。

以上都转备好之后开始运行ant -buildfile命令:ant -buildfile D:\Android\android_tool\ant_test\build.xml

3、jar包的导入与删除

    导入时将jar包放入模块下libs文件夹中,右键->Add As Library或者在File->Project Structure中添加,如图所示:

    删除时,操作顺序正好相反。

    新年第一篇博客,就写到这里吧。祝大家新的一年里工作顺利,身体健康。 

4、补充

    最近查阅资料发现可以将资源文件放入项目中,在jar包中添加反射类,进而实现jar包的代码访问资源文件。反射率如下:

public class MResource {

    public static int getIdByName(Context context, String className, String resName) {
        String packageName = context.getPackageName();
        int id = 0;
        try {
            Class r = Class.forName(packageName + ".R");
            Class[] classes = r.getClasses();
            Class desireClass = null;
            for (Class cls : classes) {
                if (cls.getName().split("\\$")[1].equals(className)) {
                    desireClass = cls;
                    break;
                }
            }
            if (desireClass != null) {
                id = desireClass.getField(resName).getInt(desireClass);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return id;
    }
}

    使用方法如下:

setContentView(MResource.getIdByName(this, "layout", "jar_layout"));
ImageView mPlayerLogo = (ImageView) this.findViewById(MResource.getIdByName(this, "id", "logo"));
mPlayerLogo.setImageResource(MResource.getIdByName(this, "drawable", "ic_launcher"));

参考:

1、https://blog.csdn.net/qq_20328181/article/details/84333750

2、https://blog.csdn.net/xiayiye5/article/details/79639044

3、https://blog.csdn.net/asan855/article/details/48027563

4、https://blog.csdn.net/rightrat/article/details/4334046

5、https://blog.csdn.net/renwudao24/article/details/69071410

6、https://blog.csdn.net/gzl003csdn/article/details/53539133

7、https://www.cnblogs.com/xxdh/p/6703746.html

原创文章 19 获赞 34 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_38141453/article/details/87902772