虽然在ndk文档中,google不推荐使用native C/C++来开发应用程序。但在实际开发中,可能不得不使用native C/C++的情况,比如跨平台软件开发。为手机开发软件,为了能够面向更广泛的用户群,免不了要同时开发symbian、windows mobile、android等主流手机平台版本。出于效率的考虑,一般手机软件采用C/C++开发,所以为了避免重起炉灶,在android下一般选择使用native C/C++开发核心组件,再加上一个Java语言编写的外壳。笔者最近移植一款应用到android,该应用采用了skia图形库,因此对android下的skia稍微进行了研究。在此系列文章中,我将分析一下android下的Skia编程。 还是以大名鼎鼎的hello world作为本文章的起点吧。我们知道,android采用skia作为其核心图形引擎,因此android天然支持skia绘图,问题在于Java层如何和jni层的代码相互访问。其实android中有很多绘图类(android.graphics包下的类)都是对skia c++类的一个封装。比如Canvas <-> SkCanvas, Paint <-> SkPaint,关键是如何在它们之间架起一座桥梁。 首先看看java侧的类定义: - public class SkiaView extends View
- {
- private static final String TAG = "skiademo";
- static
- {
- System.loadLibrary("SkiaDemo");
- }
-
- public native void renderHello(Canvas canvas);
-
- public SkiaView(Context context)
- {
- super(context);
- }
-
- @Override
- public void onDraw(Canvas canvas)
- {
- super.onDraw(canvas);
-
- Log.d(TAG, "onDraw");
- renderHello(canvas);
- }
- }
SkiaView类继承自View类,定义了一个native方法renderHello,注意其参数是Canvas。JNI侧的代码如下: - void Java_com_whtr_example_skiademo_SkiaView_renderHello(JNIEnv *env, jobject thizz, jobject canvas)
- {
- SkCanvas* canv = GraphicsJNI::getNativeCanvas(env, canvas);
- if (!canv)
- {
- return;
- }
- SkPaint paint;
- paint.setColor(SK_ColorRED);
- canv->drawText("hello skia", 10, 20, 20, paint);
- }
在函数的开始,调用GraphicsJNI::getNativeCanvas方法处理java侧传递过来的Canvas对象,获取SkCanvas对象指针,有了SkCanvas,我们就可以在上面进行绘制了。 需要注意的是,ndk中并没有包含skia相关头文件和库函数,因此要编译此程序,还需要下载android源代码并进行编译。不过android系统中已经有这些库文件,所以部署到手机上运行是没有问题的。Android.mk文件如下: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) MY_ANDROID_SOURCE=$(HOME)/android/source/cupcake LOCAL_MODULE := libSkiaDemo LOCAL_CPP_EXTENSION := .cpp LOCAL_CXXFLAGS := LOCAL_C_INCLUDES := $(MY_ANDROID_SOURCE)/frameworks/base/core/jni/android/graphics \ $(MY_ANDROID_SOURCE)/external/skia/include/core \ $(MY_ANDROID_SOURCE)/external/skia/include/images \ $(MY_ANDROID_SOURCE)/frameworks/base/include \ $(MY_ANDROID_SOURCE)/system/core/include LOCAL_SRC_FILES := SkiaDemoJni.cpp LOCAL_LDLIBS := -llog -lsgl -landroid_runtime \ -L$(MY_ANDROID_SOURCE)/out/target/product/generic/system/lib/ include $(BUILD_SHARED_LIBRARY)
完整的代码和Android.mk文件可以使用如下命令获取: svn checkout http://androidcodes.googlecode.com/svn/trunk/ androidcodes
最终的运行结果如下图所示: 注:android版本不同,skia版本也不太相同,接口有些细微的差别。
|