6
votes

Mise à jour de l'interface utilisateur du fil d'arrière-plan à l'aide de code natif entièrement (pas de JNI)?

J'écris une application Android qui fait une grande partie d'un traitement dans le fil d'arrière-plan. Les calculs sont effectués dans le code natif à l'aide de C ++. Je veux mettre à jour l'interface utilisateur avec les résultats partiels lors des calculs.

Je suis capable de le faire via JNI, nommément référencez-vous à l'objet UI en Java, puis appelez une méthode de cet objet à partir de l'auge de code natif JNI. Je cherche une solution plus efficace sans appels JNI dans la partie Rendu (la configuration de base et un point d'entrée d'activation devront être en Java).

est-il possible de modifier le fil d'exécution de l'arrière-plan à UI entièrement dans le code natif sans utiliser JNI (uniquement dans la partie Rendu)?

Merci pour vos réponses. Très appréciée.

EDIT: J'envisage d'utiliser OpenGL pour rendre le contenu calculé (type de cadres vidéo) à mon avis. Dans ce cas, je voudrais probablement utiliser EGLSwapbuffers () Méthode disponible dans la bibliothèque EGL à partir de 2.3. Je pense que le plus gros problème est, je pense, comment passer facilement de l'arrière-plan "Calcul" sur le fil "Ouvrir GL" de l'UI dans un code natif sans front de front de Jni. Que recommanderais-tu? Merci pour votre aide!

pseudocode: Voici un pseudocode qui aide à illustrer ce que je veux atteindre ici. Cela ressemble plus à un problème de filetage, mais la framework Android entre en jeu. xxx

EDIT 2: Au fur et à mesure que la prime s'appuie lentement sur la fermeture, une plus grande clarification. Il y a quelques façons d'appeler la méthode updateDateGL ci-dessus. Le plus typique est d'utiliser glsurfaceview dans le code Java. Il faudrait définir un rendu ( Setrenderer () ) puis remplacer ONDRAWFRAME avec un code pour appeler la couche JNI / natif. Cette façon pour chaque image étant rendue un appel JNI est exécuté.

Je voudrais faire le rendu un peu différemment. Je veux appeler updategl sans utiliser le code Java / JNI et utiliser uniquement la couche natale (comme présentée dans l'extrait ci-dessus). Le plus gros problème pour moi est maintenant comment exécuter le updateCategl sur le thread de l'interface utilisateur (requis par OpenGL) sans le rappel Java. Est-ce que c'est réalisable?


1 commentaires

Merci, bonne pourboire, je vais probablement finir par utiliser un mécanisme de rendu similaire (appelant Eglswapbuffer seul), mais utiliser de pure natifactivité est hors de question dans mon cas car j'ai besoin d'une interface utilisateur complexe.


4 Réponses :


0
votes

est-il possible de modifier le thread d'exécution de l'arrière-plan à l'utilisateur entièrement dans un code natif sans utiliser JNI?

Vous ne pouvez pas modifier les widgets du code natif.


2 commentaires

Merci pour votre contribution. Comment cette limitation s'applique-t-elle au rendu avec OpenGL?


@Youri: Vous pouvez certainement mettre à jour OpenGL directement à partir du code natif. Comment la threading joue dans cela, je ne peux pas dire.



1
votes

Grandes pensées, mais essayez de comprendre cette chose

  1. Vous avez du code en C ++ dans Native
  2. UI en Java court dans VM

    Maintenant, ce que vous demandez est C ++ Code d'interagir avec UI dans Java VM, qui est un autre programme de communication. La seule façon de le faire serait une communication interprocessée. Cela dit, maintenant, allez comprendre cela qui vous convient le mieux. JNI est rapide et fiable, car vous ne voulez pas y aller de cette façon, déterminez tout autre IPC qui vous convient.


4 commentaires

Merci pour votre commentaire. De mon expérience, le code NDK est en cours d'exécution dans le même processus que le code Java, donc je voudrais une gestion appropriée des threads plutôt que la communication interprocession (corrigez-moi si je me trompe). De plus, je ne veux pas me débarrasser complètement de la partie Java. Je souhaite l'utiliser pour un point d'entrée mais je ne veux pas passer par Java / JNI pour chaque cadre rendu en raison d'une surcharge supplémentaire. Désolé si je ne me suis pas rendu clair dans la question.


La communication inter-processus (IPC) est un ensemble de méthodes pour l'échange de données entre plusieurs threads dans un ou plusieurs processus. via en.wikipedia.org/wiki/inter-Process_communication


Bon, alors nous parlons de la même chose. Puisque votre réponse est un peu vague, avez-vous une idée de savoir comment résoudre ce problème particulier?


Eh bien, ma suggestion est de coller à JNI si possible. C'est le mécanisme le plus efficace disponible pour interagir entre le code natif et Android



2
votes

Je suggère de regarder la source de Fennec Mozilla. Il y a une bouteille Java / Jni minimale qui permet de rendu sur Android, mais tout le travail est effectué via un code natif (code habituel OL 'Mozilla)


1 commentaires

Merci, je vais regarder. BTW, les instructions Comment obtenir / construire la source sont décrites par exemple: wiki.mozilla .Org / Mobile / Fennec / Android # Construire .



0
votes

Je suis confronté au même problème en ce moment. Peut-être que cela pourrait aider:

Lorsque vous jetez un coup d'œil à l'Apis Stable.html dans le dernier NDK, il est indiqué: P>

> API native stables de Android-9: H2>

Toutes les API énumérées ci-dessous sont disponibles pour le développement de code natif qui fonctionne sur Android> 2.3 Images système et ci-dessus. P>

La bibliothèque graphique EGL: H2>

EGL fournit une interface de plate-forme natale pour allouer et gérer les opengles surfaces. Pour plus d'informations sur ses fonctionnalités, veuillez consulter: p>

- List supported EGL configurations
- Allocate and release OpenGLES surfaces
- Swap/Flip surfaces for display  (eglSwapBuffers)


6 commentaires

Eh bien, la bibliothèque EGL fonctionne bien, je suis capable d'initialiser le contexte EGL, la surface, etc. dans le code natif, puis dessiner à la surface à l'aide de EGLSWAPBuffer () . Cependant, le problème que je suis confronté est que, afin d'appeler ce EGLSwapbuffer () Je dois passer par Java / JNI car OpenGGL peut être touché uniquement sur le fil de l'interface utilisateur. Étant donné que mon traitement est exécuté dans un code natif dans le fil d'arrière-plan, je dois faire un commutateur. Mon objectif est de simplement éviter ces appels JNI pour que chaque cadre soit rendu en raison d'un surcharge supplémentaire. J'espère que c'est plus compréhensible maintenant? :)


Désolé, que je ne pouvais pas m'empêcher. Mais j'ai une courte question que vous pourriez être en mesure de répondre. Vous avez dit que OpenGL ne peut être touché que sur le fil de l'interface utilisateur. Pouvez-vous me dire quelles parties de OpenGL ne peuvent pas être utilisées en dehors de l'interface utilisateur? J'utilise OpenGL dans un autre fil et configurez des tampons / des textures de charge et des trucs. Jusqu'à présent, je ne découvrais que je ne pouvais pas dessiner ou utiliser GlreadPixel de l'extérieur du fil de l'UI. Mais je ressens parfois des accidents étranges tout en rendant. Peut-être que vous pouvez m'aider là-bas.


C'est une question difficile à répondre sans plus de détails. Je vous conseille vivement d'ouvrir une nouvelle question. Je vais enquêter si vous associez les questions.


ok je pense avoir la solution. Vous n'avez pas besoin de faire un GL dans l'interface utilisateur. Vous devez juste vous assurer que tout est fait dans un fil. Dans ce fil, vous devez configurer manuellement EGLSurface / EGLContext. Le constructeur de l'EGLSurface prend un titulaire de surface pour votre surface et cela informe le thread UI sur les changements automatiquement. Jetez un coup d'œil à ceci: e-university.wisdomjobs.com/net/chapter-924-288/... Cela a résolu mes problèmes, j'espère que cela aide;)


Wow, n'a pas compris ça. J'ai lu ailleurs que vous devez faire GL Rendu dans le fil de l'interface utilisateur. Merci de me le faire savoir. Je vais regarder mon code cette semaine et vous laisser savoir si cela fonctionne aussi pour moi.


Oui, j'ai déplacé GL rendu hors du fil de l'UI et tout a fonctionné. Merci! Ma question théorique reste encore, mais seulement à des fins strictement éducatives :)