android常见的FAQ

toolbar左边空白问题

toolbar自定义布局时,无论如何调整布局的间距,左侧始终有一个空白区域,如下图:
android常见的FAQ_第1张图片
答案:这是因为toolbar使用的主题apptheme里面有这样一段代码:

 16dp

这段代码会自动将toolbar里面的起始间隔设置为16dp,如何解决呢?有两种解决办法,其一,继承toolbar的theme主题,重写contentInsetStart为0dp;其二是在toolbar里面设置

app:contentInsetStart="0dp"

但是这句必须写到apptheme的后面才生效


Android屏幕亮度问题

  1. 系统亮度,亮度值分为0~255,获取系统亮度
int brightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
  1. 当前屏幕亮度,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 

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代码里面使用时就会重数据库里面找到这些文件位置信息,在去提取;

解决文件表情input type="file"在webview下无法打开文件

资源链接

[依赖注入框架dagger][1]
[1]:http://blog.fidroid.com/post/android/dagger-on-android-dagger2xiang-jie
[2]:https://www.jianshu.com/p/48e688ce801f

你可能感兴趣的:(android)