Reputation: 13
I am trying to create my first Android app that uses the NDK. I am trying to use the live555.com sources to build an app that streams a MP4 file from the phone to somewhere else.
I am using Windows 7 32 bit with JDK 1.6.0_24, MOTODev 2.1 and latest Android SDK and NDK toolkits.
So far I have setup a new project and created the jni directory. Inside JNI I have placed the source files and Android.mk files. If I execute ndk-build I see:
$ $NDK/ndk-build
SharedLibrary : libtestProgs.so
Install : libtestProgs.so => libs/armeabi/libtestProgs.so
So it seems the native library is being built.
When I run my app it crashes with a lava.lang.UnsatisfiedLinkError: startStream.
startStream() is the method I am trying to call in the libtestProgs.so library.
Things I have checked: libtestProgs.so is built and in the proper place under libs/armeabi System.loadLibrary("testProgs"); is called before I attempt the native call Run javah -o jni.h com.streamtest.MainActivity and include this .h from the .cpp file.
Here is my MainActivity.java file:
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();
}
The native c++ file is simply the testOnDemandRTSPServer.cpp file from live555.com. I changed the main() method to be a Java native method. Here it is:
#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);
Here is the LogCat output:
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)
I am wondering about the FATAL EXCEPTION: main line. In the original .cpp file their was a main() method. In my new file there is no main(). Is this the cause of the problem? If it is, how do I use a .cpp file as a library? Does it need a main() method?
Any help appreciated as I try to get my first NDK app running.
Thanks, James
Upvotes: 1
Views: 7946
Reputation: 1
have you tried the steps mentioned in this discussion?
http://forum.videolan.org/viewtopic.php?f=13&t=89166
Upvotes: 0
Reputation: 991
Did you include testOnDemandRTSPServer.cpp in your LOCAL_SRC_FILES variable in your Android.mk file?
When you executed ndk-build, you should have seen each of the c/c++ files you included in LOCAL_SRC_FILES being compiled. You should have seen a line like (among several others if there are multiple c/c++ files):
Compile arm : libtestProgs <= testOnDemandRTSPServer.cpp
In fact, Based on the output you included from your execution of ndk-build, it looks like you didn't included anything in LOCAL_SRC_FILES, and you're just creating a libtestProgs.so file with nothing compiled into it.
From the docs:
"The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source files that will be built and assembled into a module. Note that you should not list header and included files here, because the build system will compute dependencies automatically for you; just list the source files that will be passed directly to a compiler, and you should be good."
See ANDROID-MK.html in the docs folder of the Android JNI you downloaded for details.
Upvotes: 1
Reputation: 991
After you edited testOnDemandRTSPServer.cpp, did you:
Re-execute ndk-build?
Make sure the Android project got rebuilt with the updated libtestProgs.so? If you're using Eclipse, you can right-click on the libs folder and hit Refresh.
You can also have these steps be automated: http://mobilepearls.com/labs/ndk-builder-in-eclipse/ (not my site)
When I run into this, it's usually because I forgot to do one of those 2.
Upvotes: 0