2011-04-11 3 views
1

Je suis en train de créer ma première application Android qui utilise le NDK. J'essaie d'utiliser les sources live555.com pour construire une application qui diffuse un fichier MP4 du téléphone à un autre endroit. J'utilise Windows 7 32 bits avec JDK 1.6.0_24, MOTODev 2.1 et les derniers kits d'outils Android SDK et NDK.Débutant aide avec NDK, java.lang.UnsatisfiedLinkError

Jusqu'ici, j'ai configuré un nouveau projet et créé le répertoire jni. A l'intérieur de JNI j'ai placé les fichiers source et les fichiers Android.mk. Si j'exécute ndk-build, je vois:

$ $NDK/ndk-build 
SharedLibrary : libtestProgs.so 
Install  : libtestProgs.so => libs/armeabi/libtestProgs.so 

Il semble donc que la bibliothèque native est en cours de construction. Lorsque j'exécute mon application, elle se bloque avec un lava.lang.UnsatisfiedLinkError: startStream.

StartStream() est la méthode que j'essaie d'appeler dans la bibliothèque libtestProgs.so. Ce que j'ai vérifié: libtestProgs.so est construit et à l'endroit approprié sous libs/armeabi System.loadLibrary ("testProgs"); est appelé avant que j'essaie l'appel natif Exécutez javah -o jni.h com.streamtest.MainActivity et incluez ce fichier .h à partir du fichier .cpp.

Voici mon fichier MainActivity.java:


package com.streamtest; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 

public class MainActivity extends Activity { 
    public static final String LOG_TAG = "StreamTest"; 
    static 
    { 
     try 
     { 
      //System.loadLibrary("jnix"); 
      System.loadLibrary("testProgs"); 
     } 
     catch(Throwable e) 
     { 
      Log.e(LOG_TAG, e.toString()); 
      throw new RuntimeException(e); 
     } 
    } 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     // call our native code 
     Log.e(LOG_TAG, "About to call native code!"); 
     startStream(); 

    } 

    private native void startStream(); 
} 
 

Le fichier C++ natif est tout simplement le fichier testOnDemandRTSPServer.cpp de live555.com. J'ai changé la méthode main() pour qu'elle soit une méthode native Java. Ici, il est:



#include "com_streamtest_MainActivity.h" 
#include "liveMedia.hh" 
#include "BasicUsageEnvironment.hh" 


void Java_com_streamtest_MainActivity_startStream(JNIEnv *env) 
{ 
    // Begin by setting up our usage environment: 
    TaskScheduler* scheduler = BasicTaskScheduler::createNew(); 
    uenv = BasicUsageEnvironment::createNew(*scheduler); 

est ici la sortie LogCat:

 

04-12 08:40:27.934: ERROR/StreamTest(17130): About to call native code! 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130): FATAL EXCEPTION: main 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130): java.lang.UnsatisfiedLinkError: startStream 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at com.streamtest.MainActivity.startStream(Native Method) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at com.streamtest.MainActivity.onCreate(MainActivity.java:31) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.os.Looper.loop(Looper.java:123) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at java.lang.reflect.Method.invoke(Method.java:521) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
04-12 08:40:27.965: ERROR/AndroidRuntime(17130):  at dalvik.system.NativeStart.main(Native Method) 
 

Je me demande au sujet de la FATAL EXCEPTION: ligne principale. Dans le fichier .cpp d'origine, il s'agissait d'une méthode main(). Dans mon nouveau fichier, il n'y a pas de main(). Est-ce la cause du problème? Si c'est le cas, comment puis-je utiliser un fichier .cpp en tant que bibliothèque? A-t-il besoin d'une méthode main()?

Toute aide appréciée pendant que j'essaie de lancer ma première application NDK.

Merci, James

Répondre

1

Avez-vous incluez testOnDemandRTSPServer.cpp dans votre variable LOCAL_SRC_FILES dans votre fichier Android.mk?Lorsque vous avez exécuté ndk-build, vous devriez avoir vu chacun des fichiers c/C++ que vous avez inclus dans LOCAL_SRC_FILES en cours de compilation. Vous auriez dû voir une ligne comme celle (parmi plusieurs autres s'il y a plusieurs fichiers c/C++):

Compile bras: libtestProgs < = testOnDemandRTSPServer.cpp

En fait, la base de la sortie que vous avez inclus à partir de votre exécution de ndk-build, il semble que vous n'ayez rien inclus dans LOCAL_SRC_FILES, et vous créez juste un fichier libtestProgs.so sans rien compilé dedans.

De la documentation:

« Les variables LOCAL_SRC_FILES doit contenir une liste de C et/ou fichiers C++ source qui sera construit et assemblé en un module Notez que vous devez liste non-tête et fichiers inclus. ici, parce que le système de construction va automatiquement calculer les dépendances pour vous, il suffit de lister les fichiers source qui seront transmis directement à un compilateur, et vous devriez être bon. "

Voir ANDROID-MK.html dans le dossier docs du JNI Android que vous avez téléchargé pour plus de détails.

+1

C'était tout. J'ai parcouru chaque fichier Android.mk pour m'assurer que chaque variable s'étendait à la bonne chose. L'un d'eux contenait une erreur. Merci! – James

0

Après avoir édité testOnDemandRTSPServer.cpp, avez-vous:

  1. réexécuter NDK-construire?

  2. Assurez-vous que le projet Android a été reconstruit avec le fichier libtestProgs.so mis à jour? Si vous utilisez Eclipse, vous pouvez cliquer avec le bouton droit sur le dossier libs et cliquer sur Actualiser.

Vous pouvez également avoir ces étapes être automatisées: http://mobilepearls.com/labs/ndk-builder-in-eclipse/ (pas mon site)

Quand je lance dans cela, il est généralement parce que j'ai oublié de faire un de ces 2.

+0

les deux et encore Essayé même erreur. J'étais sûr que j'avais déjà fait l'étape ndk-build, mais je ne suis pas sûr de la façon de forcer l'actualisation dans Eclipse. De toute façon ne fonctionne toujours pas. – James