前言
Android开发中c语言的开发十分常见,原生的开发在App中有很多好处,譬如说运行速度更快,更安全,且可以更好的隐藏代码,不被别人反编译。简单的开发,只使用基本结构是不能满足我们的要求的,最好就是能够自定义结构,自定义结构才能更好的适应我们的需要。这里就实现一个例子,建立一个嵌套的结构体。
开始
如图所示:
勾选上红框就可以直接在代码中编写C/C++语言程序,而不必自己编译生成so
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,"<init>","()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;
}
成功完成。