Я работаю над приложением Android (под Android studio), которое позволяет пользователю запускать во время выполнения код "Java android".
Мои первые исследования помогли мне создать библиотеку из «MyClass.java», понятную для приложения Android.
- Используйте команду «Javac» для создания «MyClass.class» из «MyClass.java»
C: \ Program Files \ Android \ AndroidStudio \ jre \ bin \ javac -source 1.8 -target 1.8 -d "./" -classpath "C: \ Users \ user_account \ AppData \ Local \ Android \ Sdk \ platform \ android-27 \ android.jar" -bootclasspath "C: \ Program Files \ Android \ Android Studio \ jre \ jre \ lib \ rt.jar "" MyClass.java "
Преобразуйте этот "MyClass.class" в библиотеку Jar с помощью команды "Jar"
C: \ Program Files \ Android \ Android Studio \ jre \ bin \ jar cvf "MyClass.jar "com / YourPackage / MyClass.class
И, наконец, перевести его для системы Dalvik с помощью инструмента "dx"
, вызвать C: \ Users \ user_account \ AppData \ Local \ Android \ Sdk \ build-tools \ 27.0.3\ dx --dex --output "MyClass.dex" "MyClass.jar"
В приложении Android я могу вызвать метод внутри библиотеки с помощью:
final String libPath = Environment.getExternalStorageDirectory() + "/DexFile/MyClass.dex";
final File tmpDir = getDir("DexFile", 0);
DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
classToLoad = (Class<?>) classloader.loadClass("com.YourPackage.MyClass");
Object myInstance = classToLoad.newInstance();
Method mainMethod= classToLoad.getMethod("main");
mainMethod.invoke(myInstance);
Хитрость, этот код не работает, если вы не добавляете некоторые права доступа в свою главную:
/**
* Checks if the app has permission to write to device storage
* <p>
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
И в своем манифесте:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
На данный момент явозможность вызывать метод внутри моей пользовательской библиотеки.Но теперь мне нужно вызвать метод моей основной деятельности из библиотеки.Упрощенное представление моей проблемы:
Диаграмма моей проблемы
Первая проблема, которая мне нужна, это отклонение от точки зрения библиотеки, которую я хочу прикрепитьи сделать зависимость между моей библиотекой и моим приложением.Из-за этого я не нашел ничего, что могло бы мне помочь.Единственная идея, с которой я пришел, - это передать аргумент объекта моему «main ()» и вызвать метод внутри этого объекта, но это не сработает:
package com.YourPackage;
public class MyClass{
public void main(Object object){
try{
Class cls = obj.getClass();
Method mainMethod = cls.getMethod("methodToCall",null);
mainMethod.invoke(obj,null);
}catch(Exception e){}
}
}
Если у вас есть идеячтобы сделать это правильно, я буду рад услышать это.
Надеюсь, этот пост, по крайней мере, поможет людям, работающим с библиотекой "Dex" ... С уважением, маленький программист
Благодаря этой ссылке Как вызвать Javaметод, если имя метода указано в виде строки? Мое решение работает, даже если оно не совсем чистое.Причина, по которой мой код не работает, заключается в том, что я сохранил объект класса, если вы сделаете это непосредственно, ошибка исчезнет.Если есть какое-либо объяснение, приходите и комментируйте!
package com.YourPackage;
public class MyClass{
public void main(Object obj){
try{
Method mainMethod = obj.getClass().getMethod("methodToCall");
mainMethod.invoke(obj); // Works, invoke the right method
}catch(Exception e){}
}
}