toolbar左边空白问题
toolbar自定义布局时,无论如何调整布局的间距,左侧始终有一个空白区域,如下图:
答案:这是因为toolbar使用的主题apptheme里面有这样一段代码:
<item name="contentInsetStart">16dp</item>
这段代码会自动将toolbar里面的起始间隔设置为16dp,如何解决呢?有两种解决办法,其一,继承toolbar的theme主题,重写contentInsetStart为0dp;其二是在toolbar里面设置
app:contentInsetStart="0dp"
但是这句必须写到apptheme的后面才生效
Android屏幕亮度问题
- 系统亮度,亮度值分为0~255,获取系统亮度
int brightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
- 当前屏幕亮度,0.0~1.0的浮点型,根据系统亮度调节当前屏幕亮度
Window window = this.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
if (brightness == -1) {
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
} else {
lp.screenBrightness = (brightness <= 0 ? 1 : brightness) / 255f;
}
window.setAttributes(lp);
brightness==-1的判断是将-1作为一个标志位,标志当app设置中包含"跟随系统亮度"或者"恢复系统亮度"的时候,我们传递一个-1参数,这时将screenBrightness参数还原成默认数值(跟随系统)即可
StringBuilder清空方法
StringBuilder是一种可变字符串类,提供缓存的;但是此类没有明确提供清空字符串的方法,只能通过调用类似方法达到目的,方法有三:
(1)重新new一个StringBuilder,由垃圾回收器回收处理
(2)sb.delete(start,end)删除从头到尾
(3)sb.setLength(int),设置长度为0
三种方法里面,第二种效率更改
try(){}catch{}新特性
JDK1.7后try catch新语法,可以try()里面可以写一些IO流的赋值创建操作,在try语句结束后,会自动关闭IO流,不用自己在手动处理关闭;
try {
PrintWriter writer = new PrintWriter("demo.txt");
writer.write("dsfsd");
}catch (IOException e){
e.printStackTrace();
}
可以作为GCROOT的对象节点
常说的GC(Garbage Collector) roots,特指的是垃圾收集器(Garbage Collector)的对象,GC会收集那些不是GC roots且没有被GC roots引用的对象。
一个对象可以属于多个root,GC root有几下种:
Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。我们需要注意的一点就是,通过用户自定义的类加载器加载的类,除非相应的java.lang.Class实例以其它的某种(或多种)方式成为roots,否则它们并不是roots
- Thread - 活着的线程
- Stack Local - Java方法的local变量或参数
- JNI Local - JNI方法的local变量或参数
- JNI Global - 全局JNI引用
- Monitor Used - 用于同步的监控对象
- Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此就只有留给分析分员去确定哪些是属于"JVM持有"的了。
JNI部分
C++语法
std::nothrow标准库
即普通new和标准头文件里面的new(nothrow new),早起的C++环境new分配内存失败返回0,在某些特定的环境又会返回NULL空指针的情况,为了防止两种情况下返回不同的值,C++委员会规定了一个新版本的new,也就是nothrow new,此版本分配失败返回0;不要以为这个可有可无,在某些情况下,分配失败是非常普通的,它们通常在植入性和不支持异常的可移动的器件中发生更频繁。因此,应用程序开发者在这个环境中使用nothrow new来替代普通的new是非常安全的。
if(nullptr == s_AgentManager)
{
s_AgentManager = new (std::nothrow) AgentManager();
//s_AgentManager->init();
}
dynamic_cast
由基类强制转换为子类,在运行状态时,如果基本实例的确是派生类的实例,dynamic_cast将强制转换为子类;反之,则返回空指针
jni调用java方法
java方法调用jni想必都知道,但是jni调用却不一定清楚;jni调用java步骤有三
- jni的FindClass找到java对象的实例
- 通过java实例找到方法methodId
- 最后利用java对象实例和methodId调用方法
例子:
JNIEXPORT void JNICALL Java_cn_itcast_ndkcallback_DataProvider_callmethod1
(JNIEnv * env, jobject obj){
//在c代码里面调用java代码里面的方法
// java 反射
//1 . 找到java代码的 class文件
// jclass (*FindClass)(JNIEnv*, const char*);
jclass dpclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DataProvider");
if(dpclazz==0){
LOGI("find class error");
return;
}
LOGI("find class ");
//2 寻找class里面的方法
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID method1 = (*env)->GetMethodID(env,dpclazz,"helloFromJava","()V");
if(method1==0){
LOGI("find method1 error");
return;
}
LOGI("find method1 ");
//3 .调用这个方法
// void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env,obj,method1);
}
最后一步调用java方法,jni提供了更多的方法接口:
jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;
jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;
jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;
void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jni日志打印
1、在JNI的实现代码文件(.c或者.cpp)中加入包含LOG头文件的如下代码:
#include <Android/log.h>
2、在需要打印的方法中添加打印代码,例如:
__android_log_print(ANDROID_LOG_INFO, "JniX431FileTest", "lsx_init");
ANDROID_LOG_INFO:是日志级别;
"JniX431FileTest":是要过滤的标签,可以在LogCat视图中过滤。
"lsx_init":是实际的日志内容。
3、在Android工程的Android.mk文件中添加如下内容:
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
Android的assets资源和raw资源
众所周知,assets和raw目录下的资源时不经过编译直接合入到最终的apk包里面去,两者的区别是,存放内容大小不一样和访问方式不一样,其他都是一样的;如果是这样的话,那么我们是不是可以直接把资源放到apk里面去在签上名就可以用了?
答案是否定的,为什么呢?
因为aapt在编译的时候,虽然不编译压缩这些资源,但是会把这些文件的状态,位置描述存放到sqlite数据库里面去,到时候你在java代码里面使用时就会重数据库里面找到这些文件位置信息,在去提取;
资源链接
[依赖注入框架dagger][1]
[1]:http://blog.fidroid.com/post/android/dagger-on-android-dagger2xiang-jie