Bonjour,
Je suis à la recherche d'exemple, de lien, de tutoriel, voir livre, sur le traitement réseau *sur *des callback java via jni c++
un lien sur un projet git exemple illustrant mon cas serait parfait.
je fais appel aux pro du jni, callback et reseau
Je dois écrire une application C++ avec un *java call back *sur une api java*qui traite un appel réseau, *mais je tourne en rond sur les diverse solution, elle marchent
presque, j'ai besoin d'avis différent sur la meilleure solution à appliquer dans mon approche.
-Activité
* * ->appel jni *méthode requete*
* * * * * * *c++ prépare message
* * * * * * *c++*appel java*callback via interface*pour le traitement réseau* byte[] reponse=requete(byte[] question)
* * * * * * * * * * *java call serveur http *en envoi requete et recupère la*réponse et retour au jni appelant
* * * * * * *c++ traiter réponse (save data)
* * * * *retour Activité menu ok
j'utilise une interface java avec une implémentation *okhttp/volley/httpclient selon choix, * pour une question de liberté d'implémentation du client, je ne peux pas utiliser directement du c++ (dommage)
une méthode très simple*disponible de l'interface
le JNI est appelé par mon activité et fait il fait un callback sur ma requête via mon interface java, et execute l'impemlentation qui traite la parite réseau.
Code : Sélectionner tout - Visualiser dans une fenêtre à part *byet[] reponse=*request( byte[] question )*
je suis en mode bloquant, côté jni, je pose ma question et j'attends ma réponse pour continuer
Jje me heurte à divers problème, *
d'abord le premier cas, *simple au premier abord, **
la *requête http part vers mon serveur http qui reçu et traité,*mais je me heurte à une exeption* NetworkOnMainThreadException
en clair je ne peux pas bloquer mon activité *en exécution sur le thread principal vis à vis de 'utilisateur,*
bizarre, bizarre, je peux avoir avec des timer qui' arrête l'échange au bout de 10s.
y'a t'il une solution pour contourner cette exception sur un appel synchrone ? un exemple ?
Côté appel JNI en gros, je pensais pouvoir éviter l'exception en ouvrant une une nouvelle instance jvm/java env, mais ca ne passe pas, j'ai la même erreur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 jvm->AttachCurrentThread(&myNewEnv, &args); jbyteArray masterResponseMessageBuf = (jbyteArray) myNewEnv->CallObjectMethod( httpTaskMgr, httpMethodId, bufArray); jvm->DetachCurrentThread();Deuxième cas je me tourne vers un appel aync ca marche presque aussi, la requête part et traiter par le serveur http, je n'ai pas d'exception,*
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 public byte[] request( byte[]request ) { .. ... snip .. Response response= client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code server :" + response); ResponseBody body = response.body(); int len = (int) body.contentLength(); if (len > 0) { byteObject = new byte[len]; InputStream source = body.byteStream(); source.read(byteObject); }
mais ma response reste vide, je ne suis pas en mode bloquant*pour récupérer ma réponse et mettre à disposition de l'appel de mon appelant*jni,
y a t'il un moyen d'attendre la réponse du serveur avant de sortir de méthode java*pour revenir à l'appelant avec bien sur*un timeout si délai dépassé.
J'ai egalement *utiliser un *async task*
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public byte[] request( byte[]request ) { ... ... snip ... client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, final Response response) throws IOException { if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } ResponseBody body = response.body(); int len = (int) body.contentLength(); if (len > 0) { byteObject = new byte[len]; * InputStream source = body.byteStream(); * source.read(byteObject); } } return byteObject; // n'attend pas le callback via onResponse methode ? comment? }
mais je bloque à l'appel du jni, sur l'appel de la signature*methode
Code : Sélectionner tout - Visualiser dans une fenêtre à part extends AsyncTask<byte[], Void, byte[]>
a cause de ca, il faut faire un get pour récupèrer la reponse de l'Async
response=obj.execute(question).get(), il n'encaisse pas ce genre de signature de methode au niveau de l'appel jni., j'ai mis de côté cette solution
Pour résumer, *
je suis à 99% en native c++, mon activité(java) appelle mon*jni et qui*fais un callback java d'une requete http vers mon serveur et je récupère la réponse pour être traiter au niveau c++
en mode synchrone*j'envoi ma requête en callback jni*au serveur et je tombe en*NetworkOnMainThreadException
en mode asynchrone j'envoi*ma requête,mais ma requête sort avant de récupérer la réponse de mon call back.
Merci pour vos avis, je continu à chercher la meilleure solution, je ne sais pas pour l'instant quel est la meilleure approche, un mode async reseau, ou un appel bloquant avec timeout dans un thread séparé
je posterai la réponse si je trouve une solutoin acceptable
Cordialement
JP
Partager