@linux1s1s
2015-09-10T20:55:18.000000Z
字数 10343
阅读 3429
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 #0x7f020109
09-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 compressed
09-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 more
09-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 #0x7f02010a
09-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 compressed
09-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
09-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 #0x7f02010b
09-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 compressed
09-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)