Set up Jni and JniGen and did a successfully test

This commit is contained in:
Kevin Rodrigues Borges
2025-09-12 02:16:20 +01:00
parent 1939b0fd08
commit ad1dda5100
157 changed files with 11623 additions and 6 deletions

102
lib/aniyomi_bridge.dart Normal file
View File

@@ -0,0 +1,102 @@
import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;
import 'package:jni/jni.dart';
import 'package:k3vinb5_aniyomi_bridge/jmodels/janiyomibridge.dart';
import 'package:k3vinb5_aniyomi_bridge/jmodels/jsanime.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:archive/archive.dart';
class AniyomiBridge {
static final _aniyomiBridgeDir = "aniyomibridge";
static final _packageAssetsDir = "packages/k3vinb5_aniyomi_bridge/assets";
Future<void> initJvm() async{
Directory supportDirectory = await getApplicationSupportDirectory();
_loadJreIfNeeded(supportDirectory);
_loadJarIfNeeded(supportDirectory);
Jni.spawn(
dylibDir: _getDylibDir(supportDirectory),
classPath: _getClassPath(supportDirectory)
);
JAniyomiBridge.init();
JAniyomiBridge jAniyomiBridge = JAniyomiBridge();
jAniyomiBridge.loadExtension(JString.fromString("https://gitea.k3vinb5.dev/Backups/kohi-den-extensions/raw/branch/main/apk/aniyomi-en.allanime-v14.37.apk"));
JList<JObject?>? searchResults = jAniyomiBridge.getSearchResults(JString.fromString("Naruto"), 1, JString.fromString("allanime"));
print("Search results size: ${searchResults?.length}");
if (searchResults != null) {
for (JObject obj in searchResults.cast()) {
print(obj.toString());
JSAnime jsAnime = obj.as<JSAnime>(JSAnime.type);
print(jsAnime.getTitle().toDartString());
print(jsAnime.getUrl().toDartString());
}
}
}
String _getDylibDir(Directory supportDirectory) {
String basePath = path.join(supportDirectory.absolute.path, _aniyomiBridgeDir);
if (Platform.isLinux) {
return path.join(basePath, "jre", "linux", "customjre", "lib", "server");
} else if (Platform.isMacOS) {
return path.join(basePath, "jre", "macos", "customjre", "lib", "server");
} else if (Platform.isWindows) {
return path.join(basePath, "jre", "windows", "customjre", "lib", "server");
} else {
throw UnsupportedError("Unsupported platform");
}
}
List<String> _getClassPath(Directory supportDirectory) {
return [path.join(supportDirectory.absolute.path, _aniyomiBridgeDir, "aniyomibridge-core.jar")];
}
Future<void> _loadJarIfNeeded(Directory supportDirectory) async {
String aniyomiBridgeCorePath = path.join(supportDirectory.path, _aniyomiBridgeDir, "aniyomibridge-core.jar");
File aniyomiBridgeCore = File(aniyomiBridgeCorePath);
if (!(await aniyomiBridgeCore.exists())) {
copyAssetToFile("$_packageAssetsDir/aniyomibridge-core.jar", aniyomiBridgeCorePath);
}
}
Future<void> _loadJreIfNeeded(Directory supportDirectory) async {
String zippedJrePath = path.join(supportDirectory.path, _aniyomiBridgeDir, "jre.zip");
File zippedJre = File(zippedJrePath);
if (!(await zippedJre.exists())) {
await copyAssetToFile("$_packageAssetsDir/jre.zip", zippedJrePath);
}
Directory jreDir = Directory(path.join(supportDirectory.path, _aniyomiBridgeDir, "jre"));
if (!(await jreDir.exists())) {
final bytes = await zippedJre.readAsBytes();
final jreArchive = ZipDecoder().decodeBytes(bytes);
await _unzipFileToDir(jreArchive, "jre", jreDir.path);
zippedJre.deleteSync(recursive: false);
}
}
Future<void> _unzipFileToDir(Archive archive, String archiveName, String outDirPath) async{
outDirPath = outDirPath.replaceAll("/$archiveName", "");
for (final file in archive) {
final filename = file.name;
if (file.isFile) {
final data = file.content as List<int>;
final outFile = File(path.join(outDirPath, filename));
await outFile.parent.create(recursive: true);
await outFile.writeAsBytes(data);
} else {
await Directory(path.join(outDirPath, filename)).create(recursive: true);
}
}
}
Future<File> copyAssetToFile(String assetPath, String outPath) async {
final byteData = await rootBundle.load(assetPath);
final buffer = byteData.buffer.asUint8List();
final file = File(outPath);
await file.parent.create(recursive: true);
await file.writeAsBytes(buffer, flush: true);
return file;
}
}

View File

@@ -0,0 +1,434 @@
// AUTO GENERATED BY JNIGEN 0.14.2. DO NOT EDIT!
// ignore_for_file: annotate_overrides
// ignore_for_file: argument_type_not_assignable
// ignore_for_file: camel_case_extensions
// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: comment_references
// ignore_for_file: doc_directive_unknown
// ignore_for_file: file_names
// ignore_for_file: inference_failure_on_untyped_parameter
// ignore_for_file: invalid_internal_annotation
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: library_prefixes
// ignore_for_file: lines_longer_than_80_chars
// ignore_for_file: no_leading_underscores_for_library_prefixes
// ignore_for_file: no_leading_underscores_for_local_identifiers
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: only_throw_errors
// ignore_for_file: overridden_fields
// ignore_for_file: prefer_double_quotes
// ignore_for_file: unintended_html_in_doc_comment
// ignore_for_file: unnecessary_cast
// ignore_for_file: unnecessary_non_null_assertion
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: unused_element
// ignore_for_file: unused_field
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: unused_shown_name
// ignore_for_file: use_super_parameters
import 'dart:core' show Object, String, bool, double, int;
import 'dart:core' as core$_;
import 'package:jni/_internal.dart' as jni$_;
import 'package:jni/jni.dart' as jni$_;
/// from: `dev.k3vinb5.aniyomibridge.AniyomiBridge`
class JAniyomiBridge extends jni$_.JObject {
@jni$_.internal
@core$_.override
final jni$_.JObjType<JAniyomiBridge> $type;
@jni$_.internal
JAniyomiBridge.fromReference(jni$_.JReference reference)
: $type = type,
super.fromReference(reference);
static final _class = jni$_.JClass.forName(
r'dev/k3vinb5/aniyomibridge/AniyomiBridge',
);
/// The type which includes information such as the signature of this class.
static const nullableType = $AniyomiBridge$NullableType();
static const type = $AniyomiBridge$Type();
static final _id_COROUTINE_UTILS = _class.staticFieldId(
r'COROUTINE_UTILS',
r'Ldev/k3vinb5/aniyomibridge/utils/CoroutineUtils;',
);
/// from: `static public final dev.k3vinb5.aniyomibridge.utils.CoroutineUtils COROUTINE_UTILS`
/// The returned object must be released after use, by calling the [release] method.
static jni$_.JObject? get COROUTINE_UTILS =>
_id_COROUTINE_UTILS.get(_class, const jni$_.JObjectNullableType());
static final _id_new$ = _class.constructorId(r'()V');
static final _new$ =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>
>('globalEnv_NewObject')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>();
/// from: `public void <init>()`
/// The returned object must be released after use, by calling the [release] method.
factory JAniyomiBridge() {
return JAniyomiBridge.fromReference(
_new$(_class.reference.pointer, _id_new$ as jni$_.JMethodIDPtr).reference,
);
}
static final _id_init = _class.staticMethodId(r'init', r'()V');
static final _init =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>
>('globalEnv_CallStaticVoidMethod')
.asFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>();
/// from: `static public void init()`
static void init() {
_init(_class.reference.pointer, _id_init as jni$_.JMethodIDPtr).check();
}
static final _id_loadExtension = _class.instanceMethodId(
r'loadExtension',
r'(Ljava/lang/String;)V',
);
static final _loadExtension =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<(jni$_.Pointer<jni$_.Void>,)>,
)
>
>('globalEnv_CallVoidMethod')
.asFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.Pointer<jni$_.Void>,
)
>();
/// from: `public void loadExtension(java.lang.String string)`
void loadExtension(jni$_.JString? string) {
final _$string = string?.reference ?? jni$_.jNullReference;
_loadExtension(
reference.pointer,
_id_loadExtension as jni$_.JMethodIDPtr,
_$string.pointer,
).check();
}
static final _id_loadExtensionFile = _class.instanceMethodId(
r'loadExtensionFile',
r'(Ljava/lang/String;Ljava/lang/String;)V',
);
static final _loadExtensionFile =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<
(jni$_.Pointer<jni$_.Void>, jni$_.Pointer<jni$_.Void>)
>,
)
>
>('globalEnv_CallVoidMethod')
.asFunction<
jni$_.JThrowablePtr Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.Pointer<jni$_.Void>,
jni$_.Pointer<jni$_.Void>,
)
>();
/// from: `public void loadExtensionFile(java.lang.String string, java.lang.String string1)`
void loadExtensionFile(jni$_.JString? string, jni$_.JString? string1) {
final _$string = string?.reference ?? jni$_.jNullReference;
final _$string1 = string1?.reference ?? jni$_.jNullReference;
_loadExtensionFile(
reference.pointer,
_id_loadExtensionFile as jni$_.JMethodIDPtr,
_$string.pointer,
_$string1.pointer,
).check();
}
static final _id_getLoadedExtensions = _class.instanceMethodId(
r'getLoadedExtensions',
r'()Ljava/util/List;',
);
static final _getLoadedExtensions =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>
>('globalEnv_CallObjectMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
)
>();
/// from: `public java.util.List<java.lang.String> getLoadedExtensions()`
/// The returned object must be released after use, by calling the [release] method.
jni$_.JList<jni$_.JString?>? getLoadedExtensions() {
return _getLoadedExtensions(
reference.pointer,
_id_getLoadedExtensions as jni$_.JMethodIDPtr,
).object<jni$_.JList<jni$_.JString?>?>(
const jni$_.JListNullableType<jni$_.JString?>(
jni$_.JStringNullableType(),
),
);
}
static final _id_getSearchResults = _class.instanceMethodId(
r'getSearchResults',
r'(Ljava/lang/String;ILjava/lang/String;)Ljava/util/List;',
);
static final _getSearchResults =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<
(
jni$_.Pointer<jni$_.Void>,
jni$_.Int32,
jni$_.Pointer<jni$_.Void>,
)
>,
)
>
>('globalEnv_CallObjectMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.Pointer<jni$_.Void>,
int,
jni$_.Pointer<jni$_.Void>,
)
>();
/// from: `public java.util.List<eu.kanade.tachiyomi.animesource.model.SAnime> getSearchResults(java.lang.String string, int i, java.lang.String string1)`
/// The returned object must be released after use, by calling the [release] method.
jni$_.JList<jni$_.JObject?>? getSearchResults(
jni$_.JString? string,
int i,
jni$_.JString? string1,
) {
final _$string = string?.reference ?? jni$_.jNullReference;
final _$string1 = string1?.reference ?? jni$_.jNullReference;
return _getSearchResults(
reference.pointer,
_id_getSearchResults as jni$_.JMethodIDPtr,
_$string.pointer,
i,
_$string1.pointer,
).object<jni$_.JList<jni$_.JObject?>?>(
const jni$_.JListNullableType<jni$_.JObject?>(
jni$_.JObjectNullableType(),
),
);
}
static final _id_getEpisodeList = _class.instanceMethodId(
r'getEpisodeList',
r'(Leu/kanade/tachiyomi/animesource/model/SAnime;Ljava/lang/String;)Ljava/util/List;',
);
static final _getEpisodeList =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<
(jni$_.Pointer<jni$_.Void>, jni$_.Pointer<jni$_.Void>)
>,
)
>
>('globalEnv_CallObjectMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.Pointer<jni$_.Void>,
jni$_.Pointer<jni$_.Void>,
)
>();
/// from: `public java.util.List<eu.kanade.tachiyomi.animesource.model.SEpisode> getEpisodeList(eu.kanade.tachiyomi.animesource.model.SAnime sAnime, java.lang.String string)`
/// The returned object must be released after use, by calling the [release] method.
jni$_.JList<jni$_.JObject?>? getEpisodeList(
jni$_.JObject? sAnime,
jni$_.JString? string,
) {
final _$sAnime = sAnime?.reference ?? jni$_.jNullReference;
final _$string = string?.reference ?? jni$_.jNullReference;
return _getEpisodeList(
reference.pointer,
_id_getEpisodeList as jni$_.JMethodIDPtr,
_$sAnime.pointer,
_$string.pointer,
).object<jni$_.JList<jni$_.JObject?>?>(
const jni$_.JListNullableType<jni$_.JObject?>(
jni$_.JObjectNullableType(),
),
);
}
static final _id_getVideoList = _class.instanceMethodId(
r'getVideoList',
r'(Leu/kanade/tachiyomi/animesource/model/SEpisode;Ljava/lang/String;)Ljava/util/List;',
);
static final _getVideoList =
jni$_.ProtectedJniExtensions.lookup<
jni$_.NativeFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.VarArgs<
(jni$_.Pointer<jni$_.Void>, jni$_.Pointer<jni$_.Void>)
>,
)
>
>('globalEnv_CallObjectMethod')
.asFunction<
jni$_.JniResult Function(
jni$_.Pointer<jni$_.Void>,
jni$_.JMethodIDPtr,
jni$_.Pointer<jni$_.Void>,
jni$_.Pointer<jni$_.Void>,
)
>();
/// from: `public java.util.List<eu.kanade.tachiyomi.animesource.model.Video> getVideoList(eu.kanade.tachiyomi.animesource.model.SEpisode sEpisode, java.lang.String string)`
/// The returned object must be released after use, by calling the [release] method.
jni$_.JList<jni$_.JObject?>? getVideoList(
jni$_.JObject? sEpisode,
jni$_.JString? string,
) {
final _$sEpisode = sEpisode?.reference ?? jni$_.jNullReference;
final _$string = string?.reference ?? jni$_.jNullReference;
return _getVideoList(
reference.pointer,
_id_getVideoList as jni$_.JMethodIDPtr,
_$sEpisode.pointer,
_$string.pointer,
).object<jni$_.JList<jni$_.JObject?>?>(
const jni$_.JListNullableType<jni$_.JObject?>(
jni$_.JObjectNullableType(),
),
);
}
}
final class $AniyomiBridge$NullableType extends jni$_.JObjType<JAniyomiBridge?> {
@jni$_.internal
const $AniyomiBridge$NullableType();
@jni$_.internal
@core$_.override
String get signature => r'Ldev/k3vinb5/aniyomibridge/AniyomiBridge;';
@jni$_.internal
@core$_.override
JAniyomiBridge? fromReference(jni$_.JReference reference) =>
reference.isNull ? null : JAniyomiBridge.fromReference(reference);
@jni$_.internal
@core$_.override
jni$_.JObjType get superType => const jni$_.JObjectNullableType();
@jni$_.internal
@core$_.override
jni$_.JObjType<JAniyomiBridge?> get nullableType => this;
@jni$_.internal
@core$_.override
final superCount = 1;
@core$_.override
int get hashCode => ($AniyomiBridge$NullableType).hashCode;
@core$_.override
bool operator ==(Object other) {
return other.runtimeType == ($AniyomiBridge$NullableType) &&
other is $AniyomiBridge$NullableType;
}
}
final class $AniyomiBridge$Type extends jni$_.JObjType<JAniyomiBridge> {
@jni$_.internal
const $AniyomiBridge$Type();
@jni$_.internal
@core$_.override
String get signature => r'Ldev/k3vinb5/aniyomibridge/AniyomiBridge;';
@jni$_.internal
@core$_.override
JAniyomiBridge fromReference(jni$_.JReference reference) =>
JAniyomiBridge.fromReference(reference);
@jni$_.internal
@core$_.override
jni$_.JObjType get superType => const jni$_.JObjectNullableType();
@jni$_.internal
@core$_.override
jni$_.JObjType<JAniyomiBridge?> get nullableType =>
const $AniyomiBridge$NullableType();
@jni$_.internal
@core$_.override
final superCount = 1;
@core$_.override
int get hashCode => ($AniyomiBridge$Type).hashCode;
@core$_.override
bool operator ==(Object other) {
return other.runtimeType == ($AniyomiBridge$Type) &&
other is $AniyomiBridge$Type;
}
}

1819
lib/jmodels/jsanime.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
}

0
lib/main.dart Normal file
View File