美文网首页
如何正确打出带资源文件的jar包

如何正确打出带资源文件的jar包

作者: Stardust_ | 来源:发表于2017-08-02 20:36 被阅读0次

一、资源文件的使用

首先是如何使用res下的资源文件,直接使用R.id这样的格式是不正确的,原因如下:

当我们将src目录下的源码打出Jar后,源码代码中的如Object = findViewById(R.id.id_name)中的R.id.id_name部分,都会被替换成此时在R文件中生成的id_name对应的ID值(如果有兴趣的话,可以用反编译软件可以查看到)。但是由于R文件中的ID值是由系统自动生成的,而且在不同的系统环境和不同的时间,id_name对应的ID可能不一样。

如果你使用的是androidstudio , 打出aar包,就不会有这个问题。但是这样的话,就相当于抛弃了eclipse用户,这个方法是不可取的。

这里提供两种解决方案:

  1. 将资源文件放到assets目录下。

    可使用下面方法读取图片,其他资源文件可使用类似方案,这里不再详细说明,后面会提供将assets文件夹打入jar包的方法。

        /**
         * 从Assets中读取图片
         */
        private Bitmap getImageFromAssetsFile(String fileName) {
            Bitmap image = null;
            AssetManager am = context.getResources().getAssets();
            try {
                InputStream is = am.open(fileName);
                image = BitmapFactory.decodeStream(is);
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return image;
    
        }
    

  2. 使用Identifier获取组件ID

    方法如下

     /**
      * 获取组件的id
      * @param className  layout,string,drawable,style,id,color,array
      * @param idName     文件名
      * @return  资源id
      */
    public static int getIdByName(Context context, String className, String idName){
            String packageName = context.getPackageName();
            try {
              
                return context.getResources().getIdentifier(idName, className, 
                                                            packageName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
    

    然后将需要的使用的资源文件单独拿出来,接入时拷贝到主工程里就可以了。

    注意资源文件命名时最好加一个前缀,防止与与接入方工程文件重名,例如:js_download_image,js_download_xml

    这个方法类似网上流传的使用反射获取ID

    public static int getIdByName(Context context, String className, String idName){
            String packageName = context.getPackageName();
            int id = 0;
            try {
                Class<?> cls = Class.forName(packageName + ".R$" + className);
                id = cls.getField(idName).getInt(cls);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return id;
        }
    

    不过这个方法是有问题的,因为在这里用context.getPackageName() 获取的是 applicationId

    而R文件真正的位置是在初始化工程时建立的的com.xx.xx 为名的文件夹下

applicationId一旦修改,与文件夹名不一致,就会导致找不到R文件而报错。

二、生成jar

  1. 直接将jar拷贝出来
def SDK_NAME = "mysdk-v1.0-release"; // SDK名称

//Copy类型
task makeJar(type: Copy) {

    //删除存在的
    delete 'build/libs/'+ SDK_NAME +'.jar'
    //设置拷贝的文件目录
    from('build/intermediates/bundles/release/')
    //jar包存放的文件目录
    into('build/libs/')
    
    //include ,exclude参数来设置过滤,也可以直接写在from()的文件路径里
    include('classes.jar')
      
    //重命名
    rename ('classes.jar', SDK_NAME+'.jar')

}

makeJar.dependsOn(build)
  
  1. assets目录打入jar包中
def SDK_NAME = "mysdk-v1.0-release" // SDK名称
def jar = file('build/intermediates/bundles/release/classes.jar')

task makeJar(type: Jar) {

    //删除存在的
    delete 'build/libs/'+ SDK_NAME +'.jar'

    from zipTree(jar)
    // 包含assets目录
    from fileTree(dir: 'src/main', includes: ['assets/**']) 

    baseName = SDK_NAME
    destinationDir = file('build/libs/')
}


makeJar.dependsOn(build)

两种方式都只需要运行gradlew makeJar就可以生成jar包在build/libs/下。

相关文章

网友评论

      本文标题:如何正确打出带资源文件的jar包

      本文链接:https://www.haomeiwen.com/subject/abvylxtx.html