1、新建Android Studio工程,取名JNITest;
2、新建java类HelloJNI,并声明native方法,取名为getHelloWorld,取名为如下图;
4、执行脚本文件,生成.h文件,如下图,在编写com_terrence_jni_HelloJNI.cpp文件;
5、下载live555源码,全部复制到src/main/jni/目录下面;
6、编写Android.mk文件,详细见下面;
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ BasicUsageEnvironment/BasicHashTable.cpp \ BasicUsageEnvironment/BasicTaskScheduler.cpp \ BasicUsageEnvironment/BasicTaskScheduler0.cpp \ BasicUsageEnvironment/BasicUsageEnvironment.cpp \ BasicUsageEnvironment/BasicUsageEnvironment0.cpp \ BasicUsageEnvironment/DelayQueue.cpp \ UsageEnvironment/HashTable.cpp \ UsageEnvironment/UsageEnvironment.cpp \ UsageEnvironment/strDup.cpp \ groupsock/GroupsockHelper.cpp \ groupsock/GroupEId.cpp \ groupsock/inet.c \ groupsock/Groupsock.cpp \ groupsock/NetInterface.cpp \ groupsock/NetAddress.cpp \ groupsock/IOHandlers.cpp \ liveMedia/AC3AudioFileServerMediaSubsession.cpp \ liveMedia/AC3AudioRTPSink.cpp \ liveMedia/AC3AudioRTPSource.cpp \ liveMedia/AC3AudioStreamFramer.cpp \ liveMedia/ADTSAudioFileServerMediaSubsession.cpp \ liveMedia/ADTSAudioFileSource.cpp \ liveMedia/AMRAudioFileServerMediaSubsession.cpp \ liveMedia/AMRAudioFileSink.cpp \ liveMedia/AMRAudioFileSource.cpp \ liveMedia/AMRAudioRTPSink.cpp \ liveMedia/AMRAudioRTPSource.cpp \ liveMedia/AMRAudioSource.cpp \ liveMedia/AudioInputDevice.cpp \ liveMedia/AudioRTPSink.cpp \ liveMedia/Base64.cpp \ liveMedia/BasicUDPSink.cpp \ liveMedia/BasicUDPSource.cpp \ liveMedia/BitVector.cpp \ liveMedia/ByteStreamFileSource.cpp \ liveMedia/ByteStreamMemoryBufferSource.cpp \ liveMedia/ByteStreamMultiFileSource.cpp \ liveMedia/DeviceSource.cpp \ liveMedia/DigestAuthentication.cpp \ liveMedia/DVVideoFileServerMediaSubsession.cpp \ liveMedia/DVVideoRTPSink.cpp \ liveMedia/DVVideoRTPSource.cpp \ liveMedia/DVVideoStreamFramer.cpp \ liveMedia/EBMLNumber.cpp \ liveMedia/EBMLNumber.hh \ liveMedia/FileServerMediaSubsession.cpp \ liveMedia/FileSink.cpp \ liveMedia/FramedFileSource.cpp \ liveMedia/FramedFilter.cpp \ liveMedia/FramedSource.cpp \ liveMedia/GenericMediaServer.cpp \ liveMedia/GSMAudioRTPSink.cpp \ liveMedia/H261VideoRTPSource.cpp \ liveMedia/H263plusVideoFileServerMediaSubsession.cpp \ liveMedia/H263plusVideoRTPSink.cpp \ liveMedia/H263plusVideoRTPSource.cpp \ liveMedia/H263plusVideoStreamFramer.cpp \ liveMedia/H263plusVideoStreamParser.cpp \ liveMedia/H263plusVideoStreamParser.hh \ liveMedia/H264or5VideoFileSink.cpp \ liveMedia/H264or5VideoRTPSink.cpp \ liveMedia/H264or5VideoStreamDiscreteFramer.cpp \ liveMedia/H264or5VideoStreamFramer.cpp \ liveMedia/H264VideoFileServerMediaSubsession.cpp \ liveMedia/H264VideoFileSink.cpp \ liveMedia/H264VideoRTPSink.cpp \ liveMedia/H264VideoRTPSource.cpp \ liveMedia/H264VideoStreamDiscreteFramer.cpp \ liveMedia/H264VideoStreamFramer.cpp \ liveMedia/H265VideoFileServerMediaSubsession.cpp \ liveMedia/H265VideoFileSink.cpp \ liveMedia/H265VideoRTPSink.cpp \ liveMedia/H265VideoRTPSource.cpp \ liveMedia/H265VideoStreamDiscreteFramer.cpp \ liveMedia/H265VideoStreamFramer.cpp \ liveMedia/InputFile.cpp \ liveMedia/JPEGVideoRTPSink.cpp \ liveMedia/JPEGVideoRTPSource.cpp \ liveMedia/Locale.cpp \ liveMedia/MatroskaDemuxedTrack.cpp \ liveMedia/MatroskaDemuxedTrack.hh \ liveMedia/MatroskaFile.cpp \ liveMedia/MatroskaFileParser.cpp \ liveMedia/MatroskaFileParser.hh \ liveMedia/MatroskaFileServerDemux.cpp \ liveMedia/MatroskaFileServerMediaSubsession.cpp \ liveMedia/MatroskaFileServerMediaSubsession.hh \ liveMedia/Media.cpp \ liveMedia/MediaSession.cpp \ liveMedia/MediaSink.cpp \ liveMedia/MediaSource.cpp \ liveMedia/MP3ADU.cpp \ liveMedia/MP3ADUdescriptor.cpp \ liveMedia/MP3ADUdescriptor.hh \ liveMedia/MP3ADUinterleaving.cpp \ liveMedia/MP3ADURTPSink.cpp \ liveMedia/MP3ADURTPSource.cpp \ liveMedia/MP3ADUTranscoder.cpp \ liveMedia/MP3AudioFileServerMediaSubsession.cpp \ liveMedia/MP3AudioMatroskaFileServerMediaSubsession.cpp \ liveMedia/MP3AudioMatroskaFileServerMediaSubsession.hh \ liveMedia/MP3FileSource.cpp \ liveMedia/MP3Internals.cpp \ liveMedia/MP3Internals.hh \ liveMedia/MP3InternalsHuffman.cpp \ liveMedia/MP3InternalsHuffman.hh \ liveMedia/MP3InternalsHuffmanTable.cpp \ liveMedia/MP3StreamState.cpp \ liveMedia/MP3StreamState.hh \ liveMedia/MP3Transcoder.cpp \ liveMedia/MPEG1or2AudioRTPSink.cpp \ liveMedia/MPEG1or2AudioRTPSource.cpp \ liveMedia/MPEG1or2AudioStreamFramer.cpp \ liveMedia/MPEG1or2Demux.cpp \ liveMedia/MPEG1or2DemuxedElementaryStream.cpp \ liveMedia/MPEG1or2DemuxedServerMediaSubsession.cpp \ liveMedia/MPEG1or2FileServerDemux.cpp \ liveMedia/MPEG1or2VideoFileServerMediaSubsession.cpp \ liveMedia/MPEG1or2VideoRTPSink.cpp \ liveMedia/MPEG1or2VideoRTPSource.cpp \ liveMedia/MPEG1or2VideoStreamDiscreteFramer.cpp \ liveMedia/MPEG1or2VideoStreamFramer.cpp \ liveMedia/MPEG2IndexFromTransportStream.cpp \ liveMedia/MPEG2TransportFileServerMediaSubsession.cpp \ liveMedia/MPEG2TransportStreamFramer.cpp \ liveMedia/MPEG2TransportStreamFromESSource.cpp \ liveMedia/MPEG2TransportStreamFromPESSource.cpp \ liveMedia/MPEG2TransportStreamIndexFile.cpp \ liveMedia/MPEG2TransportStreamMultiplexor.cpp \ liveMedia/MPEG2TransportStreamTrickModeFilter.cpp \ liveMedia/MPEG2TransportUDPServerMediaSubsession.cpp \ liveMedia/MPEG4ESVideoRTPSink.cpp \ liveMedia/MPEG4ESVideoRTPSource.cpp \ liveMedia/MPEG4GenericRTPSink.cpp \ liveMedia/MPEG4GenericRTPSource.cpp \ liveMedia/MPEG4LATMAudioRTPSink.cpp \ liveMedia/MPEG4LATMAudioRTPSource.cpp \ liveMedia/MPEG4VideoFileServerMediaSubsession.cpp \ liveMedia/MPEG4VideoStreamDiscreteFramer.cpp \ liveMedia/MPEG4VideoStreamFramer.cpp \ liveMedia/MPEGVideoStreamFramer.cpp \ liveMedia/MPEGVideoStreamParser.cpp \ liveMedia/MPEGVideoStreamParser.hh \ liveMedia/MultiFramedRTPSink.cpp \ liveMedia/MultiFramedRTPSource.cpp \ liveMedia/OggDemuxedTrack.cpp \ liveMedia/OggDemuxedTrack.hh \ liveMedia/OggFile.cpp \ liveMedia/OggFileParser.cpp \ liveMedia/OggFileParser.hh \ liveMedia/OggFileServerDemux.cpp \ liveMedia/OggFileServerMediaSubsession.cpp \ liveMedia/OggFileServerMediaSubsession.hh \ liveMedia/OggFileSink.cpp \ liveMedia/OnDemandServerMediaSubsession.cpp \ liveMedia/ourMD5.cpp \ liveMedia/OutputFile.cpp \ liveMedia/PassiveServerMediaSubsession.cpp \ liveMedia/ProxyServerMediaSession.cpp \ liveMedia/QCELPAudioRTPSource.cpp \ liveMedia/QuickTimeFileSink.cpp \ liveMedia/QuickTimeGenericRTPSource.cpp \ liveMedia/rtcp_from_spec.c \ liveMedia/rtcp_from_spec.h \ liveMedia/RTCP.cpp \ liveMedia/RTPInterface.cpp \ liveMedia/RTPSink.cpp \ liveMedia/RTPSource.cpp \ liveMedia/RTSPClient.cpp \ liveMedia/RTSPCommon.cpp \ liveMedia/RTSPRegisterSender.cpp \ liveMedia/RTSPServer.cpp \ liveMedia/RTSPServerSupportingHTTPStreaming.cpp \ liveMedia/ServerMediaSession.cpp \ liveMedia/SimpleRTPSink.cpp \ liveMedia/SimpleRTPSource.cpp \ liveMedia/SIPClient.cpp \ liveMedia/StreamParser.cpp \ liveMedia/StreamParser.hh \ liveMedia/StreamReplicator.cpp \ liveMedia/T140TextRTPSink.cpp \ liveMedia/TCPStreamSink.cpp \ liveMedia/TextRTPSink.cpp \ liveMedia/TheoraVideoRTPSink.cpp \ liveMedia/TheoraVideoRTPSource.cpp \ liveMedia/uLawAudioFilter.cpp \ liveMedia/VideoRTPSink.cpp \ liveMedia/VorbisAudioRTPSink.cpp \ liveMedia/VorbisAudioRTPSource.cpp \ liveMedia/VP8VideoRTPSink.cpp \ liveMedia/VP8VideoRTPSource.cpp \ liveMedia/VP9VideoRTPSink.cpp \ liveMedia/VP9VideoRTPSource.cpp \ liveMedia/WAVAudioFileServerMediaSubsession.cpp \ liveMedia/WAVAudioFileSource.cpp \ LOCAL_SRC_FILES += com_terrence_jni_HelloJNI.h LOCAL_SRC_FILES += com_terrence_jni_HelloJNI.cpp LOCAL_SHARED_LIBRARIES := libutils LOCAL_LDLIBS := -llog LOCAL_MODULE := liblive555 LOCAL_ARM_MODE := arm LOCAL_PRELINK_MODULE := false #fatal error: xlocale.h: No such file or directory LOCAL_CFLAGS := -DXLOCALE_NOT_USED LOCAL_CPPFLAGS := \ -DNULL=0 -DSOCKLEN_T=socklen_t -DNO_SSTREAM -DBSD=1 -DNO_SSTREAM -fexceptions -DANDROID LOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/BasicUsageEnvironment/include \ $(LOCAL_PATH)/UsageEnvironment/include \ $(LOCAL_PATH)/groupsock/include \ $(LOCAL_PATH)/liveMedia/include \ LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) #include $(BUILD_STATIC_LIBRARY)7、编写Application.mk文件,如下;
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_OPTIM := release #APP_OPTIM := debug APP_ABI := armeabi-v7a APP_PLATFORM := android-19 NDK_TOOLCHAIN_VERSION := 4.98、编写app/build.gradle,大家可以自行修改;
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.terrence.jni" minSdkVersion 19 targetSdkVersion 23 versionCode 1 versionName "1.0" sourceSets.main.jni.srcDirs = [] sourceSets.main.jniLibs.srcDirs = ['src/main/libs'] } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } task buildNative(type: Exec, description: 'Compile JNI source via NDK') { def ndkDir = android.ndkDirectory commandLine "$ndkDir/ndk-build.cmd", '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source '-j', Runtime.runtime.availableProcessors(), 'all', 'NDK_DEBUG=1', 'V=1' } task cleanNative(type: Exec, description: 'Clean JNI object files') { def ndkDir = android.ndkDirectory // if (Os.isFamily(Os.FAMILY_WINDOWS)) { commandLine "$ndkDir/ndk-build.cmd", '-C', file('src/main/jni').absolutePath, 'clean' } clean.dependsOn 'cleanNative' task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') { destinationDir file("$projectDir/src/main/java/libs") // baseName 'native-libs' extension 'jar' from fileTree(dir: "$projectDir/src/main/java/libs", include: '**/*.so') into 'lib/' } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn(buildNative) } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn buildNative } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.3.0' }
9、CTRL + F9,编译成功。
10、另附下载地址