@linux1s1s
2015-09-10T12:55:18.000000Z
字数 10343
阅读 3777
AndroidBuild
Android 多渠道打包方案 中已经介绍了基本的思路和基本的源代码,这里给出实践过程出现的问题和解决思路。
首先如果你没有使用上篇博客中给出的Python脚本,而是自己写了shell脚本或者其他脚本,如果实现思路如下:
那么可能出现下面类似的问题:
09-10 17:32:00.769: W/System.err(2609): android.content.res.Resources$NotFoundException: File res/drawable-hdpi/guide_p1.gif from drawable resource ID #0x7f02010909-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)09-10 17:32:00.769: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)09-10 17:32:00.769: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)09-10 17:32:00.769: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)09-10 17:32:00.769: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)09-10 17:32:00.769: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)09-10 17:32:00.769: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)09-10 17:32:00.769: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)09-10 17:32:00.769: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)09-10 17:32:00.769: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)09-10 17:32:00.769: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)09-10 17:32:00.769: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)09-10 17:32:00.769: W/System.err(2609): Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed09-10 17:32:00.769: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)09-10 17:32:00.769: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)09-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)09-10 17:32:00.769: W/System.err(2609): ... 16 more09-10 17:32:00.769: W/System.err(2609): android.content.res.Resources$NotFoundException: File res/drawable-hdpi/guide_p2.gif from drawable resource ID #0x7f02010a09-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)09-10 17:32:00.769: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)09-10 17:32:00.769: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)09-10 17:32:00.769: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)09-10 17:32:00.769: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)09-10 17:32:00.773: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)09-10 17:32:00.773: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)09-10 17:32:00.773: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)09-10 17:32:00.773: W/System.err(2609): Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)09-10 17:32:00.773: W/System.err(2609): ... 16 more09-10 17:32:00.773: W/System.err(2609): android.content.res.Resources$NotFoundException: File res/drawable-hdpi/guide_p3.gif from drawable resource ID #0x7f02010b09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)09-10 17:32:00.773: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)09-10 17:32:00.773: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)09-10 17:32:00.773: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)09-10 17:32:00.773: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)09-10 17:32:00.773: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)09-10 17:32:00.773: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)09-10 17:32:00.773: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)09-10 17:32:00.773: W/System.err(2609): Caused by: java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)09-10 17:32:00.773: W/System.err(2609): ... 16 more
注意L2 行,问题在这里,看看前面一个代码栈,GifDrawable是第三方支持动态图的类库,所以溯本逐源到GifDrawable.java
/*** A {@link Drawable} which can be used to hold GIF images, especially animations.* Basic GIF metadata can also be examined.** @author koral--*/public class GifDrawable extends Drawable implements Animatable, MediaPlayerControl {final ScheduledThreadPoolExecutor mExecutor;volatile boolean mIsRunning = true;long mNextFrameRenderTime = Long.MIN_VALUE;private final Rect mDstRect = new Rect();/*** Paint used to draw on a Canvas*/protected final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);/*** Frame buffer, holds current frame.*/final Bitmap mBuffer;final GifInfoHandle mNativeInfoHandle;final ConcurrentLinkedQueue<AnimationListener> mListeners = new ConcurrentLinkedQueue<>();private ColorStateList mTint;private PorterDuffColorFilter mTintFilter;private PorterDuff.Mode mTintMode;final boolean mIsRenderingTriggeredOnDraw;final InvalidationHandler mInvalidationHandler;private final RenderTask mRenderTask = new RenderTask(this);private final Rect mSrcRect;ScheduledFuture<?> mSchedule;/*** Creates drawable from resource.** @param res Resources to read from* @param id resource id (raw or drawable)* @throws NotFoundException if the given ID does not exist.* @throws IOException when opening failed* @throws NullPointerException if res is null*/public GifDrawable(@NonNull Resources res, @DrawableRes @RawRes int id) throws NotFoundException, IOException {this(res.openRawResourceFd(id));}...}
继续追踪openRawResourceFd()方法
/*** Open a file descriptor for reading a raw resource. This can only be used* with resources whose value is the name of an asset files -- that is, it can be* used to open drawable, sound, and raw resources; it will fail on string* and color resources.** <p>This function only works for resources that are stored in the package* as uncompressed data, which typically includes things like mp3 files* and png images.** @param id The resource identifier to open, as generated by the appt* tool.** @return AssetFileDescriptor A new file descriptor you can use to read* the resource. This includes the file descriptor itself, as well as the* offset and length of data where the resource appears in the file. A* null is returned if the file exists but is compressed.** @throws NotFoundException Throws NotFoundException if the given ID does not exist.**/public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {TypedValue value;synchronized (mAccessLock) {value = mTmpValue;if (value == null) {value = new TypedValue();} else {mTmpValue = null;}getValue(id, value, true);}try {return mAssets.openNonAssetFd(value.assetCookie, value.string.toString());} catch (Exception e) {NotFoundException rnf = new NotFoundException("File " + value.string.toString()+ " from drawable resource ID #0x"+ Integer.toHexString(id));rnf.initCause(e);throw rnf;} finally {synchronized (mAccessLock) {if (mTmpValue == null) {mTmpValue = value;}}}}
注意上面说的几行注释:
* <p>This function only works for resources that are stored in the package* as uncompressed data, which typically includes things like mp3 files* and png images.
很明显不支持gif,所以通过上面的解压缩和压缩,就很可能导致一些资源文件不能识别,所以尽量避免解压缩和压缩apk,而应该像Python脚本给的那样,直接向压缩包写入文件,避免不必要的麻烦。
# zip获取新建立的apk文件zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)# 初始化渠道信息empty_channel_file = "META-INF/xxxx_{channel}".format(channel = target_channel)# 写入渠道信息zipped.write(src_empty_file, empty_channel_file)