移植ffmpeg到android(转)

移植ffmpegandroid()

作者:ycq

搞这东西集合了好多人的东西,单照一个人的做老出错,弄了几天终于出来了,把遇到的问题都写了下来

讲讲编译的步骤:
1. 安装cygwin
  
必须是1.7或者更新的版本
  
安装cygwin的时候,选择安装gccmake,目的是为了提供编译环境,
   make
的版本至少是3.81
2.安装ndk

·      2.1 下载ndk-r4b-windows,并将其放到cygwin/home/Administator目录

·     设置环境变量

  /etc/skel/目录的 .bash_profile  .bashrc .inputrc拷贝到/home/administrator目录,
 
编辑/home/administrator目录的 .bashrc文件,在后面增加两行:
     NDK_ROOT=~/android-ndk-r4b/
     export NDK_ROOT
  ~
的实际目录是cygwin/home/

Administrator目录

3.下载ffmpeg
 
版本是0.6.1
  android-ndk-r4b/samples目录,创建文件夹FFMPEG,在ffmpeg目录创建jni目录,
 
ffmpeg解压并将全部源码拷贝到jni目录
  ffmpeg
源码的路径变成:
  ~ /android-ndk-r4b/samples/FFMPEG/jni/ffmpeg
4.编译准备

·     cdffmpeg目录,执行dos2unix configure,转换文件格式

·    ffmpeg源码目录新建config.sh,并转换成 unix格式,

          内容如下:
               
#!/bin/bash

export TMPDIR="c:/temp/android"

export NDKROOT="C:/cygwin/home/Administrator/android-ndk-r4b"

PREBUILT=$NDKROOT/build/prebuilt/windows/arm-eabi-4.4.0

PLATFORM=$NDKROOT/build/platforms/android-8/arch-arm

./configure --target-os=linux \

--arch=arm \

--enable-version3 \

--enable-gpl \

--enable-nonfree \

--disable-stripping \

--disable-ffmpeg \

--disable-ffplay \

--disable-ffserver \

--disable-ffprobe \

--disable-encoders \

--disable-muxers \

--disable-devices \

--disable-protocols \

--enable-protocol=file \

--enable-avfilter \

--disable-network \

--disable-mpegaudio-hp \

--disable-avdevice \

--enable-cross-compile \

--cc=$PREBUILT/bin/arm-eabi-gcc \

--cross-prefix=$PREBUILT/bin/arm-eabi- \

--nm=$PREBUILT/bin/arm-eabi-nm \

--extra-cflags="-fPIC -DANDROID" \

--disable-asm \

--enable-neon \

--enable-armv5te \

--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"

 

 

执行: chmod +x config.sh && ./config.sh

      输出creating config.mak and config.h...
     
执行成功

·      修改生成的config.h,将其中的

             #define restrict restrict改成 #define restrict
            
转换文件格式

·      编辑libavutil/libm.h,将其中的所有static方法删除

            转换文件格式

·      修改libavcodec,libavfilter,libavformat,libavutil,libpostproclibswscale目录的MakeFile文件,

      将以下内容删除:
        include $( SUBDIR ) ../config.mak
        include $ (SUBDIR) .. / subdir.mak
     
修改之后转换文件格式

·      ffmpeg源码目录新建av.mk文件

           内容如下:

         # LOCAL_PATH is one of libavutil, libavcodec, libavformat, or libswscale

 

#include $(LOCAL_PATH)/../config-$(TARGET_ARCH).mak

include $(LOCAL_PATH)/../config.mak

 

OBJS :=

OBJS-yes :=

MMX-OBJS-yes :=

include $(LOCAL_PATH)/Makefile

 

# collect objects

OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)

OBJS += $(OBJS-yes)

 

FFNAME := lib$(NAME)

FFLIBS := $(foreach,NAME,$(FFLIBS),lib$(NAME))

FFCFLAGS  = -DHAVE_AV_CONFIG_H -Wno-sign-compare -Wno-switch -Wno-pointer-sign

FFCFLAGS += -DTARGET_CONFIG=\"config-$(TARGET_ARCH).h\"

 

ALL_S_FILES := $(wildcard $(LOCAL_PATH)/$(TARGET_ARCH)/*.S)

ALL_S_FILES := $(addprefix $(TARGET_ARCH)/, $(notdir $(ALL_S_FILES)))

 

ifneq ($(ALL_S_FILES),)

ALL_S_OBJS := $(patsubst %.S,%.o,$(ALL_S_FILES))

C_OBJS := $(filter-out $(ALL_S_OBJS),$(OBJS))

S_OBJS := $(filter $(ALL_S_OBJS),$(OBJS))

else

C_OBJS := $(OBJS)

S_OBJS :=

endif

 

C_FILES := $(patsubst %.o,%.c,$(C_OBJS))

S_FILES := $(patsubst %.o,%.S,$(S_OBJS))

 

FFFILES := $(sort $(S_FILES)) $(sort $(C_FILES))

 

 创建一系列Android.mk文件

         jni目录,创建Android.mk,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_WHOLE_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale

LOCAL_MODULE := ffmpeg

include $(BUILD_SHARED_LIBRARY)

include $(call all-makefiles-under,$(LOCAL_PATH))

libavformat/目录,创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_CFLAGS += -include "string.h" -Dipv6mr_interface=ipv6mr_ifindex

LOCAL_LDLIBS := -lz

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

libavcodec/目录,创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_LDLIBS := -lz

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

libavfilter创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

 

libavutil创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

 

libpostproc创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

 

libswscale目录,创建Android.mk,文件如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include $(LOCAL_PATH)/../av.mk

LOCAL_SRC_FILES := $(FFFILES)

LOCAL_C_INCLUDES :=        \

    $(LOCAL_PATH)        \

    $(LOCAL_PATH)/..

LOCAL_CFLAGS += $(FFCFLAGS)

LOCAL_STATIC_LIBRARIES := $(FFLIBS)

LOCAL_MODULE := $(FFNAME)

include $(BUILD_STATIC_LIBRARY)

 

5.进行编译
 
执行: $NDK_ROOT/ndk-build         NDK_PROJECT_PATH=$NDK_ROOT/samples/FFMPEG
 
编译成功,在生成的libs目录看到.a.so文件
 
 
6.可能出现的错误
  6.1
执行config.sh时,出现错误:
      Unknown option "--target-os=linux".
      See ./configure --help for available options.
     
解决办法:ffmpeg的版本不支持,换成0.6.1即可
  6.2
执行config.sh是,出现错误:
      ./config.sh: line 8: --enable-nonfree: command not found
      ./config.sh: line 9: --disable-ffprobe: command not found
      .........
     
解决办法:config.sh中的configure命令,后面跟的参数有换行符,导致系统认为
               
参数是新的命令行。将换行符删除即可


7.其他问题
  
编辑的文件,都要转换成unix文件格式。
  
unix文件格式中, '\'可以代表空格。

8.libffmpeg文件很小是空文件问题解决

很多人在用 havlenapetr的方法编译 FFmpeg时只得到一个 1599字节 1.6KB 大小的 libffmpeg.so 文件,无论是用 Android NDK r4b编译还是用 Android NDK r5编译结果都是如此,很让人抓狂。我也很郁闷,最后花时间研究了一下 NDK,终于发现了解决方法,而且 Android NDK r4b Android NDK r5 的情况还是完全不同的,请继续往下读。

1        使用 Android NDK r4b编译

打开 android-ndk-r4b/build/toolchains/arm-eabi-4.4.0目录中的 setup.mk文件,你会发现 Google在里面定义了一个用于编译动态库的 cmd-build-shared-library函数。在cmd-build-shared-library函数中 Google 使用了 PRIVATE_WHOLE_STATIC_LIBRARIES函数。但是你在 android-ndk-r4b/build/core目录中的 build-binary.mk文件里却找不到 PRIVATE_WHOLE_STATIC_LIBRARIES函数……外?WHY?终于搞清楚了,原来得不到正确的 libffmpeg.so 文件不是我的错,而是 Android NDK r4b BUG!你妹啊!你大爷啊!坑爹呢这是!发布前不做测试吗!居然漏掉一个函数!!!(我敢说这是个 BUG是因为 Google Android NDK r5 中修复了这个 BUG

木办法,只好手动替 Google修补这个 BUG。好在修改方法很简单,只需要照 build-binary.mk文件里的 PRIVATE_STATIC_LIBRARIES增加一个 PRIVATE_WHOLE_STATIC_LIBRARIES就行了。具体方法见下图

修改前的 build-binary.mk文件

 

修改后的 build-binary.mk文件

 

 

1          使用 Android NDK r5编译

打开 android-ndk-r5/build/core目录中的 build-binary.mk文件,发现 Google这次没有忘记 PRIVATE_WHOLE_STATIC_LIBRARIES,但还最后编译得到的 libffmpeg.so文件大小还是不正确。这次的问题是,android-ndk-r5默认是使用 arm-linux-androideabi-4.4.3编译,而不是 arm-eabi-4.4.0。但 android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3目录中的 setup.mk文件里定义的  cmd-build-shared-library 函数并没有将静态库文件链接在一起生成动态库文件。所以解决的办法就是在执行 ndk-build时加上 NDK_TOOLCHAIN参数,指定使用 arm-eabi-4.4.0来编译。完整命令如下

/root/android-ndk-r5/ndk-build NDK_PROJECT_PATH=/root/ffmpeg NDK_TOOLCHAIN=arm-eabi-4.4.0 NDK_PLATFORM=android-8

9.编译好libffmpeg.so后,我们要怎么应用呢,如下

折腾了几天,成功的用jni调用了libffmpeg中的一个方法-----avcodec_version(),

还得编译一个so文件,这个so里的是jni方法,可以由java层调用的,而这些jni方法里用到的函数则就是来至libffmpeg.so了。思路是有了,但是具体怎么做呢?又经过一顿摸索,n次的编译,终于编译成功了。我是拿一个标准的ndk例子来做的测试就是ndk samples文件夹里的hello-jni工程。进入该工程的jni目录,将ffmpeg的源代码(就是你用来编译libffmpeg的那个增加了Android.mk的那个源码)拷到该目录下,做这部的原因是你要编译的so文件里需要调用ffmpeg的方法,自然要引用ffmpeg里的h文件,然后将libffmpeg.so文件拷到ndk目录下的platforms/android-5/arch-arm/usr/lib目录下(你会发现platfroms里有好几个android文件夹如 -3 -4 -5分别代表不同的版本,本以为只要拷其中一个就可以,可编译的时候老出错,什么找不到-lffmpeg什么错,还是要全部都拷),因为等等系统编译的时候要用。接下来就编辑android.mk和hello-jni.c文件了 代码如下

android.mk

C代码 

  1. # Copyright (C) 2009 The Android Open Source Project   
  2. #   
  3. # Licensed under the Apache License, Version 2.0 (the "License");   
  4. # you may not use this file except in compliance with the License.   
  5. # You may obtain a copy of the License at   
  6. #   
  7. #      http://www.apache.org/licenses/LICENSE-2.0   
  8. #   
  9. # Unless required by applicable law or agreed to in writing, software   
  10. # distributed under the License is distributed on an "AS IS" BASIS,   
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   
  12. # See the License for the specific language governing permissions and   
  13. # limitations under the License.   
  14. #   
  15. LOCAL_PATH := $(call my-dir)   
  16.   
  17. include $(CLEAR_VARS)   
  18. PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg   
  19. LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)   
  20. LOCAL_LDLIBS := -lffmpeg   
  21. LOCAL_MODULE    := hello-jni   
  22. LOCAL_SRC_FILES := hello-jni.c   
  23.   
  24. include $(BUILD_SHARED_LIBRARY)  
# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg
LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
LOCAL_LDLIBS := -lffmpeg
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
 
include $(BUILD_SHARED_LIBRARY)

 

PATH_TO_FFMPEG_SOURCE:=$(LOCAL_PATH)/ffmpeg

这行是定义一个变量,也就是ffmpeg源码的路径

LOCAL_C_INCLUDES += $(PATH_TO_FFMPEG_SOURCE)
这行是指定源代码的路径,也就是刚才拷过去的ffmpeg源码,$(LOCAL_PATH)是根目录,如果没有加这行那么引入ffmpeg库中的h文件编译就会出错说找不到该h文件。

LOCAL_LDLIBS := -lffmpeg
这行很重要,这是表示你这个so运行的时候依赖于libffmpeg.so这个库,再举个例子:如果你要编译的so不仅要用到libffmpeg.so这个库还要用的libopencv.so这个库的话,你这个参数就应该写成

LOCAL_LDLIBS := -lffmpeg -lopencv

其他的参数都是正常的ndk编译用的了,不明白的话google一下。

 

hello-jni.c

C代码 

  1. /*  
  2.  * Copyright (C) 2009 The Android Open Source Project  
  3.  *  
  4.  * Licensed under the Apache License, Version 2.0 (the "License");  
  5.  * you may not use this file except in compliance with the License.  
  6.  * You may obtain a copy of the License at  
  7.  *  
  8.  *      http://www.apache.org/licenses/LICENSE-2.0  
  9.  *  
  10.  * Unless required by applicable law or agreed to in writing, software  
  11.  * distributed under the License is distributed on an "AS IS" BASIS,  
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.  * See the License for the specific language governing permissions and  
  14.  * limitations under the License.  
  15.  *  
  16.  */  
  17. #include <string.h>   
  18. #include <stdio.h>   
  19. #include <android/log.h>   
  20. #include <stdlib.h>    
  21. #include <jni.h>   
  22. #include <ffmpeg/libavcodec/avcodec.h>   
  23. /* This is a trivial JNI example where we use a native method  
  24.  * to return a new VM String. See the corresponding Java source  
  25.  * file located at:  
  26.  *  
  27.  *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java  
  28.  */  
  29. jstring   
  30. Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,   
  31.                                                   jobject thiz )   
  32. {   
  33.     char str[25];   
  34.     sprintf(str, "%d", avcodec_version());    
  35.   
  36.   
  37.     return (*env)->NewStringUTF(env, str);   
  38. }  
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include <stdlib.h> 
#include <jni.h>
#include <ffmpeg/libavcodec/avcodec.h>
/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
 char str[25];
 sprintf(str, "%d", avcodec_version()); 
 
 
    return (*env)->NewStringUTF(env, str);
}

 #include <ffmpeg/libavcodec/avcodec.h>
这行是因为下面要用到avcodec_version()这个函数。

 

    改完这两个文件以后就可以编译了~~用ndk-build命令编译完后在工程的libs/armeabi目录底下就会有一个libhello-jni.so文件了!(两行眼泪啊~终于编译成功了)

    编译完成后就可以进行测试了,记得将libffmpeg.so也拷到armeabi目录底下,并在java代码中写上

Java代码 

  1. static {   
  2.        System.loadLibrary("ffmpeg");   
  3.         System.loadLibrary("hello-jni");   
  4.     }  
static {
       System.loadLibrary("ffmpeg");
        System.loadLibrary("hello-jni");
    }

     HelloJni.java

 

 

Java代码 

  1. /*  
  2.  * Copyright (C) 2009 The Android Open Source Project  
  3.  *  
  4.  * Licensed under the Apache License, Version 2.0 (the "License");  
  5.  * you may not use this file except in compliance with the License.  
  6.  * You may obtain a copy of the License at  
  7.  *  
  8.  *      http://www.apache.org/licenses/LICENSE-2.0  
  9.  *  
  10.  * Unless required by applicable law or agreed to in writing, software  
  11.  * distributed under the License is distributed on an "AS IS" BASIS,  
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13.  * See the License for the specific language governing permissions and  
  14.  * limitations under the License.  
  15.  */  
  16. package com.example.hellojni;   
  17.   
  18. import android.app.Activity;   
  19. import android.widget.TextView;   
  20. import android.os.Bundle;   
  21.   
  22.   
  23. public class HelloJni extends Activity   
  24. {   
  25.     /** Called when the activity is first created. */  
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState)   
  28.     {   
  29.         super.onCreate(savedInstanceState);   
  30.   
  31.         /* Create a TextView and set its content.  
  32.          * the text is retrieved by calling a native  
  33.          * function.  
  34.          */  
  35.         TextView  tv = new TextView(this);   
  36.         tv.setText( "1111" );   
  37.         //System.out.println();   
  38.         setContentView(tv);   
  39.         tv.setText(String.valueOf(stringFromJNI()));   
  40.     }   
  41.   
  42.     /* A native method that is implemented by the  
  43.      * 'hello-jni' native library, which is packaged  
  44.      * with this application.  
  45.      */  
  46.     public native String  stringFromJNI();   
  47.   
  48.     /* This is another native method declaration that is *not*  
  49.      * implemented by 'hello-jni'. This is simply to show that  
  50.      * you can declare as many native methods in your Java code  
  51.      * as you want, their implementation is searched in the  
  52.      * currently loaded native libraries only the first time  
  53.      * you call them.  
  54.      *  
  55.      * Trying to call this function will result in a  
  56.      * java.lang.UnsatisfiedLinkError exception !  
  57.      */  
  58.     public native String  unimplementedStringFromJNI();   
  59.   
  60.     /* this is used to load the 'hello-jni' library on application  
  61.      * startup. The library has already been unpacked into  
  62.      * /data/data/com.example.HelloJni/lib/libhello-jni.so at  
  63.      * installation time by the package manager.  
  64.      */  
  65.     static {   
  66.           System.loadLibrary("ffmpeg");   
  67.         System.loadLibrary("hello-jni");   
  68.     }   
  69. }  
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.example.hellojni;
 
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
 
 
public class HelloJni extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
 
        /* Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( "1111" );
        //System.out.println();
        setContentView(tv);
        tv.setText(String.valueOf(stringFromJNI()));
    }
 
    /* A native method that is implemented by the
     * 'hello-jni' native library, which is packaged
     * with this application.
     */
    public native String  stringFromJNI();
 
    /* This is another native method declaration that is *not*
     * implemented by 'hello-jni'. This is simply to show that
     * you can declare as many native methods in your Java code
     * as you want, their implementation is searched in the
     * currently loaded native libraries only the first time
     * you call them.
     *
     * Trying to call this function will result in a
     * java.lang.UnsatisfiedLinkError exception !
     */
    public native String  unimplementedStringFromJNI();
 
    /* this is used to load the 'hello-jni' library on application
     * startup. The library has already been unpacked into
     * /data/data/com.example.HelloJni/lib/libhello-jni.so at
     * installation time by the package manager.
     */
    static {
       System.loadLibrary("ffmpeg");
        System.loadLibrary("hello-jni");
    }
}

   到此就完成了,将程序装到手机可看到打印出3426306 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页