一、前言
一年前写过几篇Android基础的知识,但是网上这类博客的数量已经很多了。而我又不自认为能比别人写出更好更新的知识点。就不再重复造轮子了。这次,我打算将自己在项目中遇到的Android开发常见的坑,或者是一些实用的技巧记录下来,以日记的形式,按遇到的顺序记录,而不是按类整理。
二、本篇知识点
1,Android导入第三方库过多,导致方法数量大于65535时,如何解决?
答案是分包,在app模块下的build.gradle中导入multidex库,具体操作如下:
android{
defaultConfig{
...
//把允许分包打开
multiDexEnabled = true
}
}
denpendencise{
//加入分包库
implementation 'com.android.support:multidex:1.0.0'
}
当然,gradle中配置完成后,还需要在application中将 MultiDex 初始化。有2种方式,一是extend MultiDexApplication,但是由于java单继承,通常都用来继承某个第三方库的了。我们可以用第二种方式:在attachBaseContext中初始化。
@Override
protected void attachBaseContext(Context base) {
MultiDex.install(base);
}
完成上面3步,分包工作就完成了,我们就可以继续愉快的导入第三方库了。
2,Android studio版本更新到3.0以后,使用全局变量Handler的时候,整个代码块是黄色的背景,这是为什么呢?
原因是直接使用Handler当全局变量,可能会引起内存泄漏,正确的方式是自定义一个静态的MyHandler。
private MyHandler myHandler = new MyHandler(this);
private static class MyHandler extends Handler {
//使用一个弱引用
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = mActivity.get();
}
}
3,Android Studio 有时会出现遇到编译错误之后,你修改错误文件却仍然报同样的错误,并且还把你的修改给还原到错误的情况。这种情况下,不论是clean还是rebuild甚至使用File下的Invalidate Caches / Restart..也无法解决。本人尝试了各种坑之后,发现是app下的build中generated文件夹在作怪。所以解决方法是,把app下的build文件夹中的东西全部删除。修改错误文件之后再clean,就OK了。
4,我们都知道的是android中不能在非UI线程中更新view视图。但是有时你使用代码在onCreate方法中这样写了不会报错,但是你一旦在后续的交互操作中这样做了就会报错。这是为什么呢?看下错误提示信息中,有一个ViewRootImpl的概念。说如果调用更改视图的方法所在的ViewRootImpl与view创建者所在的ViewRootImpl不一致就报错。这样我们明白了,子线程中创建的view是可以在该子线程中更新的。因为他们的ViewRootImpl是一致的!回到前面的问题,为啥onCreate中直接在子线程更新UI线程中的view不会报错?因为执行你更新view的方法时,该view所在的ViewRootImpl还没有实例化(这个过程是异步的),所以你在onCreate方法中没有报错是个巧合。后面交互时,该view的ViewRootImpl已经被实例化了,所以再更新就会报错。如何验证这一点?很简单,使用debug模式在onCreate方法中断点停顿一下。再执行就会看到onCreate方法中更新view也会报错了。因为断点时,ViewRootImpl已经在异步里实例化成功。
三、结束语。
好了,第一次发博客,把最近一周遇到的几个疑难点记录一下。遇到类似问题的朋友可以参考,欢迎留言交流。