Java вызывает плагин NDK, который вызывает собственную Java со слушателем

У меня есть плагин C++ NDK (.so), который я хочу изменить макет Activity на Android. Этот плагин должен поддерживать push-уведомления и интерфейс слушателя.

Я знаю, что для этого мне нужно использовать интерфейс JNI, чтобы инициировать запросы к Java, а также получать события обратно от элементов пользовательского интерфейса. Однако где я застрял, так это то, как мой C++ имеет доступ к JVM или JEnv должным образом и за его пределами.

Предупреждение весь псудо-код. Мои вопросы и недоумение - в слове.

public class MyActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new TestRenderer().Start()
    }
}

class TestRenderer {
    // Messages to the plugin.
    void native Start();

    // Messages from the plugin.
    void OnCreated() {
        // Do something.
    }

    static {
        System.loadLibrary("testrenderer");
    }
}

Который затем вызовет JNI

JNIEXPORT void JNICALL Java_TestRenderer_Start(JNIEnv* env, jobject obj)
{
    // Create my C++ class that does all the work!
    TestRenderer renderer = new TestRenderer();
    renderer.Start();
}

Однако, когда приходит время для моего C++ TestRenderer вызывать его собственную Java, здесь я рисую пробел относительно того, что здесь делать.

class TestRenderer
{
public:
    ...
    void Start()
    {
        // Create a relative view.
        CreateRelativeView();
    }

private:
    void CreateRelativeView()
    {
        // JNI create my java class and find method.
        // Call method against against that Java class.
        // What JVM, JEnv, or jobject should I use?
        // AT THIS EXACT POINT I NEED ACCESS TO THE ACTIVITY CONTEXT.
        // new CustomView(context); <--- ?????
    }

    // Also, how do I ensure I call OnCreated on the right Java object.
    void OnCreated()
    {
        ...
        // Call method against Java TestRenderer on the right jobject.
    }
};

Теперь о Java плагина

public class CustomView extends RelativeLayout {
    public CustomView(Context context) {
        super(context);

        // Call back into native
        OnCreated();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Call back into native
        OnCreated();
    }

    // My listener call I would want invoked to go back through plugin to client.
    public native OnCreated();

    static {
        // I assume back to the same plugin?
        System.loadLibrary("testrenderer");
    }
}

Я знаю, что это звучит запутанно, но если я смогу пройти через нативный на среднем уровне, это решит так много проблем с общим кодом на других платформах. Я чувствую, что это вполне возможно, но я рисую пустое место.

Заранее спасибо.

JavaVM* безопасно кэшировать, поэтому вы можете взять тот, который вы получили в JNI_OnLoad, и сохранить его в глобальной переменной. JNIEnv* безопасен для кэширования нет, поэтому для получения действительного JNIEnv* из произвольного потока требуется немного времени. См. этот ответ.

Michael 04.06.2018 10:01

Я понимаю. Итак, исходя из того, что вы сказали, похоже, что лучшим подходом было бы сохранить Activity в каком-то одноэлементном значении, которое будет извлечено из GetEnv / AttachCurrentThread, которое использует кешированную JavaVM из JNI_OnLoad. Это также звучит так, как будто в идеале я хотел бы кэшировать этот созданный мной проект для поддержания срока службы CustomView, созданного из нативного ... Как мне узнать, какой CustomView соответствует какому TestRenderer? Я предполагаю, что я буду реализовывать JNI для «общедоступного встроенного OnCreated ();» а будет какой способ сравнить проекты?

gravityab 04.06.2018 21:00
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
91
0

Другие вопросы по теме