1. makefile ifeq可以有多个参数
多于两种情况的使用很简单,害我尝试很多种方法,如ifeq elifeq等等这些。其实就如同c中的if [else if] [else if]...else的使用一样,举个我使用的例子,Android中的NDK程序android.mk判断当前是哪种CPU架构:
ifeq ($(TARGET_ARCH), arm)
LOCAL_SRC_FILES := ...
else ifeq ($(TARGET_ARCH), x86)
LOCAL_SRC_FILES := ...
else ifeq ($(TARGET_ARCH), mips)
LOCAL_SRC_FILES := ...
else
LOCAL_SRC_FILES := ...
endif123456789123456789
很简单有木有,但网上的资料都没有去涉及,可能大多数来源都一样,呵呵,这是我看Makefile标准文档中得到了。希望给同样困惑的人一点帮助。
2. Android.mk 的一个问题
如果common.mk在之前有被调用到的话,直接把MY_DEBUG_OPEN抛出来。或者你为什么不定义在这个makefile里面。
include $(LOCAL_PATH)/../common.mk
makefile文件里面应该不支持这种写法。
3. android 怎么编译so文件
android NDK编译多个so文件
android编译系统的makefile文件Android.mk写法如下
(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。由于一般情况下
Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:
LOCAL_PATH:=$(call my-dir)
上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。
(2)Android.mk中可以定义多个编译模块,每个编译模块都是以include $(CLEAR_VARS)开始
以include $(BUILD_XXX)结束。
include $(CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除除LOCAL_PATH以外的所有LOCAL_XXX变量,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示编译成静态库
include $(BUILD_SHARED_LIBRARY)表示编译成动态库。
include $(BUILD_EXECUTABLE)表示编译成可执行程序
(3)举例如下(frameworks/base/libs/audioflinger/Android.mk):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) 模块一
ifeq ($(AUDIO_POLICY_TEST),true)
ENABLE_AUDIO_DUMP := true
endif
LOCAL_SRC_FILES:= \
AudioHardwareGeneric.cpp \
AudioHardwareStub.cpp \
AudioHardwareInterface.cpp
ifeq ($(ENABLE_AUDIO_DUMP),true)
LOCAL_SRC_FILES += AudioDumpInterface.cpp
LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
endif
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_CFLAGS += -DGENERIC_AUDIO
endif
LOCAL_MODULE:= libaudiointerface
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_SRC_FILES += A2dpAudioInterface.cpp
LOCAL_SHARED_LIBRARIES += liba2dp
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_C_INCLUDES += $(call include-path-for, bluez)
endif
include $(BUILD_STATIC_LIBRARY) 模块一编译成静态库
include $(CLEAR_VARS) 模块二
LOCAL_SRC_FILES:= \
AudioPolicyManagerBase.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libmedia
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudiopolicybase
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_A2DP
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
include $(BUILD_STATIC_LIBRARY) 模块二编译成静态库
include $(CLEAR_VARS) 模块三
LOCAL_SRC_FILES:= \
AudioFlinger.cpp \
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioResamplerSinc.cpp.arm \
AudioResamplerCubic.cpp.arm \
AudioPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
LOCAL_CFLAGS += -DGENERIC_AUDIO
else
LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
endif
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudioflinger
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_SHARED_LIBRARIES += liba2dp
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(HOST_OS),linux)
LOCAL_LDLIBS += -lrt -lpthread
endif
endif
ifeq ($(BOARD_USE_LVMX),true)
LOCAL_CFLAGS += -DLVMX
LOCAL_C_INCLUDES += vendor/nxp
LOCAL_STATIC_LIBRARIES += liblifevibes
LOCAL_SHARED_LIBRARIES += liblvmxservice
# LOCAL_SHARED_LIBRARIES += liblvmxipc
endif
include $(BUILD_SHARED_LIBRARY) 模块三编译成动态库
(4)编译一个应用程序(APK)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory-->直译(建立在java子目录中的所有Java文件)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build-->直译(创建APK的名称)
LOCAL_PACKAGE_NAME := LocalPackage
# Tell it to build an APK-->直译(告诉它来建立一个APK)
include $(BUILD_PACKAGE)
(5)编译一个依赖于静态Java库(static.jar)的应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# List of static libraries to include in the package
LOCAL_STATIC_JAVA_LIBRARIES := static-library
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
# Tell it to build an APK
include $(BUILD_PACKAGE)
(6)编译一个需要用平台的key签名的应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
LOCAL_CERTIFICATE := platform
# Tell it to build an APK
include $(BUILD_PACKAGE)
(7)编译一个需要用特定key前面的应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
LOCAL_CERTIFICATE := vendor/example/certs/app
# Tell it to build an APK
include $(BUILD_PACKAGE)
(8)添加一个预编译应用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Mole name should match apk name to be installed.
LOCAL_MODULE := LocalMoleName
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)
(9)添加一个静态JAVA库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Any libraries that this library depends on
LOCAL_JAVA_LIBRARIES := android.test.runner
# The name of the jar file to create
LOCAL_MODULE := sample
# Build a static jar file.
include $(BUILD_STATIC_JAVA_LIBRARY)
(10)Android.mk的编译模块中间可以定义相关的编译内容,也就是指定相关的变量如下:
LOCAL_AAPT_FLAGS
LOCAL_ACP_UNAVAILABLE
LOCAL_ADDITIONAL_JAVA_DIR
LOCAL_AIDL_INCLUDES
LOCAL_ALLOW_UNDEFINED_SYMBOLS
LOCAL_ARM_MODE
LOCAL_ASFLAGS
LOCAL_ASSET_DIR
LOCAL_ASSET_FILES 在Android.mk文件中编译应用程序(BUILD_PACKAGE)时设置此变量,表示资源文件,
通常会定义成LOCAL_ASSET_FILES += $(call find-subdir-assets)
LOCAL_BUILT_MODULE_STEM
LOCAL_C_INCLUDES 额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录
举例如下:
LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_CC 指定C编译器
LOCAL_CERTIFICATE 签名认证
LOCAL_CFLAGS 为C/C++编译器定义额外的标志(如宏定义),举例:LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1
LOCAL_CLASSPATH
LOCAL_COMPRESS_MODULE_SYMBOLS
LOCAL_COPY_HEADERS install应用程序时需要复制的头文件,必须同时定义LOCAL_COPY_HEADERS_TO
LOCAL_COPY_HEADERS_TO install应用程序时复制头文件的目的路径
LOCAL_CPP_EXTENSION 如果你的C++文件不是以cpp为文件后缀,你可以通过LOCAL_CPP_EXTENSION指定C++文件后缀名
如:LOCAL_CPP_EXTENSION := .cc
注意统一模块中C++文件后缀必须保持一致。
LOCAL_CPPFLAGS 传递额外的标志给C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection
LOCAL_CXX 指定C++编译器
LOCAL_DX_FLAGS
LOCAL_EXPORT_PACKAGE_RESOURCES
LOCAL_FORCE_STATIC_EXECUTABLE 如果编译的可执行程序要进行静态链接(执行时不依赖于任何动态库),则设置LOCAL_FORCE_STATIC_EXECUTABLE:=true
目前只有libc有静态库形式,这个只有文件系统中/sbin目录下的应用程序会用到,这个目录下的应用程序在运行时通常
文件系统的其它部分还没有加载,所以必须进行静态链接。
LOCAL_GENERATED_SOURCES
LOCAL_INSTRUMENTATION_FOR
LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME
LOCAL_INTERMEDIATE_SOURCES
LOCAL_INTERMEDIATE_TARGETS
LOCAL_IS_HOST_MODULE
LOCAL_JAR_MANIFEST
LOCAL_JARJAR_RULES
LOCAL_JAVA_LIBRARIES 编译java应用程序和库的时候指定包含的java类库,目前有core和framework两种
多数情况下定义成:LOCAL_JAVA_LIBRARIES := core framework
注意LOCAL_JAVA_LIBRARIES不是必须的,而且编译APK时不允许定义(系统会自动添加)
LOCAL_JAVA_RESOURCE_DIRS
LOCAL_JAVA_RESOURCE_FILES
LOCAL_JNI_SHARED_LIBRARIES
LOCAL_LDFLAGS 传递额外的参数给连接器(务必注意参数的顺序)
LOCAL_LDLIBS 为可执行程序或者库的编译指定额外的库,指定库以"-lxxx"格式,举例:
LOCAL_LDLIBS += -lcurses -lpthread
LOCAL_LDLIBS += -Wl,-z,origin
LOCAL_MODULE 生成的模块的名称(注意应用程序名称用LOCAL_PACKAGE_NAME而不是LOCAL_MODULE)
LOCAL_MODULE_PATH 生成模块的路径
LOCAL_MODULE_STEM
LOCAL_MODULE_TAGS 生成模块的标记
LOCAL_NO_DEFAULT_COMPILER_FLAGS
LOCAL_NO_EMMA_COMPILE
LOCAL_NO_EMMA_INSTRUMENT
LOCAL_NO_STANDARD_LIBRARIES
LOCAL_OVERRIDES_PACKAGES
LOCAL_PACKAGE_NAME APK应用程序的名称
LOCAL_POST_PROCESS_COMMAND
LOCAL_PREBUILT_EXECUTABLES 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用,指定需要复制的可执行文件
LOCAL_PREBUILT_JAVA_LIBRARIES
LOCAL_PREBUILT_LIBS 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用, 指定需要复制的库.
LOCAL_PREBUILT_OBJ_FILES
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
LOCAL_PRELINK_MODULE 是否需要预连接处理(默认需要,用来做动态库优化)
LOCAL_REQUIRED_MODULES 指定模块运行所依赖的模块(模块安装时将会同步安装它所依赖的模块)
LOCAL_RESOURCE_DIR
LOCAL_SDK_VERSION
LOCAL_SHARED_LIBRARIES 可链接动态库
LOCAL_SRC_FILES 编译源文件
LOCAL_STATIC_JAVA_LIBRARIES
LOCAL_STATIC_LIBRARIES 可链接静态库
LOCAL_UNINSTALLABLE_MODULE
LOCAL_UNSTRIPPED_PATH
LOCAL_WHOLE_STATIC_LIBRARIES 指定模块所需要载入的完整静态库(这些精通库在链接是不允许链接器删除其中无用的代码)
LOCAL_YACCFLAGS
OVERRIDE_BUILT_MODULE_PATH
4. 如何在Android中使用OpenCV
如何在Android程序中使用OpenCV
有两种方式(重点讲后面一种):
1.使用OpenCV Java API。
OpenCV安装路径“F:\OpenCV-2.3.1-android-bin”下有两个文件夹,
将文件夹“OpenCV-2.3.1”拷贝到你的Eclipse工作空间所在的目录,也就是在你的项目的上一级目录中,然后导入到工作空间中,在Package Explorer中选择你的项目,单机右键在弹出菜单中选择Properties,然后在弹出的Properties窗口中左侧选择Android,然后点击右下方的Add按钮,选择OpenCV-2.3.1并点击OK,
此时,展开你的项目树,你可以看到新加了一个OpenCV-2.3.1_src目录,如下图,那么就是正确添加了OpenCV Java API,否则就是你放置OpenCV-2.3.1的目录路径不正确。
然后就可以在你的Java源文件中导入OpenCV的API包,并且使用OpenCV API了,OpenCV API的包的形式如下:
Org.opencv.(OpenCV模块名)。(OpenCV类名)
例如:
Org.opencv.core.Mat
2.利用JNI编写C++ OpenCV代码,通过Android NDK创建动态库(。so)
新建一个工作空间,例如“TestOpenCV”,在Window->Preferences中设置好Android SDK的路径。
然后新建一个Android项目,Build Target选择Android2.2,命名为“HaveImgFun”,活动名改为HaveImgFun,Package name中填写com.testopencv.haveimgfun,最后点击finish。
如同使用OpenCV Java API那样,将OpenCV-2.3.1文件夹拷贝到与工作空间同一级目录中;另外,将“F:\OpenCV-2.3.1-android-bin\samples”下的includeOpenCV.mk文件拷贝到和项目HaveImgFun同一级目录中:
(上面这个各个文件夹和文件的放置很重要,因为OpenCV-2.3.1下的OpenCV.mk中有很多相对路径的指定,如果不是这样放置,在NDK生成动态库时可能会报文件或文件夹无法找到的错误)
选择Package Explorer中你的项目,右键选择new->folder,新建一个名为jni的文件夹,用来存放你的c/c++代码。
然后把res->layout下的main.xml的内容改为下面所示:
1 <?xml version=“1.0” encoding=“utf-8”?> 2 <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android” 3 android:orientation=“vertical” 4 android:layout_width=“fill_parent” 5 android:layout_height=“fill_parent” 6 > 7 <Button android:layout_height=“wrap_content” 8 android:layout_width=“fill_parent” 9 android:id=“@+id/btnNDK” 10 android:text=“使用C++ OpenCV进行处理” /> 11 <Button android:layout_height=“wrap_content” 12 android:layout_width=“fill_parent” 13 android:id=“@+id/btnRestore” 14 android:text=“还原” /> 15 <ImageView android:id=“@+id/ImageView01” 16 android:layout_width=“fill_parent” 17 android:layout_height=“fill_parent” /> 18 </LinearLayout>
上面的代码就是一个线性布局里面包含2个按钮加上一个显示图像的ImageView
在文件夹src下的com.testopencv.haveimgfun包中新建一个类用于包装使用了opencv c++代码的动态库的导出函数,类名为LibImgFun。
Eclipse会为你创建一个新的文件LibImgFun.java,将里面的内容改为:
1 package com.testopencv.haveimgfun; 2 public class LibImgFun { 3 static { 4 System.loadLibrary(“ImgFun”); 5 } 6 /** 7 * @param width the current view width 8 * @param height the current view height 9 */ 10 public static native int[] ImgFun(int[] buf, int w, int h); 11 }
从上面的代码可以得知,我们的动态库名字应该为“libImgFun.so”,注意“public static native int[] ImgFun(int[] buf, int w, int h)”中的native关键字,表明这个函数来自native code。static表示这是一个静态函数,这样就可以直接用类名去调用。
在jni文件夹下建立一个“ImgFun.cpp”的文件,内容改为下面所示:
1 #include <jni.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <opencv2/opencv.hpp> 5 using namespace cv;6 7 extern “C”8 { 9 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h); 10 JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h){ 11 12 jint *cbuf; 13 cbuf = env->GetIntArrayElements(buf, false); 14 if(cbuf == NULL) 15 { 16 return 0; 17 } 18 19 Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf); 20 for(int j=0;j<myimg.rows/2;j++) 21 { 22 myimg.row(j)。setTo(Scalar(0,0,0,0)); 23 } 24 25 int size=w * h; 26 jintArray result = env->NewIntArray(size); 27 env->SetIntArrayRegion(result, 0, size, cbuf); 28 env->ReleaseIntArrayElements(buf, cbuf, 0); 29 return result; 30 } 31 }
上面的代码中#include <jni.h>是必须要包含的头文件,#include <opencv2/opencv.hpp>是opencv要包含的头文件。
动态库要导出的函数如下声明:
JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT 和JNICALL是必须要加的关键字
jintArray就是int[],这里返回类型要么为空,要么为jni中定义的类型,事实上就是C\C++类型前面加上j,如果是数组,则在后面加上Array。
函数名的命名规则如下:
Java_(包路径)_(类名)_(函数名) (JNIEnv *env, jobject obj, 自己定义的参数…)
包路径中的“.”用“_”(下划线)代替,类名就是上面包装该动态库函数的类的名字,最后一个才是真正的函数名;JNIEnv *env和jobject obj这两个参数时必须的,用来调用JNI环境下的一些函数;后面就是你自己定义的参数。在这里,jintArray buf代表了传进来的图像的数据,int w是图像的宽,int h是图像的高。
这个函数的功能是将传进来的图像的上半部分涂成黑色。
然后再在jni下新建两个文件“Android.mk”文件和“Application.mk”文件,这两个文件事实上就是简单的Makefile文件。
其中将Android.mk的内容改为如下所示:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include /includeOpenCV.mk
ifeq (“$(wildcard $(OPENCV_MK_PATH))”,“”)
#try to load OpenCV.mk from default install location
include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := ImgFun
LOCAL_SRC_FILES := ImgFun.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk的内容改为如下所示:
APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI:=armeabi armeabi-v7a
其中APP_ABI指定的是目标平台的CPU架构。(经过很多测试,android2.2必须指定为armeabi,android2.2以上的使用armeabi-v7a,如果没有设置对,很有可能安装到android虚拟机失败,当然你同时如上面写上也是可以的)
上面的步骤完成后,就可以使用NDK生成动态库了,打开cygwin,cd到项目目录下:
输入$NDK/ndk-build命令,开始创建动态库。
这时候刷新Eclipse的Package Explorer会出现两个新的文件夹obj和libs。
现在,只剩最后一步完成这个测试程序。
将一张图片,例如“lena.jpg”放到项目res->drawable-hdpi目录中并刷新该目录。
然后将HaveImgFun.java的内容改为下面所示:
1 package com.testopencv.haveimgfun; 2 3 import android.app.Activity; 4 import android.graphics.Bitmap; 5 import android.graphics.Bitmap.Config; 6 import android.graphics.drawable.BitmapDrawable; 7 import android.os.Bundle; 8 import android.widget.Button; 9 import android.view.View; 10 import android.widget.ImageView; 11 12 public class HaveImgFun extends Activity{ 13 /** Called when the activity is first created. */ 14 ImageView imgView; 15 Button btnNDK, btnRestore; 16 17 @Override 18 public void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.main); 21 22 this.setTitle(“使用NDK转换灰度图”); 23 btnRestore=(Button)this.findViewById(R.id.btnRestore); 24 btnRestore.setOnClickListener(new ClickEvent()); 25 btnNDK=(Button)this.findViewById(R.id.btnNDK); 26 btnNDK.setOnClickListener(new ClickEvent()); 27 imgView=(ImageView)this.findViewById(R.id.ImageView01); 28 Bitmap img=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 29 imgView.setImageBitmap(img); 30 } 31 32 class ClickEvent implements View.OnClickListener{ 33 public void onClick(View v){ 34 if(v == btnNDK){35 long current=System.currentTimeMillis(); 36 Bitmap img1=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 37 int w=img1.getWidth(),h=img1.getHeight(); 38 int[] pix = new int[w * h]; 39 img1.getPixels(pix, 0, w, 0, 0, w, h); 40 int[] resultInt=LibImgFun.ImgFun(pix, w, h); 41 Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565); 42 resultImg.setPixels(resultInt, 0, w, 0, 0,w, h); 43 long performance=System.currentTimeMillis()-current; 44 imgView.setImageBitmap(resultImg); 45 HaveImgFun.this.setTitle(“w:”+String.valueOf(img1.getWidth())+“,h:”+String.valueOf(img1.getHeight())+“NDK耗时”+String.valueOf(performance)+“ 毫秒”); 46 } else if(v == btnRestore){ 47 Bitmap img2=((BitmapDrawable) getResources()。getDrawable(R.drawable.lena))。getBitmap(); 48 imgView.setImageBitmap(img2); 49 HaveImgFun.this.setTitle(“使用OpenCV进行图像处理”);50 } 51 }52 } 53 }
点击全部保存,OK,现在可以选择一个Android虚拟机运行看一下效果,配置好Run Configuration然后点击Run,得到下面的结果:
点击使用C++ OpenCV进行处理,得到下面的结果:
5. 怎么在Android.mk里拷贝文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# files that live under /system/etc/...
_from := \
etc/dbus.conf \
etc/hosts
ifeq ($(TARGET_PRODUCT),generic)
_from += etc/vold.conf
endif
# the /system/etc/init.goldfish.sh is needed to enable emulator support
# in the system image. In theory, we don't need these for -user builds
# which are device-specific. However, these builds require at the moment
# to run the dex pre-optimization *in* the emulator. So keep the file until
# we are capable of running dex preopt on the host.
#
_from += etc/init.goldfish.sh
_to := $(addprefix $(TARGET_OUT)/,$(_from))
_from := $(addprefix $(LOCAL_PATH)/,$(_from))
$(_to) : PRIVATE_MODULE := system_etcdir
$(_to) : $(TARGET_OUT)/% : $(LOCAL_PATH)/% | $(ACP)
$(transform-prebuilt-to-target)
ALL_PREBUILT += $(_to)
上面的参考
6. Android.mk/makefile 的ifeq和ifdef的区别
android.mk是Android操作系统编译的时候使用的编译规则文件 Makefile是Linux操作系统编译的时候使用的编译规则文件。 作用是一样的,只是名称不一样罢了
7. mk是什么格式的文件,用什么软件打开
makefile文件格式,是一种源代码编译指令集合文件,用写字板就可以打开。
8. Android.mk/makefile 的ifeq和ifdef的区别
ifeq是这样用的: ifeq(a,b) 命令1; else 命令2; 意思是如果a等于b,则执行命令1,如果不相等则执行命令2. ifdef是这样用的: ifdef a 命令1; else 命令2; 意思是说如果之前已经有这样的定义了:#define a //a可以是语句也可以是变量 则执行命令1,如果没有定义,则执行命令2.
9. 实战——Android.mk常用模板实例
LOCAL_PATH :=$(call my-dir) :编译目录
include $(CLEAR_VARS) :清理环境变量
LOCAL_JAVA_LIBRARIES := #指定依赖的共享Java类库
LOCAL_STATIC := #指定依赖的静态Java类库
#指定源码列表。 这里使用系统定义的函数搜寻 src目录下的文件形式的列表
LOCAL_SRC_FILE :=$(call all-java-files-under,src)
LOCAL_MODULE_TAGS := optional #指定模块的标签
LOCAL_CERTIFICATE := shared #指定模块的签名方式
LOCAL_PACKAGE_NAME :=testapk #指定模块的名称
include $(BUILD_PACKAGE)
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_MODULE_TAGS :=optional #指定模块的标签
LOCAL_MODULE := javadynamiclib #指定模块的名称
include $(BUILD_JAVA_LIBRARY)
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java_files-under,src)
LOCAL_MODULE :=javastaticlib #指定模块的名称
include $(BUILD_STATIC_JAVA_LIBRARY)
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_NO_STANDARD_LIBRARIES := true #指定依赖的静态Java类库
LOCAL_PACKAGE_NAME := javareslib #定义模块名
LOCAL_CERTIFICATE :=platform #指定签名类型
LOCAL_APPT_FLAGS := -x #定义aapt工具参数
LOCAL_MODULE_TAGS := user #指定模块的安装路径
LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
LOCAL_EXPORT_PACKAGE_RESOURCES := true #值为ture时,其他的apk模块能引用本模块的资源
include$(BUILD_PACKAGE) #apk
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=service.cpp hello.c
LOCAL_SHARED_LIBRARIES :=libutils libbinder #指定模块需要链接的动态库
ifeq ($(TARGET_OS),linux)
LOCAL_CFLAGS += -DXP_UNIX
#定义编译标志
endif
LOCAL_MODULE := service #指定模块的名称
include $(BUILD_EXECUTABLE)
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional #指定模块的名称
LOCAL_MODULE :=libnativedynamic #指定模块的源文件
LOCAL_SRC_FILES := \
nativedynamic.cpp
LOCAL_SHARED_LIBRARIES := \ #指定模块需要链接的动态库
libcutils \
libutils
LOCAL_SHARED_LIBRARIES := libnativestatic #指定模块依赖的静态库
LOCAL_C_INCLUDES += \ #指定头文件的查找路径
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/../include
LOCAL_CFLAGS += -O #定义编译标志
include $(BUILD_SHARED_LIBRARY)
#-----------------------------------------------------------------------------------
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional #指定模块的标签
LOCAL_MODULE :=libnativestatic #指定模块的名称
LOCAL_SRC_FILES :=\ #指定模块的源文件
nativestatic.cpp
LOCAL_C_INCLUDES += #定义编译标志
LOCAL_CFLAGS +=-O
include $(BUILD_STATIC_LIBRARY)
#-----------------------------------------------------------------------------------
10. Android.mk/makefile 的ifeq和ifdef的区别
ifeq重点在eq: equal, 等于简写
例子:
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
ifdef, def: define, 定义简写
ifdef只是测试一个变量是否有值,其并不会把变量扩展到当前位置。
例子
bar =
foo = $(bar)
ifdef foo
frobozz = yes
else
frobozz = no
endif
detail see http://blog.csdn.net/liang13664759/article/details/1771246