Java android: вызов метода main, внутри импортированной пользовательской библиотеки - PullRequest
0 голосов
/ 31 мая 2018

Я работаю над приложением Android (под Android studio), которое позволяет пользователю запускать во время выполнения код "Java android".

Мои первые исследования помогли мне создать библиотеку из «MyClass.java», понятную для приложения Android.

  1. Используйте команду «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){}
    }
}
...