[关闭]
@linux1s1s 2015-09-10T20:55:18.000000Z 字数 10343 阅读 3396

Android 多渠道打包方案问题记录及解决方案

AndroidBuild


Android 多渠道打包方案 中已经介绍了基本的思路和基本的源代码,这里给出实践过程出现的问题和解决思路。

首先如果你没有使用上篇博客中给出的Python脚本,而是自己写了shell脚本或者其他脚本,如果实现思路如下:

那么可能出现下面类似的问题:

  1. 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
  2. 09-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)
  3. 09-10 17:32:00.769: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)
  4. 09-10 17:32:00.769: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)
  5. 09-10 17:32:00.769: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)
  6. 09-10 17:32:00.769: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  7. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
  8. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
  9. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)
  10. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
  11. 09-10 17:32:00.769: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)
  12. 09-10 17:32:00.769: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)
  13. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)
  14. 09-10 17:32:00.769: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)
  15. 09-10 17:32:00.769: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)
  16. 09-10 17:32:00.769: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
  17. 09-10 17:32:00.769: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
  18. 09-10 17:32:00.769: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)
  19. 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
  20. 09-10 17:32:00.769: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)
  21. 09-10 17:32:00.769: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)
  22. 09-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)
  23. 09-10 17:32:00.769: W/System.err(2609): ... 16 more
  24. 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
  25. 09-10 17:32:00.769: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)
  26. 09-10 17:32:00.769: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)
  27. 09-10 17:32:00.769: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)
  28. 09-10 17:32:00.769: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)
  29. 09-10 17:32:00.769: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  30. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
  31. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
  32. 09-10 17:32:00.769: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)
  33. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
  34. 09-10 17:32:00.773: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)
  35. 09-10 17:32:00.773: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)
  36. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)
  37. 09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)
  38. 09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)
  39. 09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
  40. 09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
  41. 09-10 17:32:00.773: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)
  42. 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
  43. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)
  44. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)
  45. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)
  46. 09-10 17:32:00.773: W/System.err(2609): ... 16 more
  47. 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
  48. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1087)
  49. 09-10 17:32:00.773: W/System.err(2609): at pl.droidsonroids.gif.GifDrawable.<init>(GifDrawable.java:148)
  50. 09-10 17:32:00.773: W/System.err(2609): at com.android.activity.UserGuideActivity.onCreate(UserGuideActivity.java:73)
  51. 09-10 17:32:00.773: W/System.err(2609): at android.app.Activity.performCreate(Activity.java:5231)
  52. 09-10 17:32:00.773: W/System.err(2609): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  53. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
  54. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
  55. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.access$800(ActivityThread.java:135)
  56. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
  57. 09-10 17:32:00.773: W/System.err(2609): at android.os.Handler.dispatchMessage(Handler.java:102)
  58. 09-10 17:32:00.773: W/System.err(2609): at android.os.Looper.loop(Looper.java:136)
  59. 09-10 17:32:00.773: W/System.err(2609): at android.app.ActivityThread.main(ActivityThread.java:5001)
  60. 09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invokeNative(Native Method)
  61. 09-10 17:32:00.773: W/System.err(2609): at java.lang.reflect.Method.invoke(Method.java:515)
  62. 09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
  63. 09-10 17:32:00.773: W/System.err(2609): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
  64. 09-10 17:32:00.773: W/System.err(2609): at dalvik.system.NativeStart.main(Native Method)
  65. 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
  66. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFdNative(Native Method)
  67. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.AssetManager.openNonAssetFd(AssetManager.java:429)
  68. 09-10 17:32:00.773: W/System.err(2609): at android.content.res.Resources.openRawResourceFd(Resources.java:1084)
  69. 09-10 17:32:00.773: W/System.err(2609): ... 16 more

注意L2 行,问题在这里,看看前面一个代码栈,GifDrawable是第三方支持动态图的类库,所以溯本逐源到GifDrawable.java

  1. /**
  2. * A {@link Drawable} which can be used to hold GIF images, especially animations.
  3. * Basic GIF metadata can also be examined.
  4. *
  5. * @author koral--
  6. */
  7. public class GifDrawable extends Drawable implements Animatable, MediaPlayerControl {
  8. final ScheduledThreadPoolExecutor mExecutor;
  9. volatile boolean mIsRunning = true;
  10. long mNextFrameRenderTime = Long.MIN_VALUE;
  11. private final Rect mDstRect = new Rect();
  12. /**
  13. * Paint used to draw on a Canvas
  14. */
  15. protected final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
  16. /**
  17. * Frame buffer, holds current frame.
  18. */
  19. final Bitmap mBuffer;
  20. final GifInfoHandle mNativeInfoHandle;
  21. final ConcurrentLinkedQueue<AnimationListener> mListeners = new ConcurrentLinkedQueue<>();
  22. private ColorStateList mTint;
  23. private PorterDuffColorFilter mTintFilter;
  24. private PorterDuff.Mode mTintMode;
  25. final boolean mIsRenderingTriggeredOnDraw;
  26. final InvalidationHandler mInvalidationHandler;
  27. private final RenderTask mRenderTask = new RenderTask(this);
  28. private final Rect mSrcRect;
  29. ScheduledFuture<?> mSchedule;
  30. /**
  31. * Creates drawable from resource.
  32. *
  33. * @param res Resources to read from
  34. * @param id resource id (raw or drawable)
  35. * @throws NotFoundException if the given ID does not exist.
  36. * @throws IOException when opening failed
  37. * @throws NullPointerException if res is null
  38. */
  39. public GifDrawable(@NonNull Resources res, @DrawableRes @RawRes int id) throws NotFoundException, IOException {
  40. this(res.openRawResourceFd(id));
  41. }
  42. ...
  43. }

继续追踪openRawResourceFd()方法

  1. /**
  2. * Open a file descriptor for reading a raw resource. This can only be used
  3. * with resources whose value is the name of an asset files -- that is, it can be
  4. * used to open drawable, sound, and raw resources; it will fail on string
  5. * and color resources.
  6. *
  7. * <p>This function only works for resources that are stored in the package
  8. * as uncompressed data, which typically includes things like mp3 files
  9. * and png images.
  10. *
  11. * @param id The resource identifier to open, as generated by the appt
  12. * tool.
  13. *
  14. * @return AssetFileDescriptor A new file descriptor you can use to read
  15. * the resource. This includes the file descriptor itself, as well as the
  16. * offset and length of data where the resource appears in the file. A
  17. * null is returned if the file exists but is compressed.
  18. *
  19. * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
  20. *
  21. */
  22. public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {
  23. TypedValue value;
  24. synchronized (mAccessLock) {
  25. value = mTmpValue;
  26. if (value == null) {
  27. value = new TypedValue();
  28. } else {
  29. mTmpValue = null;
  30. }
  31. getValue(id, value, true);
  32. }
  33. try {
  34. return mAssets.openNonAssetFd(
  35. value.assetCookie, value.string.toString());
  36. } catch (Exception e) {
  37. NotFoundException rnf = new NotFoundException(
  38. "File " + value.string.toString()
  39. + " from drawable resource ID #0x"
  40. + Integer.toHexString(id));
  41. rnf.initCause(e);
  42. throw rnf;
  43. } finally {
  44. synchronized (mAccessLock) {
  45. if (mTmpValue == null) {
  46. mTmpValue = value;
  47. }
  48. }
  49. }
  50. }

注意上面说的几行注释:

  1. * <p>This function only works for resources that are stored in the package
  2. * as uncompressed data, which typically includes things like mp3 files
  3. * and png images.

很明显不支持gif,所以通过上面的解压缩和压缩,就很可能导致一些资源文件不能识别,所以尽量避免解压缩和压缩apk,而应该像Python脚本给的那样,直接向压缩包写入文件,避免不必要的麻烦。

  1. # zip获取新建立的apk文件
  2. zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)
  3. # 初始化渠道信息
  4. empty_channel_file = "META-INF/xxxx_{channel}".format(channel = target_channel)
  5. # 写入渠道信息
  6. zipped.write(src_empty_file, empty_channel_file)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注