Create .so file in android studio and used it in another application in Android

夙愿已清 提交于 2019-12-08 11:04:23

问题


I am started learning android ndk. I am new in it. I had created one project in Android studio 3.0.1 using adding c++ support. In this application user enter number in activity and using c++ code it tells whether its prime number or not. Here is my Activity code:

package com.app.androidkt.samplendk;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


EditText number_chk;
Button result_btn;


// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    result_btn = (Button)findViewById(R.id.result_btn);
    number_chk = (EditText) findViewById(R.id.number_chk);
    final TextView tv = (TextView) findViewById(R.id.sample_text);



    result_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int number;
            try{
                number = Integer.parseInt(number_chk.getText().toString());
                tv.setText(isPrimeNumber(number));
            }
            catch (Exception e)
            {
                tv.setText("Please enter valid number");
            }
        }
    });

    // Example of a call to a native method


}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
//public native String stringFromJNI();
private native String isPrimeNumber(int number);
}

my native-lib.cpp is like:

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring

JNICALL

Java_com_app_androidkt_samplendk_MainActivity_isPrimeNumber(
    JNIEnv *jenv,
    jobject self,
    jint number)
{
std::string result = "Prime Number";
int i;
for(i = 2; i <= number / 2; ++i)
{
    if(number % i == 0)
    {
        result = "Not a Prime Number";
        break;
    }
}
return jenv->NewStringUTF(result.c_str());
}

my app.gradle is like below, I had not changed anything in this:

apply plugin: 'com.android.application'

android {
compileSdkVersion 26
defaultConfig {
    applicationId "com.app.androidkt.samplendk"
    minSdkVersion 15
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags ""
        }
    }
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
   }
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

My application structure is like:

Upto this everything is perfect. Application runs and give me expected result. Now what i want is - Create new project and use above project .so file so in my new project I don't want to write c++ logic again. For this I am planning create a new Project in that add directory as jniLibs and copy .so file of above project. But I did not got .so file in above project. When I extract apk file of above project then I got only one so file.

  1. So How to create .so file for above project
  2. How to use this .so file in another project

Any suggestion and answer will be appreciated. Thanks in advance.


回答1:


The best practice is not to create native methods in the MainActivity class. If you create a separate small class for isPrimeNumber() and possibly other native methods, sharing your work will be easier.

In your case, the method can be declared static, because it does not depend on the Java object that invokes it. Native static methods have better performance, and – again – are easier to share.

Android Studio puts all built libnative-lib.so files in the app/build/intermediates directory. You will find fat libraries and also smaller, stripped, files in different subdirectories. You can copy the smaller ones to the jniLibs directory of the second project.

If your C++ uses a shared STL library, e.g. libgnustl_shared.so, you must also copy it the the jniLibs directory of the second project.

We often restrict the variants of native library we build, by defining abiFilters in the gradle script. The script you posted above does not feature any, and on the face of it, it does not create split APKs, so I cannot explain why you see only one libnative-lib.so in your APK.

Note that mips devices do not exist these days, and armeabi (old v6 variant) are also extremely rare. The latest NDK reminds that these ABIs will not be supported for long.

By the way, you don't need to rename it to ZIP: Android Studio has Analyze APK in its menus, and will show you reliably the contents of your file.



来源:https://stackoverflow.com/questions/49509856/create-so-file-in-android-studio-and-used-it-in-another-application-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!