Android App Bundle์ ํตํด ์์ฑ๋ Fresco๋ฅผ ์ฌ์ฉํ๋ ํ๋์ ์์ํ ๋ "libimagepipeline.so"๋ฅผ ์ฐพ์ง ๋ชปํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ถฉ๋ํฉ๋๋ค.
๋๋ ์๋ ์ด๊ฒ์ด minify, R8 ๋๋ Proguard์ ๋ฌธ์ ์ผ ์ ์๋ค๊ณ ์๊ฐํ์ง๋ง, ๊ทธ๊ฒ๋ค์ ๋ชจ๋ ๋นํ์ฑํํ๊ณ App Bundle์ ํตํด ๋น๋ํ ๋ ์ฌ์ ํ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๊ด์ฐฐํ์ต๋๋ค.
๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฌ์ฉํ๋ ์ฑ์ ๋ค๋ฅธ ๊ตฌ์ฑ ์์๋ฅผ ํ ์คํธํ์ง๋ง Fresco๊ฐ ํด๋น ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์ ๋๋ง ์์๋๋ก ์๋ํฉ๋๋ค.
๋ด๊ฐ ์ฐพ์ ์์์ ์ด์ง๋ง ์ด์์ ์ด์ง ์์ ์๋ฃจ์
์ ๋ค์ ๊ตฌ์ฑ์ ์ฌ์ฉํ์ฌ abi
๋ก APK ๋ถํ ์ ๋นํ์ฑํํ๋ ๊ฒ์ด์ง๋ง ๋ชจ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ํฌํจํ๋ฉด APK ํฌ๊ธฐ๊ฐ ํจ์ฌ ์ปค์ง๋๋ค.
android {
// Rest of your configuration here
bundle {
abi {
enableSplit false
}
}
}
์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ค์๊ณผ ๊ฐ์ต๋๊น? #2049
๋ค, ๋์ถฉ. ๊ทธ๋ฌ๋ ์ด ๋ฌธ์ ๋ ๊ด๋ จ์ด ์๋ ๋์
Fresco ๋๋ SoLoader์์ Android App Bundle์ ๋ํ ์ง์ ๋ถ์กฑ ๋ฐ
๊ทธ๋ฐ ์์ผ๋ก ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ถํ ํฉ๋๋ค.
๋ด๊ฐ ์ค์ํ ์ ์์ง๋ง ์ด ๋ฌธ์ ๋ ๋ด๊ฐ ์ฌ์ฉํ๋ ๋ชจ๋ ๊ธฐ๊ธฐ์์ ์ฌํํ ์ ์์ต๋๋ค.
ํ
์คํธ๋ฅผ ๊ฑฐ์น ๋ธ๋๋๋ง์ด ์๋๋๋ค.
๊ทธ๋ฆฌ๊ณ Fresco ๋ฐฐ์ก ๊ฐ์ด๋์ ๋ฐ๋ผ ์ฌ์ฉ ์ฌ๋ก์ ๋ํ ๋ฉ๋ชจ๊ฐ ์์ต๋๋ค.
Android App Bundle์ ํตํด ๋ฐฐ์ก๋๋ฉฐ splits
ํค๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
bundle
ํ๋ฉด splits
ํค๊ฐ ๋ฌด์๋ฉ๋๋ค.
2018๋ 12์ 11์ผ ํ, 06:40 KimiChiu, [email protected] ์์ฑ:
์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ค์๊ณผ ๊ฐ์ต๋๊น? #2049
https://github.com/facebook/fresco/issues/2049โ
์ค๋ ๋๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/facebook/fresco/issues/2253#issuecomment-446089907 ,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ABUQnQ4cZ-sWkG5b72Ea81wiQjS02yjlks5u31NxgaJpZM4ZIsuf
.
์๋ ํ์ธ์ @icerfish ์ ๋๋ค .
ํ์ํ ๋ชจ๋ ์ธ๋ถ์ ๋ณด์ ํจ๊ป ์ด ๋ฌธ์ ๋ฅผ ์ ์ถํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค(์๊ฐ์ด ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ถ์ฌ๋ฃ์ ์ ์์). Fresco๊ฐ ์ฑ ๋ฒ๋ค์ ์์ ํ ์ง์ํ์ง ์์ ์ ์์ผ๋ฉฐ ์ํธ ์์ฉ์ ํ ์คํธํ ์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ์คํ ์์ค ์ปค๋ฎค๋ํฐ๊ฐ ์ฐ๋ฆฌ๋ฅผ ๋์ธ ์ ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ ์ด๊ฒ์ "๋ฒ๊ทธ" ๋ฐ "๋์์ด ํ์ํ" ๊ฒ์ผ๋ก ํ์ํ ๊ฒ์ ๋๋ค.
์๋ ํ์ธ์ @lambdapioneer ์ ๋๋ค .
๋ค์์ ์คํ ์ถ์ ์ ๋๋ค.
FATAL EXCEPTION: FrescoIoBoundExecutor-8
Process: com.gobuzzvault.android, PID: 17499
java.lang.NoClassDefFoundError: com.facebook.imagepipeline.memory.NativeMemoryChunk
at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:25)
at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:13)
at com.facebook.imagepipeline.memory.BasePool.get(BasePool.java:267)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferOutputStream.<init>(MemoryPooledByteBufferOutputStream.java:51)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferFactory.newByteBuffer(MemoryPooledByteBufferFactory.java:73)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferFactory.newByteBuffer(MemoryPooledByteBufferFactory.java:24)
at com.facebook.imagepipeline.producers.LocalFetchProducer.getByteBufferBackedEncodedImage(LocalFetchProducer.java:87)
at com.facebook.imagepipeline.producers.LocalFetchProducer.getEncodedImage(LocalFetchProducer.java:99)
at com.facebook.imagepipeline.producers.LocalContentUriFetchProducer.getCameraImage(LocalContentUriFetchProducer.java:100)
at com.facebook.imagepipeline.producers.LocalContentUriFetchProducer.getEncodedImage(LocalContentUriFetchProducer.java:76)
at com.facebook.imagepipeline.producers.LocalFetchProducer$1.getResult(LocalFetchProducer.java:52)
at com.facebook.imagepipeline.producers.LocalFetchProducer$1.getResult(LocalFetchProducer.java:48)
at com.facebook.common.executors.StatefulRunnable.run(StatefulRunnable.java:43)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:51)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.UnsatisfiedLinkError: couldn't find DSO to load: libimagepipeline.so
at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:703)
at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:564)
at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:500)
at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:455)
at com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader.load(ImagePipelineNativeLoader.java:40)
at com.facebook.imagepipeline.memory.NativeMemoryChunk.<clinit>(NativeMemoryChunk.java:31)
at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:25)
at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:13)
at com.facebook.imagepipeline.memory.BasePool.get(BasePool.java:267)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferOutputStream.<init>(MemoryPooledByteBufferOutputStream.java:51)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferFactory.newByteBuffer(MemoryPooledByteBufferFactory.java:73)
at com.facebook.imagepipeline.memory.MemoryPooledByteBufferFactory.newByteBuffer(MemoryPooledByteBufferFactory.java:24)
at com.facebook.imagepipeline.producers.LocalFetchProducer.getByteBufferBackedEncodedImage(LocalFetchProducer.java:87)
at com.facebook.imagepipeline.producers.LocalFetchProducer.getEncodedImage(LocalFetchProducer.java:99)
at com.facebook.imagepipeline.producers.LocalContentUriThumbnailFetchProducer.getThumbnail(LocalContentUriThumbnailFetchProducer.java:135)
at com.facebook.imagepipeline.producers.LocalContentUriThumbnailFetchProducer.getCameraImage(LocalContentUriThumbnailFetchProducer.java:100)
at com.facebook.imagepipeline.producers.LocalContentUriThumbnailFetchProducer.getEncodedImage(LocalContentUriThumbnailFetchProducer.java:75)
at com.facebook.imagepipeline.producers.LocalFetchProducer$1.getResult(LocalFetchProducer.java:52)ย
at com.facebook.imagepipeline.producers.LocalFetchProducer$1.getResult(LocalFetchProducer.java:48)ย
at com.facebook.common.executors.StatefulRunnable.run(StatefulRunnable.java:43)ย
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)ย
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)ย
at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:51)ย
at java.lang.Thread.run(Thread.java:764)
๋ค๋ฅธ ์ฌ๋๋ค์ด ๊ฒช๊ณ ์๋ ๋ฌธ์ ์ ์ ์ฌํด ๋ณด์ ๋๋ค.
์ฝ๋๋ฒ ์ด์ค๋ฅผ ๋๋ฌ๋ณด๋ฉด ์ด๊ฒ์ Fresco ์์ฒด์ ๋ฌธ์ ๊ฐ ์๋๋ผ SoLoader ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฌธ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ํด๋น ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ฌธ์ ๋ฅผ ๊ต์ฐจ ๊ฒ์ํ๊ณ ๋ฌธ์ ๊ฐ ์ ํํ ๋ฌด์์ธ์ง ์์๋ด๊ธฐ ์ํด ์๊ฐ์ ํ ์ ํ ์ ์๋ ์ํฌ๋ก๋๋ฅผ ํ์ฉํฉ๋๋ค.
์๋ ํ์ธ์, https://github.com/facebook/fresco/issues/2049#issuecomment -441088387์ ์ค๋ช ๋ ๋๋ก ์ฑ ๋ฒ๋ค์ ์ฌ์ฉํ ๋๋ ๋์ผํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
Fresco 1.11์ ์ฌ์ฉํ๊ณ Fresco์ ImagePipelineConfig์์ .experiment().setNativeCodeDisabled(true)
๋ฅผ ์ค์ ํ๋ฉด ์ ์ ์ด๋ฏธ์ง๊ฐ ์๋ํ์ง๋ง GIF๋ ๋ค๋ฅธ ์คํ ์ถ์ ์ผ๋ก ์ถฉ๋ํ๊ณ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋์ผํ SoLoader ๋ฌธ์ ์ฒ๋ผ ๋ณด์์ต๋๋ค. @icerfish , GIF๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
Fresco์์ ์ฌ์ฉํ๋ SoLoader lib์์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ์์ ์ผ๋ก PR์ ์ค๋นํ์ต๋๋ค: facebook/soloader#26
์ด ์์ ์ผ๋ก fresco๋ App Bundle์์ ์ ์๋ํฉ๋๋ค.
ํจ์น๋ ๋ฒ์ ์ SoLoader lib๋ฅผ ๊ฒ์ํ์ต๋๋ค. PR์ด ๋ณํฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์๋ค๋ฉด ํ๋ก์ ํธ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
repositories {
maven {
url "https://dl.bintray.com/nnesterov/maven"
}
}
compile('com.facebook.fresco:fresco:1.10.0') {
exclude group: 'com.facebook.soloader', module: 'soloader'
}
compile("com.avito.android:patched-soloader:0.1.0")
ํจ์น๋ soloader์ ์ด์ ๋ฒ์ ์ ๋กค๋ฆฌํ ์ด์ ์ฅ์น์์ ์๋ํ์ง ์์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๊ณ ์ณค๋ค. ์ฌ์ฉํ๋ค
compile("com.avito.android:patched-soloader:0.1.1")
@nesterov-n ํ๋ฅญํ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ํ๋ ์ค์ฝ์ ํตํฉํ๋ ๋ฐ ์ง์ ์ด ์์ต๋๊น?
@nesterov-n ์ ๋ ๊ฐ์ ๋ฌธ์ ์ ์ง๋ฉดํ๊ณ ์์ต๋๋ค. ์ธ์ ํ๋ ์ค์ฝ์ ํตํฉ๋๋์ง ์๋ ค์ฃผ์ญ์์ค.
์๋
ํ์ธ์ @theromis ์ @sailesh2์
๋๋ค.
๋๋ ํ์ด์ค๋ถ์์ ์ผํ์ง ์๋๋ค(๋๋ฌด ์ฌํ๋ค). ๋๋ ๋จ์ง Fresco ์ฌ์ฉ์์ด์ง๋ง ์์ ์ ๊ธฐ๋ค๋ฆด ์ ์์์ต๋๋ค. ๊ทธ๋์ ๋๋ฒ๊น
ํ๊ณ ์์ ํด์ผํ์ต๋๋ค.
ํ์ฌ ์์ ์ค๋ช
์์ ์ค๋ช
ํ ๋๋ก ๋ด ํ๋ก์ ํธ์ ํจ์น๋ ๋ฒ์ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ต์ ๋ฒ์ ์ com.avito.android:patched-soloader:0.1.2
ํ์ฌ soloader lib์ ๋ํ ๋ด PR์ ๊ฒํ ํ๊ณ ์์ง๋ง soloader ์ ์ง ๊ด๋ฆฌ์๋ ์๋ก์ด soloader lib ๋ฆด๋ฆฌ์ค์ ๋ํ ์์์ด ์๋ค๊ณ ๋งํฉ๋๋ค. ๋ฐ๋ผ์ Fresco๊ฐ ์ด ์ ๋ฒ์ ์ ์ธ์ ์ฌ์ฉํ ์ง ์์ธกํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๊ธํ ๊ฒฝ์ฐ ๋ด ํจ์น ๋ฒ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ๋ ์ค์ฝ๊ฐ ์๋ ๋ฒ๋ค์ ํ๋ก๋์ ์ ๊ฒ์ํ์ต๋๋ค. ์ ์๋ํฉ๋๋ค.
์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์์ง Fresco์ ํตํฉ๋์ง ์์ ์ด์ ๋ฅผ ์ ์ ์์ต๋๋ค.
SoLoader ์์ ์ฌํญ์ด ์ ์ฉ๋์์ต๋๋ค. SoLoader ๋ฒ์ ์ด ์ถ์๋๋ฉด ๊ณง ์๋ก์ด Fresco ๋ฒ์ ์ ์ถ์ํ ๊ฒ์ ๋๋ค.
@oprisnik ์ถ์
SoLoader v0.6.0์ด ๋ฐฉ๊ธ ๋ฆด๋ฆฌ์ค๋์์ผ๋ฉฐ Fresco ์ข ์์ฑ์ ์ ๋ฐ์ดํธํ์ต๋๋ค(6fc071d1892166d11d1f237f10e2d9bcdf858087). ์ฐ๋ฆฌ๋ MIT ๋ผ์ด์ผ์ค Bolts ๋ฆด๋ฆฌ์ค(#2257)๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์ถ์ต๋๋ค. ํด๋น ๋ฆด๋ฆฌ์ค๊ฐ ์์๋ณด๋ค ์ค๋ ๊ฑธ๋ฆฌ๋ฉด ์ง๊ธ์ ๊ฑด๋๋ฐ๊ณ ๋ฆด๋ฆฌ์คํ์ง ์๊ณ ๋ฆด๋ฆฌ์คํ ๊ฒ์ ๋๋ค. ์ด์จ๋ ์ ๋ฒ์ ์ ๋ฉฐ์น ์์ ๋์ฌ ๊ฒ์ ๋๋ค.
๋ํํ๊ณ ์ถ์ง ์์๋ฐ ํ๋ ์ค์ฝํ๋ ํ์ด์ผ ํ์ง ์๊ฒ ์ต๋๊น? ์ง์ ํ์ ์ด ๋ฌธ์ ๋ ํ๋์ ํ๋์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ณ ์ SoLoader ๋ฒ์ ์ด ํฌํจ๋ ๋ฒ์ 1.12.0 ์ ๋ฐฉ๊ธ ์ถ์ํ์ต๋๋ค.
ํ๋ก ๊ฐ๋ ์ถ๊ฐ ์๋
- @com.facebook.common.internal.DoNotStrip ํด๋์ค ์ ์ง *
-keepclassmembers ํด๋์ค * {
@com.facebook.common.internal.DoNotStrip *;
}
- @com.facebook.soloader.DoNotOptimize ํด๋์ค ์ ์ง *
-keepclassmembers ํด๋์ค * {
@com.facebook.soloader.DoNotOptimize *;
}
-keepclassmembers ํด๋์ค * {
ํ ์ข
์
}
- ์คํค์ค๋ฅผ ๊ฒฝ๊ณ ํ์ง ๋ง์ญ์์ค. *-dontwarn com.squareup.okhttp. *
-okhttp3๋ฅผ ๊ฒฝ๊ณ ํ์ง ๋ง์ญ์์ค. *-javax.annotation์ ๊ฒฝ๊ณ ํ์ง ์์ต๋๋ค. *
-dontwarn com.android.volley.toolbox. *-dontwarn com.facebook.infer. *
@ProHzen ์ด๊ฒ์ด soloader ์ถฉ๋์ ์์ ํ์ต๋๊น?
๋ค, ํด๊ฒฐํ์ต๋๋ค.
์ฌ์ ํ fresco 2.0.0์ ์์ต๋๋ค. :-(, ๋ฅ์์ค ์ฅ์น์๋ง ๋ฌธ์ ๊ฐ ์๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ์ํ์ญ์์ค.
@ProHzen ์๋
ํ์ธ์, ํผ๋ ๋ชฉ๋ก์ ์ ์๊ฒ ๋ณด๋ด์ฃผ์๊ฒ ์ต๋๊น?๋น์ ์ด ํ ๋ฐฉ์์ผ๋ก ์๋ํ์ง๋ง ์๋ํ์ง ์์์ต๋๋ค.
์ ๋ณด:
ํ๋ ์ค์ฝ:1.13.0
ํด๋์ค ๊ฒฝ๋ก 'com.android.tools. ๋น๋:๊ทธ๋ผ๋ค :3.5.1'
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
Fresco์์ ์ฌ์ฉํ๋ SoLoader lib์์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ์์ ์ผ๋ก PR์ ์ค๋นํ์ต๋๋ค: facebook/soloader#26
์ด ์์ ์ผ๋ก fresco๋ App Bundle์์ ์ ์๋ํฉ๋๋ค.
ํจ์น๋ ๋ฒ์ ์ SoLoader lib๋ฅผ ๊ฒ์ํ์ต๋๋ค. PR์ด ๋ณํฉ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์๋ค๋ฉด ํ๋ก์ ํธ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.