如何在sdk下使用.9.png图片

来源:互联网 发布:java dos 运行命令 编辑:程序博客网 时间:2024/06/05 05:14

***************************************

在经过几年的经验累积之后,我终于决定整理一下曾经遇到的各种问题,给各位走在android开发路上的朋友一点帮助,更多相关问题,请访问我的博客:http://blog.csdn.net/xiaoliluote  如果您对该问题有更多的解决方式,请留言,验证之后我会编辑博客

***************************************


如果有编写过sdk的朋友,或许就会遇到过该问题,由于我们是做的sdk,最终打包成jar文件给外部使用,jar文件里面就没法使用xml的布局,也没法用资源来引入图片等资源,我们则一般是将图片放在assets目录下,这样打包的时候可以打包进去,在主项目加载的时候,会将主项目和jar里面的assets目录的内容合并。

进入主题,由于要处理兼容问题,不希望放太多的图片在assets目录下去打包,这样jar包太大。于是需要用到 .9.png 图片,在制作好.9.png图片之后,就开始蛋疼了,因为以前都是直接在xml里面引用图片,而且也不需要加上 .9的后缀,现在就只能用文件流的方式来读取图片了,于是大胆的进行猜测,编写了以下代码:

public static  Bitmap getImageFromAssetsFile(Context context, 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;   }

BitmapDrawable draw = new BitmapDrawable(getImageFromAssetsFile(_context,"image/activity_popu_top.png"));
然后马上就发现不行,没法像xml那么智能,它只会找对应的图片,于是改成这样:

BitmapDrawable draw = new BitmapDrawable(getImageFromAssetsFile(_context,"image/activity_popu_top.9.png"));
这样图片是读取出来了,但是加载图片的时候,.9.png的效果却丢失了,根本没有拉伸,顿时心里千万个草泥马飘过。

开始想其他的办法,于是去寻找,是否有代码可以创建 .9.png图片的,在官网找到 NinePatch这个类,以为找到了救星,于是赶紧拿过来用,代码如下:

Bitmap bitmap =getImageFromAssetsFile(_context,"image/activity_popu_top.9.png");NinePatch nine = new NinePatch(bitmap,bitmap.getNinePatchChunk(),null);NinePatchDrawable draw = new NinePatchDrawable(nine);
怀着初恋的心情去运行,结果居然闪退了,卧槽,要死了,为什么会闪退,然后查看一下logcat的错误信息,说是空指针,然后debug一下,发现是bitmap.getNinePatChunk() 这个空了,得不到byte[]  

代码虐我千百遍,我待代码如初恋,没办法,还是得找解决办法啊,于是我又开始尝试,放一个图片去res目录,试试用R文件来引入图片,读取出来的是否正常,代码如下:

Bitmap bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.activity_popu_top);byte[] b =bitmap.getNinePatchChunk();
代码这个bitch,居然这样就有值,冷静下来之后,我很明确这就是 用资源引入和用文件流读取的区别,于是脑洞大开,如果能得到运行后,打包成apk文件时的这个.9.png 图片,那么应该就OK了吧,于是找方法,终于找到解决办法,如下:

去我们的sdk目录,找一个叫做aapt.exe的文件,我是在这里找到的: E:\adt-bundle-windows-x86_64-20130729\sdk\build-tools\20.0.0\aapt.exe

但我看网上的说法,都是去platform-tools 目录下找,于是将信将疑的,我将这个文件copy到了 platform-tools目录下,然后在环境变量path 里面,加上platform-tools这个目录,最后cmd命令进入该目录,运行以下代码:

aapt package -f -SE:\workspace\项目\res -IE:\xxx\xxx\platforms\android-19\android.jar -M
 E:\workspace\xxx\AndroidManifest.xml -FE:\xxx\xxx\xxx.zip

我解释一下上面的代码:  我将.9.png的图片,放入了res其中的一个目录(drawable-hdpi),然后它的规则是:

aapt package -f -S  (res的目录) -I (android.jar所在目录,我的是在sdk目录下的platforms\android-19\android.jar) -M (存放res目录的这个项目的AndroidManifest.xml全路径) -F (打包后,希望放入的文件,以zip格式结尾)

特别留意:cmd 命令里面的 -f -S -I -M ,是严格区分大小写的,如果你写成  -f -s 那么就打包不出来了

打包完成后,解压zip文件,得到里面对应名字的 .9.png图片,然后再调用以下代码:

Bitmap bitmap =getImageFromAssetsFile(_context,"image/activity_popu_top.9.png");NinePatch nine = new NinePatch(bitmap,bitmap.getNinePatchChunk(),null);NinePatchDrawable draw = new NinePatchDrawable(nine);

这次就不会报错啦。

以上所有内容纯原创,如果转载,请说明出处,国内的各大论坛抄袭的内容太多,经常是一个问题,一搜,csdn是这个答案,eoe也是这个答案,新浪博客也是这个答案,真正有意义的东西太少。






0 0