假如你的 ImageButton 的宽高是100x100,而你要设置上去的图片是80x80, 1.如果用src进行设置,则你的图片会按80x80 居中绘制上去。 2.如果你使用的是background 则 你设置上去的图片会被拉伸成100x100 简单说来,就是用src的时候是原图显示,不改变图片的大小;用background的时候,按照组件的大小来放大或者缩小图片。
假如你的 ImageButton 的宽高是100x100,而你要设置上去的图片是80x80, 1.如果用src进行设置,则你的图片会按80x80 居中绘制上去。 2.如果你使用的是background 则 你设置上去的图片会被拉伸成100x100 简单说来,就是用src的时候是原图显示,不改变图片的大小;用background的时候,按照组件的大小来放大或者缩小图片。
Android.mk文档规范 Android.mk 编译文件是用来向 Android NDK描述你的 C,C++源代码文件的, 这篇文档描 述了它的语法。在阅读下面的内容之前,假定你已经阅读了 docs/OVERVIEW.TXT 文件,了解 了它们的脚色和用途。 一、概述 一个 Android.mk file 用来向编译系统描述你的源代码。具体来说: (1) 该文件是GNU Makefile的一小部分, 会被编译系统解析一次或更多次的build系统。 因此,您应尽量减少您声明的变量,不要认为某些变量在解析过程中不会被定义。 (2)这个文件的语法允许把你的源代码组织成模块,一个模块属下列类型之一: 1)静态库 2)共享库 且只有共享库将被安装/复制到您的应用软件包,虽然静态库能被用于生成共享库。 可以在每一个 Android.mk file 中定义一个或多个模块, 你也可以在几个模块中使用同一个 源代码文件。 编译系统为你处理许多细节问题。例如,你不需要在你的 Android.mk 中列出头文件和依 赖文件。NDK 编译系统将会为你自动处理这些问题。这也意味着,在升级 NDK 后,你应该 得到新的 toolchain/platform支持,而且不需要改变你的 Android.mk 文件。 注意,这个语法同公开发布的 Android平台的开源代码很接近,然而编译系统实现他们的 方式却是不同的,这是故意这样设计的,可以让程序开发人员重用外部库的源代码更容易。 在描述语法细节之前,咱们来看一个简单的"hello world"的例子,比如,下面的文件: sources/helloworld/helloworld.c sources/helloworld/Android.mk 'helloworld.c'是一个 JNI 共享库,实现返回"hello world"字符串的原生方法。相应的 Android.mk 文件会象下面这样: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= helloworld LOCAL_SRC_FILES := helloworld.c include $(BUILD_SHARED_LIBRARY) 解释一下这几行代码: LOCAL_PATH := $(call my-dir) 一个Android.mk file首先必须定义好LOCAL_PATH变量。 它用于在开发树中查找源文件。 在这个例子中, 宏函数‘my-dir’, 由编译系统提供, 用于返回当前路径(即包含Android.mk file 文件的目录)。 include $(CLEAR_VARS) CLEAR_VARS 由编译系统提供(可以在 android 安装目录下的/build/core/config.mk 文件看 到其定义,为 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk),指定让 GNU MAKEFILE 为你清除许多 LOCAL_XXX 变量 ( 例如 LOCAL_MODULE , LOCAL_SRC_FILES , Android.mk 文档规范 2 LOCAL_STATIC_LIBRARIES,等等…),除 LOCAL_PATH。这是必要的,因为所有的编译控 制文件都在同一个 GNU MAKE 执行环境中,所有的变量都是全局的。 LOCAL_MODULE := helloworld LOCAL_MODULE 变量必须定义,以标识你在 Android.mk 文件中描述的每个模块。名称 必须是唯一的,而且不包含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话 说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。注意:如果把库命名为 ‘libhelloworld’,编译系统将不会添加任何的 lib 前缀,也会生成 libhelloworld.so,这是 为了支持来源于 Android平台的源代码的 Android.mk 文件。 LOCAL_SRC_FILES := helloworld.c LOCAL_SRC_FILES 变量必须包含将要编译打包进模块中的 C 或 C++源代码文件。不用 在这里列出头文件和包含文件,编译系统将会自动找出依赖型的文件。 【注意,默认的 C++源码文件的扩展名是‘.cpp’ 。指定一个不同的扩展名也是可能的,只要定义 LOCAL_DEFAULT_CPP_EXTENSION 变量,不要忘记开始的小圆点(也就是定义为 ‘.cxx’,而不是‘cxx’)】 include $(BUILD_SHARED_LIBRARY) BUILD_SHARED_LIBRARY 是编译系统提供的变量,指向一个 GNU Makefile 脚本(应该 就是在 build/core 目录下的 shared_library.mk) ,负责收集自从上次调用 'include $(CLEAR_VARS)'以来,定义在 LOCAL_XXX 变量中的所有信息,并且决定编译什么,如何正 确地去做。并根据其规则生成静态库。同理对于静态库。 在 sources/samples目录下有更复杂一点的例子,写有注释的 Android.mk 文件。 二、参考 这是一份你应该在 Android.mk 中依赖或定义的变量列表, 可以定义其他变量为自己使用, 但是 NDK编译系统保留下列变量名: -以 LOCAL_开头的名字(例如 LOCAL_MODULE) -以 PRIVATE_, NDK_ 或 APP_开头的名字(内部使用) -小写名字(内部使用,例如‘my-dir’) 如果为了方便在 Android.mk 中定义自己的变量,建议使用 MY_前缀,一个小例子: MY_SOURCES := foo.c ifneq ($(MY_CONFIG_BAR),) MY_SOURCES += bar.c endif LOCAL_SRC_FILES += $(MY_SOURCES) 1. GNU Make 变量 这些 GNU Make 变量在你的 Android.mk 文件解析之前,就由编译系统定义好了。注意在 某些情况下,NDK可能分析 Android.mk 几次,每一次某些变量的定义会有不同。 (1)CLEAR_VARS: 指向一个编译脚本,几乎所有未定义的 LOCAL_XXX 变量都在 "Module-description"节中列出。必须在开始一个新模块之前包含这个脚本:include $(CLEAR_VARS) (2)BUILD_SHARED_LIBRARY: 指向编译脚本,收集
首先看一下下面的程序(测试英文和中文在Unicode、UTF-8、UTF-16这三种编码下,一个字符占几个字节) [java] view plaincopy System.out.println("a(Unicode) :" + "a".getBytes("Unicode").length); System.out.println("a(Unicode) :" + "aa".getBytes("Unicode").length); System.out.println("啊(Unicode) :" + "啊".getBytes("Unicode").length); System.out.println("啊啊(Unicode) :" + "啊啊".getBytes("Unicode").length); System.out.println(""); System.out.println("a(UTF-8) :" + "a".getBytes("UTF-8").length); System.out.println("aa(UTF-8) :" + "aa".getBytes("UTF-8").length); System.out.println("啊(UTF-8) :" + "啊".getBytes("UTF-8").length); System.out.println("啊啊(UTF-8) :" + "啊啊".getBytes("UTF-8").length); System.out.println(""); System.out.println("a(UTF-16) :" + "a".getBytes("UTF-16").length); System.out.println("aa(UTF-16) :" + "aa".getBytes("UTF-16").length); System.out.println("啊(UTF-16) :" + "啊".getBytes("UTF-16").length); System.out.println("啊啊(UTF-16) :" + "啊啊".getBytes("UTF-16").length); 运行结果如下: a(Unicode) :4 a(Unicode) :6 啊(Unicode) :4 啊啊(Unicode) :6 a(UTF-8) &nbs
http 和 https url错误问题,参见 The HttpURLConnection‘s follow redirect is just an indicator, in fact it won’t help you to do the “real” http redirection, you still need to handle it manually. URL obj = new URL(url); HttpURLConnection conn = (HttpURLConnection) obj.openConnection(); conn.setInstanceFollowRedirects(true); //you still need to handle redirect manully. HttpURLConnection.setFollowRedirects(true); 1. Java Http Redirect Example If a server is redirected from the original URL to another URL, the response code should be 301: Moved Permanently or 302: Temporary Redirect. And you can get the new redirected url by reading the “Location” header of the HTTP response header. For example, access to the normal HTTP twitter website – http://www.twitter.com , it will auto redirect to the HTTPS twitter website – https://www.twitter.com. HttpRedirectExample – Full Java follow redirect example, see comments for self-explanatory. package com.mkyong.http; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class HttpRedirectExample { public static void main(String[] args
jclass和jobject的迷惑 第一次使用JNI,实例引用(jobject)和类引用(jclass)让人觉得很困惑。 实例引用与一个数组和java.lang.Object类或它的子类的实例对应。类引用与java.lang.Class实例对应,它代表着类的类型。 一 个操作如GetFieldID,需要参数jclass,是一个类操作,因为它从一个类中获得field的描述。与此相反,GetIntField需要参数 jobject,这是一个实例操作,因为它从这个实例中获得这个field的值。在所有的JNI方法中jobject和实例操作的结合和jclass和类 操作的结合保持一致。所以是很容易记住类操作与实例操作的不同的。 随后,普及下静态方法和实例方法的区别: 静态方法与静态变量一样,属于类本身,而不属于那个类的一个对象。调用一个被定义为static的方法,可以通过在它前面加上这个类的名称,也可以像调用非静态方法一样通过类对象调用。 实例方法必须通过类的实例来使用。实例方法可以使用类的非静态成员,也可以使用类的静态成员。 类的静态方法,静态变量是在类装载的时候装载的。但是要特别注意,类的静态变量是该类的对象所共有的,即是所有对象共享变量。所以建议尽量少用静态变量。尽量在静态方法中使用内部变量。 其中static关键字即表示静态的。声明静态方法的语法如下: <访问修饰符>static返回类型 方法名(参数列表) {//方法体} 静态方法与实例方法唯一不同的,就是静态方法在返回类型前加static关键字。静态方法的调用有两种途径: (1)通过类的实例对象去调用 调用格式为: 对象名.方法名 (2) 通过类名直接调用 调用格式为: 类名::方法名 对于JNI的头文件的区别: /* * Class: com_nedu_jni_helloword_HeaderFile * Method: doInt * Signature: (DD)I */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DD (JNIEnv *, jobject, jdouble, jdouble); /* * Class: com_nedu_jni_helloword_HeaderFile * Method: doInt * Signature: (DDD)I */ JNIEXPORT jint JNICALL Java_com_nedu_jni_helloword_HeaderFile_doInt__DDD (JNIEnv *, jclass, jdouble, jdouble, jdouble); 这里可以看到参数列表的第二个参数的类型不一样,第一个是jobject,表明这个函数是一个实例方法,指向这个实例;而下面的是jclass,表明是个静态方法,指向这个类的class
Android Studio集成和添加了一些实用的工具,其中一个便是terminal。在Windows平台下Android Studio中的terminal在原理上实际使用的是window中的cmd控制台也就是位于C:\Windows\System32\目录下的 cmd.exe。升级了win10的用户会发现,win10下的cmd比以前平台下的cmd改进了不少,但这些改进也导致了Android studio在调用cmd上出现了问题。 解决办法: 打开cmd控制台窗口,在选项中进行如下操作,如图: 然后重启系统即可。 再次打开Android Studio你会发下terminal可以用了。
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 libaudiopolicybas
@author ASCE1885的 Github 简书 微博 CSDN 原文链接 早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种! Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起),每一种都关联着一个相应的ABI。 应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐到可用的系统函数库。在Android 系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。 为什么你需要重点关注.so文件 如果项目中使用到了NDK,它将会生成.so文件,因此显然你已经在关注它了。如果只是使用Java语言进行编码,你可能在想不需要关注.so文件 了吧,因为Java是跨平台的。但事实上,即使你在项目中只是使用Java语言,很多情况下,你可能并没有意识到项目中依赖的函数库或者引擎库里面已经嵌 入了.so文件,并依赖于不同的ABI。 例如,项目中使用RenderScript支持库,OpenCV,Unity,android-gif-drawable,SQLCipher等,你都已经在生成的APK文件中包含.so文件了,而你需要关注.so文件。 Android应用支持的ABI取决于APK中位于lib/ABI目录中的.so文件,其中ABI可能是上面说过的七种ABI中的一种。 Native Libs Monitor这个应用可以帮助我们理解手机上安装的APK用到了哪些.so文件,以及.so文件来源于哪些函数库或者框架。 当然,我们也可以自己对app反编译来获取这些信息,不过相对麻烦一些。 很多设备都支持多于一种的ABI。例如ARM64和x86设备也可以同时运行armeabi-v7a和armeabi的二进制包。但最好是针对特定 平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新,例 如硬件fpu,更多的寄存器,更好的向量化等)。 我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为 Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,如果在对应的lib/ABI目录中存在.so文件的 话。 App中可能出错的地方 处理.so文件时有一条简单却并不知名的重要法则。 你应该尽可能的提供专为每个ABI优化过的.so文件,但要么全部支持,要么都不支持:你不应该混合着使用。你应该为每个ABI目录提供对应的.so文件。 当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。在x86设备上,libs/x86目录中如果存在.so文件的话, 会被安装,如果不存在,则会选择armeabi-v7a中的.so文件,如果也不存在,则选择armeabi目录中的.so文件(因为x86设备也支持 armeabi-v7a和armeabi)。 其他地方也可能出错 当你引入一个.so文件时,不止影响到CPU架构。我从其他开发者那里可以看到一系列常见的错误,其中最多的是"UnsatisfiedLinkError","dlopen: failed"以及其他类型的crash或者低下的性能: 使用android-21平台版本编译的.so文件运行在android-15的设备上 使用NDK时,你可能会倾向于使用最新的编译平台,但事实上这是错误的,因为NDK平台不是后向兼容的,而是前向兼容的。推荐使用app的minSdkVersion对应的编译平台。 这也意味着当你引入一个预编译好的.so文件时,你需要检查它被编译所用的平台版本。 混合使用不同C++运行时编译的.so文件 .so文件可以依赖于不同的C++运行时,静态编译或者动态加载。混合使用不同版本的C++运行时可能导致很多奇怪的crash,是应该避免的。作 为一个经验法则,当只有一个.so文件时,静态编译C++运行时是没问题的,否则当存在多个.so文件时,应该让所有的.so文件都动态链接相同的C++ 运行时。 这意味着当引入一个新的预编译.so文件,而且项目中还存在其他的.so文件时,我们需要首先确认新引入的.so文件使用的C++运行时是否和已经存在的.so文件一致。 没有为每个支持的CPU架构提供对应的.so文件 这一点在前文已经说到了,但你应该真的特别注意它,因为它可能发生在根本没有意识到的情况下。 例如:你的app支持armeabi-v7a和x86架构,然后使用Android Studio新增了一个函数库依赖,这个函数库包含.so文件并支持更多的CPU架构,例如新增android-gif-drawable函数库: compile ‘pl.droidsonroids.gif:android-gif-drawable:1.1.+’ 发布我们的app后,会发现它在某些设备上会发生Crash,例如Galaxy S6,最终可以发现只有64位目录下的.so文件被安装进手机。 解决方案:重新编译我们的.so文件使其支持缺失的ABIs,或者设置 ndk.abiFilters 显示指定支持的ABIs。 最后一点:如果你是一个SDK提供者,但提供的函数库不支持所有的ABIs,那你将会搞砸你的用户,因为他们能支持的ABIs必将只能少于你提供的。 将.so文件放在错误的地方 我们往往很容易对.so文件应该放在或者生成到哪里感到困惑,下面是一个总结: Android Studio工程放在jniLibs/ABI目录中(当然也可以通过在build.gradle文件中的设置jniLibs.srcDir属性自己指定) Eclipse工程放在libs/AB
著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处。 作者:夏海亮 链接:http://www.zhihu.com/question/32298079/answer/56010423 来源:知乎 通过这两天对Android Studio的研究,终于搞通了Android Studio的基本操作及与SVN的相关关联操作(这样才能在公司的开发工作中使用);Google年底将会停止ADT插件的更新和支持,全面转向Android Studio(果然是自己的孩子啊),因此使用Android Studio进行安卓项目的开发也是大势所趋,项目得闲之时研究一下Android Studio的使用;Android Studio的基本编辑操作现在网上已经很多了,需要的可以找着看看,下面是这几天摸索出来的Android Studio关联SVN的相关操作,时间较短,如果有疏漏或错误的地方还望指正。 一、Android Studio配置SVN Android Studio关联配置SVN很简单,在Settings里面,找到Version Control->Subversion;在这个页面的控制面板中的General中将Use command line client打勾勾选上,然后浏览本地的SVN安装目录,选到"\svn.exe"即可; 在Use command line client下面还有一个Use system default Subversion configuration directory,这个默认是勾选上上的,这个是svn相关配置信息的路径,保留默认路径就行,目前没有发现需要修改什么东西;以上操作如下图: 二、Android Studio项目关联SVN资源库及添加忽略文件 在Android Studio中新创建一个Android项目,成功后我们先来添加要忽略的文件;在Android Studio中添加忽略文件同Eclipse有所不同,在Eclipse上我们什么时候添加忽略文件都可以,但是在Android Studio中只有在未关联SVN之前添加忽略文件才有效(试了好多次才将忽略文件忽略成功啊!)。Android Studio添加忽略文件同样是在Settings->Version Control(跟版本控制有关的设置都在这个目录下)下的Ignored Files里,点击加号进行忽略文件的设置,Android Studio默认给出了三种忽略方式,供开发者进行选择:忽略指定的文件、忽略文件夹下所有文件和忽略符合匹配规则的文件;如图所示: 点击右侧的“+”进行添加,“-”删除;Android Studio创建的Android项目一般需要忽略.idea文件夹、.gradle文件夹、所有的build文件夹、所有的.iml文件及local.properties文件。 忽略完文件后,我们进行项目同SVN的关联,选择VCS->Import into Version Control->Share Project(Subversion);这里说明一点,在Import into Version Control下有Import into Subversion和Share Project(Subversion)两个选项:第一个是直接将项目导入到SVN服务器上,但是这样做本地的项目同SVN服务器没有建立起关联,在导入后项目所有的文件都会变成红色,而且在要提交到SVN服务器时会提示项目不是SVN下的工作副本;第二个是将Android Studio当前项目同SVN服务器关联起来,但是并没有将项目导入到SVN服务器上,需要在完成建立连接后再次提交项目到SVN服务器。两种方式都可以实现将本地代码提交到SVN服务器的功能,但是步骤有所不同,先来完成第二种方式的项目同SVN的关联及代码提交,第一种貌似不正规,之后再说;下图既是第二种方式将本地项目同SVN进行关联的: 之后会弹出选择要分享的SVN地址及其他选项,如下图:
Some things to point out, make sure you have your settings.gradle updated to reference both the app and library modules. settings.gradle: include ':app', ':libraries:lib1', ':libraries:lib2' Also make sure that the app's build.gradle has the followng: dependencies { compile project(':libraries:lib1') } You should have the following structure: MyProject/ | settings.gradle + app/ | build.gradle + libraries/ + lib1/ | build.gradle + lib2/ | build.gradle The app's build.gradle should use the