在Android NDK系列(一)手动搭建Native Project 已经介绍了如何手动搭建一个基于NativeActivity的工程,本文主要介绍NativeActivity的工作流程,通过本文的学习,可以了解到NativeActivity是如何与Native层交互的,Native的NativeWindow是从哪里来的。下面从NativeActivity的源码开始了解它的工作流程。
1、NativeActivity概览
NativeActivity是Framework中的一个类,路径为frameworks\base\core\java\android\appNativeActivity.java,类的继承关系如下。
public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
InputQueue.Callback, OnGlobalLayoutListener {
static class NativeContentView extends View {
NativeActivity mActivity;
public NativeContentView(Context context) {
super(context);
}
public NativeContentView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
mNativeContentView = new NativeContentView(this);
setContentView(mNativeContentView);
}
}
从NativeActivity类的定义可以看出,它也继承于Activity,在onCreate回调中将NativeContentView作为内容视图。
JNI层有一个android_app_NativeActivity.cpp与NativeActivity.对应,路径为
frameworks\base\core\jni\android_app_NativeActivity.cpp。
在NativeActivity类中定义了一些native方法,调用这些方法可以与android_app_NativeActivity交互,比如调用NativeActivity的loadNativeCode,相应地android_app_NativeActivity.cpp的loadNativeCode_native会被调用。
2、加载本地代码
在onCreate回调中开始加载本地代码,如下所示。
public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
InputQueue.Callback, OnGlobalLayoutListener {
protected void onCreate(Bundle savedInstanceState) {
String libname = "main";
String funcname = "ANativeActivity_onCreate";
ai = getPackageManager().getActivityInfo(
getIntent().getComponent(), PackageManager.GET_META_DATA);
if (ai.metaData != null) {
String ln = ai.metaData.getString(META_DATA_LIB_NAME);
if (ln != null) libname = ln;
ln = ai.metaData.getString(META_DATA_FUNC_NAME);
if (ln != null) funcname = ln;
}
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
getAbsolutePath(getExternalFilesDir(null)),
Build.VERSION.SDK_INT, getAssets(), nativeSavedState,
classLoader, classLoader.getLdLibraryPath());
}
}
在onCreate中,主要解析Activity配置的libname,比如下面的示例配置的libname为native。
<activity
android:name