Android NDK: 嵌套结构体编程

前言

Android开发中c语言的开发十分常见,原生的开发在App中有很多好处,譬如说运行速度更快,更安全,且可以更好的隐藏代码,不被别人反编译。简单的开发,只使用基本结构是不能满足我们的要求的,最好就是能够自定义结构,自定义结构才能更好的适应我们的需要。这里就实现一个例子,建立一个嵌套的结构体。

开始

如图所示:
勾选上红框就可以直接在代码中编写C/C++语言程序,而不必自己编译生成so
Android NDK: 嵌套结构体编程_第1张图片

java代码

等工程新建完毕后,就会有一些基本的代码了,那些我们忽略,先如下构建两个类:
MediaInfo类:

package cn.edu.scnu.hellojni;

/**
 * Created by zjt on 17-11-27.
 */

public class MediaInfo {
    public int nWidth;
    public int nHeight;
    public String str;
    public Detail detail;
}

Detail类:

package cn.edu.scnu.hellojni;

/**
 * Created by zjt on 17-11-27.
 */

public class Detail {
    public String detailStr;
}

上面这两个类就是我们嵌套的结构了。

然后看看我们的主类,MainActivity:

package cn.edu.scnu.hellojni;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // 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);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
        MediaInfo m = new MediaInfo();
        // 调用原生代码来为我们的类进行赋值
        GetMediaInfo(0,m);
        Log.d("tag","" + m.str+ " " + m.nHeight + " " + m.nWidth);
        Log.d("tag","" + m.detail.detailStr);
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
    public native static int GetMediaInfo(int handle,MediaInfo info);
}

原生代码

extern "C"
JNIEXPORT jint JNICALL
Java_cn_edu_scnu_hellojni_MainActivity_GetMediaInfo(JNIEnv *env, jclass type, jint handle,
                                                    jobject info) {
    // TODO 这里是基本的类型,两个int和一个String类型,是MediaInfo中的基本类型
    jclass objectClass = (env)->FindClass("cn/edu/scnu/hellojni/MediaInfo");
    jfieldID str = (env)->GetFieldID(objectClass,"str","java/lang/String");
    jfieldID nHeight = (env)->GetFieldID(objectClass,"nHeight","I");
    jfieldID nWidth = (env)->GetFieldID(objectClass,"nWidth","I");
    (env)->SetIntField(info,nHeight,10);
    (env)->SetIntField(info,nWidth,100);
    (env)->SetObjectField(info,str,(env)->NewStringUTF("mynjjj"));

    // 这里是为MediaInfo中的类Detail进行新建并赋值
    jclass oClass = (env)->FindClass("cn/edu/scnu/hellojni/Detail");
    // 调用构造函数并新建对象
    jmethodID method = (env)->GetMethodID(oClass,"","()V");
    jobject mObj = (env)->NewObject(oClass,method);
    // 为Detail成员变量赋值
    jfieldID inStr = (env)->GetFieldID(oClass,"detailStr","java/lang/String");
    (env)->SetObjectField(mObj,inStr,(env)->NewStringUTF("This is my string"));
    // 将Detail的对象赋给MediaInfo中的detail对象
    jfieldID inObj = (env)->GetFieldID(objectClass,"detail","cn/edu/scnu/hellojni/Detail");
    (env)->SetObjectField(info,inObj,mObj);

    return 0;
}

成功完成。

你可能感兴趣的:(android)