快速点击StartActivity引发的误会

问题来源





在A 跳到 B ,再跳到C的过程中,一定条件下发送广播,需要把B关掉,达到的效果就是 C直接返回A。


但是现在出现一个Bug就是C返回的时候,还是B。当时没有打印onCreate的日志,只发现B在前面finish了,居然又在后面onResume了,这显然违反科学。当时想就算B启动了多个,B也都在onCreate的时候注册了广播,都应该可以收到广播的。后面怀疑是手滑不小心点击了2次,或是系统突然响应过慢,点击了多次,造成创建了多个实例,所以我直接通过for循环快速模拟这种情况。

阅读更多

JNI为什么要调用AttachCurrentThread?

我们写JNI的时候,通常要通过 如果需要反调java层的代码,是需要通过jvm->AttachCurrentThread 将当前线程注册到虚拟机中,为什么一定要调用这个方法呢?我们追一下这个方法里面到底做了什么?

阅读更多

如何用AndroidStudio动态调试ART虚拟机?

1.前言

之前有debug过jvm, 开发anroid 临时起意想能不能动态debug art虚拟机,代码是看不下去的,还是跑起来直观。其实调试其他native lib 的原理是一样的。网上也看到一些,受启发比较大的是这位大佬17年写的https://zhuanlan.zhihu.com/p/24867284, 在此先感谢一下他,自己也算是做一个较的,记录一下自己踩过的坑。以下全部基于Android 9 。

2. 编译Android 9 系统

这个有门槛,毕竟AOSP 超大。有个在64核服务器当然好,大概半个小时,全目录60GB左右,但是自己笔记本还是吃不消的,怎么拉下自己编译,还请google。如果只是想要原生这里有https://ci.android.com/,AOSP google编译的,可以在里面直接下载AOSP编译文件,也比较大,且需要联网。如果你还有个pixel, 还可以用来刷机。

阅读更多

理解MeasureSpec widthMeasureSpec/heightMeasureSpec

在 onMeasure中的参数 heightMeasureSpec 又是什么?

MeasureSpec是父控件提供给子View的onMeaure参数,作为设定自身大小参考,只是个参考,要多大,还是View自己说了算。

MeasureSpec 是一个复合参数,包含了specMode和specSize,可以通过如下获取。

阅读更多

View的几个高度/宽度

自定义view的过程

onMeasure()–>onLayout()–>onDraw()

  • onMeasure() 计算当前各个子view的高宽度

  • onLayout() 确定各个子view在父容器的位置

阅读更多

深入理解Handler原理

一. Handler初始化

Handler–> Looper <– MessageQueue <– Message


Handler需要Looper,Looperl里包含构建的MessageQueue。 可以在构造的时候,通过参数传入。

1. Handler 构造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public Handler(Callback callback, boolean async) {

//检查潜在的泄漏
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}

//获取当前线程的Looper
mLooper = Looper.myLooper();
//Handler需要Looper,如果为null,抛出异常
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
//设置当前Handler的MessageQueue 等于Looper的MessageQueue
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
阅读更多