build: compile release APK and update dependencies (expo-image-manipulator/loader)
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
<manifest>
|
||||
</manifest>
|
||||
Generated
Vendored
+105
@@ -0,0 +1,105 @@
|
||||
package expo.modules.imageloader
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import expo.modules.core.interfaces.InternalModule
|
||||
import expo.modules.interfaces.imageloader.ImageLoaderInterface
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.Future
|
||||
|
||||
class ImageLoaderModule(val context: Context) : InternalModule, ImageLoaderInterface {
|
||||
|
||||
override fun getExportedInterfaces(): List<Class<*>> {
|
||||
return listOf(ImageLoaderInterface::class.java)
|
||||
}
|
||||
|
||||
override fun loadImageForDisplayFromURL(url: String): Future<Bitmap> {
|
||||
val future = SimpleSettableFuture<Bitmap>()
|
||||
loadImageForDisplayFromURL(
|
||||
url,
|
||||
object : ImageLoaderInterface.ResultListener {
|
||||
override fun onSuccess(bitmap: Bitmap) = future.set(bitmap)
|
||||
|
||||
override fun onFailure(cause: Throwable?) =
|
||||
future.setException(ExecutionException(cause))
|
||||
}
|
||||
)
|
||||
return future
|
||||
}
|
||||
|
||||
override fun loadImageForDisplayFromURL(
|
||||
url: String,
|
||||
resultListener: ImageLoaderInterface.ResultListener
|
||||
) {
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(url)
|
||||
.into(object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
resultListener.onSuccess(resource)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
resultListener.onFailure(Exception("Loading bitmap failed"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun loadImageForManipulationFromURL(url: String): Future<Bitmap> {
|
||||
val future = SimpleSettableFuture<Bitmap>()
|
||||
loadImageForManipulationFromURL(
|
||||
url,
|
||||
object : ImageLoaderInterface.ResultListener {
|
||||
override fun onSuccess(bitmap: Bitmap) = future.set(bitmap)
|
||||
|
||||
override fun onFailure(cause: Throwable?) = future.setException(ExecutionException(cause))
|
||||
}
|
||||
)
|
||||
return future
|
||||
}
|
||||
|
||||
override fun loadImageForManipulationFromURL(
|
||||
url: String,
|
||||
resultListener: ImageLoaderInterface.ResultListener
|
||||
) {
|
||||
val normalizedUrl = normalizeAssetsUrl(url)
|
||||
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.load(normalizedUrl)
|
||||
.into(object : CustomTarget<Bitmap>() {
|
||||
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
||||
resultListener.onSuccess(resource)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
resultListener.onFailure(Exception("Loading bitmap failed"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun normalizeAssetsUrl(url: String): String {
|
||||
var actualUrl = url
|
||||
if (url.startsWith("asset:///")) {
|
||||
actualUrl = "file:///android_asset/" + url.split("/").last()
|
||||
}
|
||||
return actualUrl
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
package expo.modules.imageloader
|
||||
|
||||
import android.content.Context
|
||||
import expo.modules.core.BasePackage
|
||||
import expo.modules.core.interfaces.InternalModule
|
||||
|
||||
class ImageLoaderPackage : BasePackage() {
|
||||
override fun createInternalModules(context: Context): List<InternalModule> = listOf(ImageLoaderModule(context))
|
||||
}
|
||||
Generated
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
// Copied from React Native
|
||||
package expo.modules.imageloader;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* A super simple Future-like class that can safely notify another Thread when a value is ready.
|
||||
* Does not support canceling.
|
||||
*/
|
||||
public class SimpleSettableFuture<T> implements Future<T> {
|
||||
private final CountDownLatch mReadyLatch = new CountDownLatch(1);
|
||||
private @Nullable
|
||||
T mResult;
|
||||
private @Nullable
|
||||
Exception mException;
|
||||
|
||||
/**
|
||||
* Sets the result. If another thread has called {@link #get}, they will immediately receive the
|
||||
* value. set or setException must only be called once.
|
||||
*/
|
||||
public void set(@Nullable T result) {
|
||||
checkNotSet();
|
||||
mResult = result;
|
||||
mReadyLatch.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the exception. If another thread has called {@link #get}, they will immediately receive
|
||||
* the exception. set or setException must only be called once.
|
||||
*/
|
||||
public void setException(Exception exception) {
|
||||
checkNotSet();
|
||||
mException = exception;
|
||||
mReadyLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return mReadyLatch.getCount() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable
|
||||
T get() throws InterruptedException, ExecutionException {
|
||||
mReadyLatch.await();
|
||||
if (mException != null) {
|
||||
throw new ExecutionException(mException);
|
||||
}
|
||||
|
||||
return mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait up to the timeout time for another Thread to set a value on this future. If a value has
|
||||
* already been set, this method will return immediately.
|
||||
*
|
||||
* <p>NB: For simplicity, we catch and wrap InterruptedException. Do NOT use this class if you are
|
||||
* in the 1% of cases where you actually want to handle that.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable
|
||||
T get(long timeout, TimeUnit unit)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (!mReadyLatch.await(timeout, unit)) {
|
||||
throw new TimeoutException("Timed out waiting for result");
|
||||
}
|
||||
if (mException != null) {
|
||||
throw new ExecutionException(mException);
|
||||
}
|
||||
|
||||
return mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for {@link #get()} that re-throws get()'s Exceptions as RuntimeExceptions.
|
||||
*/
|
||||
public @Nullable
|
||||
T getOrThrow() {
|
||||
try {
|
||||
return get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for {@link #get(long, TimeUnit)} that re-throws get()'s Exceptions as
|
||||
* RuntimeExceptions.
|
||||
*/
|
||||
public @Nullable
|
||||
T getOrThrow(long timeout, TimeUnit unit) {
|
||||
try {
|
||||
return get(timeout, unit);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNotSet() {
|
||||
if (mReadyLatch.getCount() == 0) {
|
||||
throw new RuntimeException("Result has already been set!");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user