title: Android Studio - Native method not found - Include .so file in build
body: <p>I'm starting with NDK, and want to compile my first hello-world app with it.</p>
  
  <p>My application is just a simple application with an Activity, and my MainActivity is in com.example.myapplication2.app</p>
  
  <p>I would like to use a native method in it, and here is what I did :</p>
  
  <p>MainActivity.java</p>
  
  <pre><code>    @Override
      protected void onCreate(Bundle savedInstanceState) {
          TextView  tv = new TextView(this);
          tv.setText(stringFromJNI());
          setContentView(tv);
      }
  
      public native String  stringFromJNI();
  
      static {
          System.loadLibrary("hello-jni");
      }
  </code></pre>
  
  <p>in my jni folder :</p>
  
  <p>Android.mk</p>
  
  <pre><code>LOCAL_PATH := $(call my-dir)
  
  include $(CLEAR_VARS)
  
  LOCAL_MODULE    := hello-jni
  LOCAL_SRC_FILES := hello-jni.c
  
  include $(BUILD_SHARED_LIBRARY)
  </code></pre>
  
  <p>Application.mk</p>
  
  <pre><code>APP_ABI := all
  </code></pre>
  
  <p>hello-jni.c</p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;jni.h&gt;
  
  JNIEXPORT jstring JNICALL   Java_com_example_myapplication2_app_MainActivity_stringFromJNI(JNIEnv* env, jobject  thiz)
  {
      return (*env)-&gt;NewStringUTF(env, "Hello from native code!");
  }
  </code></pre>
  
  <p>And here, my gradle :</p>
  
  <pre><code>apply plugin: 'android'
  
  android {
      compileSdkVersion 19
      buildToolsVersion "19.0.3"
  
      defaultConfig {
          minSdkVersion 8
          targetSdkVersion 19
          versionCode 1
          versionName "1.0"
      }
      buildTypes {
          release {
              runProguard false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
          }
      }
  
      sourceSets.main {
          jniLibs.srcDir 'src/main/libs'
          jni.srcDirs = [] //disable automatic ndk-build call
      }
  
      productFlavors {
          x86 {
              versionCode Integer.parseInt("6" + defaultConfig.versionCode)
              ndk {
                  abiFilter "x86"
              }
          }
          mips {
              versionCode Integer.parseInt("4" + defaultConfig.versionCode)
              ndk {
                  abiFilter "mips"
              }
          }
          armv7 {
              versionCode Integer.parseInt("2" + defaultConfig.versionCode)
              ndk {
                  abiFilter "armeabi-v7a"
              }
          }
          arm {
              versionCode Integer.parseInt("1" + defaultConfig.versionCode)
              ndk {
                  abiFilter "armeabi"
              }
          }
          fat
      }
  }
  
  def getVersionCodeFromManifest() {
      def manifestFile = file(android.sourceSets.main.manifest.srcFile)
      def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
      def matcher = pattern.matcher(manifestFile.getText())
      matcher.find()
      return Integer.parseInt(matcher.group(1))
  }
  
  task copyNativeLibs(type: Copy, dependsOn: 'buildNative') {
      // TODO fix deprecated
      dependsOn 'buildNative'
      from(new File('src/main/libs')) { include '**/*.so' }
      into new File(buildDir, 'native-libs')
  }
  
  tasks.withType(Compile) { compileTask -&gt; compileTask.dependsOn copyNativeLibs }
  
  clean.dependsOn 'cleanCopyNativeLibs'
  
  tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -&gt;
      pkgTask.jniFolders = new HashSet&lt;File&gt;();
      pkgTask.jniFolders.add(new File(projectDir, 'native-libs'))
  }
  
  task buildNative(type: Exec) {
      if (System.env.ANDROID_NDK != null) {
          def ndkBuild = new File(System.env.ANDROID_NDK, 'ndk-build')
          workingDir "src/main/jni"
          commandLine 'cmd', '/c', '%ANDROID_NDK%\\ndk-build'
          //executable ndkBuild
      } else {
          doLast {
              println '##################'
              println 'Skipping NDK build'
              println 'Reason: ANDROID_NDK not set.'
              println '##################'
          }
      }
  }
  
  task nativeLibsToJar(
          type: Zip,
          description: 'create a jar archive of the native libs') {
      destinationDir file("$buildDir/native-libs")
      baseName 'native-libs'
      extension 'jar'
      from fileTree(dir: 'libs', include: '**/*.so')
      into 'lib/'
  }
  
  dependencies {
      compile 'com.android.support:appcompat-v7:+'
      compile fileTree(dir: 'libs', include: ['*.jar'])
  }
  </code></pre>
  
  <p>When I want to run my project, I have no C error (I had before, that's why I'm sure compilation is done, and OK).</p>
  
  <p>But, when I want to run the application, I have the error :</p>
  
  <blockquote>
    <p>java.lang.UnsatisfiedLinkError: Native method not found: com.example.myapplication2.app.MainActivity.stringFromJNI:()Ljava/lang/String;</p>
  </blockquote>
  
  <p>What I've checked is (<a href="https://stackoverflow.com/questions/14444776/android-ndk-native-method-not-found-error">Android NDK Native method not found error</a>) :</p>
  
  <ul>
  <li>com.example.myapplication2.app.MainActivity.stringFromJNI and Java_com_example_myapplication2_app_MainActivity_stringFromJNI are matching</li>
  <li>extern "C" is not present, because when I used it, I encountered this error : <a href="https://stackoverflow.com/questions/10307762/error-expected-before-string-constant">Error: &quot;expected &#39;(&#39; before string constant&quot;</a></li>
  </ul>
  
  <p>May you know why I encounter this error ?</p>