You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
load assets and bitmaps directly from apk
This commit is contained in:
@@ -103,4 +103,12 @@ void set_up_handle_cache(JNIEnv *env, char *apk_main_activity_class)
|
|||||||
handle_cache.view.setLayoutParams = _METHOD(handle_cache.view.class, "setLayoutParams", "(Landroid/view/ViewGroup$LayoutParams;)V");
|
handle_cache.view.setLayoutParams = _METHOD(handle_cache.view.class, "setLayoutParams", "(Landroid/view/ViewGroup$LayoutParams;)V");
|
||||||
if((*env)->ExceptionCheck(env))
|
if((*env)->ExceptionCheck(env))
|
||||||
(*env)->ExceptionDescribe(env);
|
(*env)->ExceptionDescribe(env);
|
||||||
|
|
||||||
|
handle_cache.asset_manager.class = _REF((*env)->FindClass(env, "android/content/res/AssetManager"));
|
||||||
|
handle_cache.asset_manager.extractFromAPK = _STATIC_METHOD(handle_cache.asset_manager.class, "extractFromAPK", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||||
|
}
|
||||||
|
|
||||||
|
void extract_from_apk(const char *path, const char *target) {
|
||||||
|
JNIEnv *env = get_jni_env();
|
||||||
|
(*env)->CallStaticObjectMethod(env, handle_cache.asset_manager.class, handle_cache.asset_manager.extractFromAPK, _JSTRING(path), _JSTRING(target));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ struct handle_cache {
|
|||||||
jclass class;
|
jclass class;
|
||||||
jmethodID setLayoutParams;
|
jmethodID setLayoutParams;
|
||||||
} view;
|
} view;
|
||||||
|
struct {
|
||||||
|
jclass class;
|
||||||
|
jmethodID extractFromAPK;
|
||||||
|
} asset_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct handle_cache handle_cache;
|
extern struct handle_cache handle_cache;
|
||||||
@@ -76,5 +80,6 @@ extern struct handle_cache handle_cache;
|
|||||||
const char * attribute_set_get_string(JNIEnv *env, jobject attrs, char *attribute, char *schema);
|
const char * attribute_set_get_string(JNIEnv *env, jobject attrs, char *attribute, char *schema);
|
||||||
int attribute_set_get_int(JNIEnv *env, jobject attrs, char *attribute, char *schema, int default_value);
|
int attribute_set_get_int(JNIEnv *env, jobject attrs, char *attribute, char *schema, int default_value);
|
||||||
void set_up_handle_cache(JNIEnv *env, char *apk_main_activity_class);
|
void set_up_handle_cache(JNIEnv *env, char *apk_main_activity_class);
|
||||||
|
void extract_from_apk(const char *path, const char *target);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,16 +27,23 @@ import org.xmlpull.v1.XmlPullParserFactory;
|
|||||||
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to an application's raw asset files; see {@link Resources}
|
* Provides access to an application's raw asset files; see {@link Resources}
|
||||||
@@ -327,6 +334,7 @@ public final class AssetManager {
|
|||||||
*/
|
*/
|
||||||
public final InputStream open(String fileName, int accessMode) throws IOException {
|
public final InputStream open(String fileName, int accessMode) throws IOException {
|
||||||
int asset;
|
int asset;
|
||||||
|
// try loading from filesystem
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (!mOpen) {
|
if (!mOpen) {
|
||||||
throw new RuntimeException("Assetmanager has been closed");
|
throw new RuntimeException("Assetmanager has been closed");
|
||||||
@@ -338,7 +346,8 @@ public final class AssetManager {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new FileNotFoundException("Asset file: " + fileName + ", errno: " + asset);
|
// alternatively load directly from APK
|
||||||
|
return ClassLoader.getSystemClassLoader().getResourceAsStream("assets/" + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final AssetFileDescriptor openFd(String fileName)
|
public final AssetFileDescriptor openFd(String fileName)
|
||||||
@@ -425,6 +434,7 @@ public final class AssetManager {
|
|||||||
*/
|
*/
|
||||||
public final InputStream openNonAsset(int cookie, String fileName, int accessMode) throws IOException {
|
public final InputStream openNonAsset(int cookie, String fileName, int accessMode) throws IOException {
|
||||||
int asset;
|
int asset;
|
||||||
|
// try loading from filesystem
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (!mOpen) {
|
if (!mOpen) {
|
||||||
throw new RuntimeException("Assetmanager has been closed");
|
throw new RuntimeException("Assetmanager has been closed");
|
||||||
@@ -436,7 +446,8 @@ public final class AssetManager {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new FileNotFoundException("Asset absolute file: " + fileName + ", errno: " + asset);
|
// alternatively load directly from APK
|
||||||
|
return ClassLoader.getSystemClassLoader().getResourceAsStream(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final AssetFileDescriptor openNonAssetFd(String fileName)
|
public final AssetFileDescriptor openNonAssetFd(String fileName)
|
||||||
@@ -663,6 +674,30 @@ public final class AssetManager {
|
|||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void extractFromAPK(String path, String target) throws IOException {
|
||||||
|
if (path.endsWith("/")) { // directory
|
||||||
|
try (JarFile apk = new JarFile(Context.this_application.getPackageCodePath())) {
|
||||||
|
Enumeration<JarEntry> entries = apk.entries();
|
||||||
|
while(entries.hasMoreElements()) {
|
||||||
|
JarEntry entry = entries.nextElement();
|
||||||
|
if (entry.getName().startsWith(path)) {
|
||||||
|
extractFromAPK(entry.getName(), entry.getName().replace(path, target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // single file
|
||||||
|
Path file = Paths.get(android.os.Environment.getExternalStorageDirectory().getPath(), target);
|
||||||
|
if (!Files.exists(file)) {
|
||||||
|
try(InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(path)) {
|
||||||
|
if(inputStream != null) {
|
||||||
|
Files.createDirectories(file.getParent());
|
||||||
|
Files.copy(inputStream, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the state in this asset manager is up-to-date with
|
* Determine whether the state in this asset manager is up-to-date with
|
||||||
* the files on the filesystem. If false is returned, you need to
|
* the files on the filesystem. If false is returned, you need to
|
||||||
|
|||||||
@@ -19,10 +19,15 @@ package android.graphics;
|
|||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public final class Bitmap {
|
public final class Bitmap {
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +116,18 @@ public final class Bitmap {
|
|||||||
} // FIXME
|
} // FIXME
|
||||||
|
|
||||||
Bitmap(String path) {
|
Bitmap(String path) {
|
||||||
pixbuf = native_bitmap_from_path(android.os.Environment.getExternalStorageDirectory().getPath() + "/" + path);
|
Path file = Paths.get(android.os.Environment.getExternalStorageDirectory().getPath(), path);
|
||||||
|
if (!Files.exists(file)) {
|
||||||
|
try (InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(path)) {
|
||||||
|
if (inputStream != null) {
|
||||||
|
Files.createDirectories(file.getParent());
|
||||||
|
Files.copy(inputStream, file);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pixbuf = native_bitmap_from_path(file.toString());
|
||||||
|
|
||||||
mIsMutable = false;
|
mIsMutable = false;
|
||||||
mIsPremultiplied = false;
|
mIsPremultiplied = false;
|
||||||
|
|||||||
@@ -330,6 +330,8 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h
|
|||||||
jmethodID loadLibrary_with_classloader = _METHOD(java_runtime_class, "loadLibrary", "(Ljava/lang/String;Ljava/lang/ClassLoader;)V");
|
jmethodID loadLibrary_with_classloader = _METHOD(java_runtime_class, "loadLibrary", "(Ljava/lang/String;Ljava/lang/ClassLoader;)V");
|
||||||
(*env)->CallVoidMethod(env, java_runtime, loadLibrary_with_classloader, _JSTRING("translation_layer_main"), class_loader);
|
(*env)->CallVoidMethod(env, java_runtime, loadLibrary_with_classloader, _JSTRING("translation_layer_main"), class_loader);
|
||||||
|
|
||||||
|
extract_from_apk("assets/", "assets/");
|
||||||
|
|
||||||
/* -- run the main activity's onCreate -- */
|
/* -- run the main activity's onCreate -- */
|
||||||
|
|
||||||
(*env)->CallVoidMethod(env, handle_cache.apk_main_activity.object, handle_cache.apk_main_activity.onCreate, NULL);
|
(*env)->CallVoidMethod(env, handle_cache.apk_main_activity.object, handle_cache.apk_main_activity.onCreate, NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user