开发中总会遇到形形色色的小问题,猝不及防的就被射弯了膝盖🤣🤣🤣
特此整理记录,遇到的点滴,不定期更新,都是泪啊😂
1、SSLHandshakeException
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
解决方法检查手机的时间是不是准确的 , 调整手机系统时间跟当前网络时间保持一致,再次刷新尝试。
2、gradle依赖加载失败问题
gradle版本和gradle插件版本并不是一一对应的- 加载插件失败,可以尝试替换仓库:
google()
maven {
url 'https://maven.google.com/'
name 'Google'
}
3、recyclerview 内容超过一屏时,findFistCompletelyVisibleItemPosition 会返回 -1 的原因
- 原因是在
findOneVisibleChild计算出来的 start 和 end 已经超过了 reclclerview 的 start 和 end.经过研究源码得到以下。
findFirstCompletelyVisibleItemPosition -> -1
findLastCompletelyVisibleItemPosition -> -1
findFirstVisibleItemPosition -> 正常
4、混淆打包后,插件中某个混淆路径和主工程完全相同问题
混淆配置中添加 -flattenpackagehierarchy '指定文件夹名称' 让对应的Classe文件放到指定文件下,避免冲突
5、解决5.0以上Button自带阴影效果的方案
在xml定义的Button中,添加以下样式定义
style="?android:attr/borderlessButtonStyle"
6、针对 onSingleTapUp 和 onSIngleTapConfirmed 的使用区别
前者在按下并抬起时发生,后者有一个附加条件时Android会确保点击之后在短时间内没有再次点击才会触发。常用于如果需要监听单击和双击事件。
7、如何理解 Intent 传递数据出现 TransactionTooLargeException的问题
Intent 传输数据的机制中,用到了 Binder。Intent 中的数据,会作为 Parcel 被存储在 Binder 的事务缓冲区(Binder transaction buffer)中的对象进行传输.而这个 Binder 事务缓冲区具有一个有限的固定大小,当前为 1MB。这里的 1MB 空间并不是当前操作独享的,而是由当前进程所共享。也就是说 Intent 在 Activity 间传输数据,本身也不适合传递太大的数据.
更好的解释 Android 开发太难了,这异常竟然捕获不到?
8、如何解决华为设备产生太多 broadcast 导致crash的问题
部分华为中,如果app注册超过500个BroadcastReceiver就会抛出 “ Register too many Broadcast Receivers ” 异常。通过分析发现其内部有一个白名单,自己可以通过创建一个新的app,使用微信包名进行测试,发现并没有这个限制。通过反射 LoadedApk 类拿到 mReceiverResource 中的 mWhiteList 对象添加我们的包名就可以了
9、Dalvik 分包构建每一个 dex 文件时可能出现 java.lang.NoClassDefFoundError
这个问题的原因是构建工具绘制行比较复杂决策来确定主 dex 文件中需要的类以便应用能够正常的启动。如果启动期间需要的任何类在主 dex 中未能找到,则会抛出上述异常。所有必须要 multiDexKeepFile 或 multiDexKeepProguard 属性中声明他们,手动将这些类指定为主 dex 文件中的必需项。
创建 multidex-new.txt文件,写入以下新增的类
com/example/Main2.class
com/example/Main3.class
创建 meltidex-new.pro,写入以下 keep 住的类
-keep class com.example.Main2
-keep class com.example.Main3
然后在gradle multiDexKeepFile属性 和 multiDexKeepProguard属性声明上述文件
android {
buildTypes {
release {
multiDexKeepFile file 'multidex-new.txt'
multiDexKeepProguard 'multidex-new.pro'
...
}
}
10、构建一个圆角图片
11、运行时注解与编译时注解的区别是什么呢?
a)保留阶段不同。运行时注解保留到运行时,可在运行时访问。而编译时注解保留到编译时,运行时无法访问。
b)原理不同。运行时注解是Java反射机制,Retrofit运行时注解,需要用的时候才用到,而编译时注解通过APT、AbstractProcessor。
c)性能不同。运行时注解由于使用Java反射,因此对性能上有影响。编译时注解对性能没影响。这也是为什么ButterKnife从运行时切换到了编译时的原因。
d)产物不同。运行时注解只需自定义注解处理器即可,不会产生其他文件。而编译时注解通常会产生新的Java源文件
12、魅族安装apk失败问题
1.打开手机-->设置,进入设置界面,找到指纹和安全,点击进入;
2.进入指纹和安全界面,打开访客模式,如果已经开启访客模式直
接点击进入;
3.进入访客模式界面。
如果有“清除数据”选项,直接点击清楚访客数据;
如果没有“清楚数据”的选项,直接锁屏,然后输入访客密码,进
入访客模式,删除里面对应的APP,锁屏,然后再输入手机密
码(不是访客密码,是你手机解锁密码)重新进入手机安装apk。
13、关于RecyclerView中包含Edittext的问题的几种解决方法
RecyclerView中包含Edittext的问题的几种解决方法
14、HTTPS如何实现自签名SSL证书
15、InputManagerService异常DeadObjectException
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
这一行代码怎么看也不会有问题,但是仔细查看以下相关文档的说明发现有:(gjhappyyy.iteye.com/blog/129872…)
OpenGl ES关于渲染方式有以下两种:
RENDERMODE_CONTINUOUSLY
RENDERMODE_WHEN_DIRTY
默认渲染方式为RENDERMODE_CONTINUOUSLY,这两种渲染的含义是:
RENDERMODE_CONTINUOUSLY:渲染器会不停地渲染场景,
RENDERMODE_WHEN_DIRTY:只有在创建和调用requestRender()时才会刷新。
一般设置为RENDERMODE_WHEN_DIRTY方式,这样不会让CPU一直处于高速运转状态,提高手机电池使用时间和软件整体性能。
也就是说activity页面在开着的时候,即使不做任何操作,手机的CPU等资源也是处于高速运转的状态,意味着有可能会耗掉其他app所需要的资源,从而触发其他应用导致InputManagerService的异常信息。
16、安卓6.0~9.0适配
17、避坑!!webview如何加载pdf
18、dialog的context问题
dialog.getContext()不一定能拿到创建时传入的context:
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
if (createContextThemeWrapper) {
if (themeResId == ResourceId.ID_NULL) {
final TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
themeResId = outValue.resourceId;
}
//这里创建了一个ContextWrapper
mContext = new ContextThemeWrapper(context, themeResId);
} else {
mContext = context;
}
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Window w = new PhoneWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
w.setOnWindowSwipeDismissedCallback(() -> {
if (mCancelable) {
cancel();
}
});
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
19. Arrays.asList后往里add数据会报错
通常使用的ArrayList在java.util.ArrayList这个包下,实现了List接口
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
Arrays.asList生成的ArrayList在java.util.Arrays包里面的,而这里面的ArrayList并没有去实现List接口,所以也就没有add,get等方法,另外在kotlin里面,我们会看到一个细节,当你敲完Arrays.asList的时候,编译器会提示你,可以转换成listof函数,而这个还是我们知道生成的list都是只能读取,不能往里写数据
20.Thread.sleep(0)到底“睡没睡”
在Android操作系统中,每个线程使用cpu资源都是有优先级的,优先级高的才有资格使用,而操作系统则是在一个线程释放cpu资源以后,重新计算所有线程的优先级来重新分配cpu资源,所以sleep真正的意义不是暂停,而是在接下去的时间内不参与cpu的竞争,等到cpu重新分配完资源以后,如果优先级没变,那么继续执行,所以sleep(0)秒的真正含义是触发cpu资源重新分配