小米09月工作记录 工作记录
小米09月工作记录
2015.09.01
-
它是整个Binder机制的守护进程,涉及到Binder进程间通信。
-
它在init进程启动之后启动。
-
管理系统中service,包括 add_service、check_service、get_service(获取服务)。
-
不同于一般的进程间通信方式(共享内存,信号,信号量,socket,管道等)
-
其实就是提供RPC功能(Remote Process Call)
-
Binder机制主要由4部分系统组件组成,Client、Server、Service Manager(这三运行在用户空间)、Binder驱动程序(运行在内核空间)。其中Service Manager和Binder驱动程序已经在Android中实现好了,用户只要按照规范实现自己的Client和Server组件就可以通信了。
-
Binder驱动程序提供设备文件/dev/binder与用户空间交互,Client、Server和Service Manager通过open和ioctl文件操作函数与Binder驱动程序进行通信。
BnMediaPlayerService是一个Binder本地对象,它在内核中有一个对应的Binder实体对象,当另外一个进程要使用MediaPlayerService的时候,Binder驱动程序就会在内核创建一个Binder引用对象,同时在那个进程创建一个Binder代理对象,即一个BpMediaPlayerService对象。这四个对象是有一一对应关系的,因此,当一个进程调用BpMediaPlayerService对象的transact函数时,通过Binder驱动程序就可以找到对应的BnMediaPlayerService对象,并且调用它的OnTransact函数。
接下去的while循环是通过sm->getService接口来不断尝试获得名称为“media.player”的Service,即MediaPlayerService。为什么要通过这无穷循环来得MediaPlayerService呢?因为这时候MediaPlayerService可能还没有启动起来,所以这里如果发现取回来的binder接口为NULL,就睡眠0.5秒,然后再尝试获取,这是获取Service接口的标准做法。 (MiLinkService也是这么干的)
2015.09.06
-
只要你触摸了任何控件,肯定是先调用该控件的
view.dispatchTouchEvent
方法。//{java} public boolean dispatchTouchEvent(MotionEvent event) { if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && mOnTouchListener.onTouch(this, event)) { return true; } return onTouchEvent(event); }
-
由上源码可以看出
onTouch
与onTouchEvent
的关系,mOnTouchListener
是注册的回调。 -
执行的log。case:都不拦截和消费。
//{bash} 09-06 14:01:23.639 V/TouchEventActivity( 1750): dispatchTouchEvent begin action:0 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): dispatchTouchEvent begin 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): onInterceptTouchEvent begin 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): onInterceptTouchEvent result = false 09-06 14:01:23.639 V/TouchEventView( 1750): dispatchTouchEvent begin 09-06 14:01:23.639 V/TouchEventView( 1750): onTouchEvent begin 09-06 14:01:23.639 V/TouchEventView( 1750): onTouchEvent result = false 09-06 14:01:23.639 V/TouchEventView( 1750): dispatchTouchEvent result = false 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): onTouchEvent begin 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): onTouchEvent result = false 09-06 14:01:23.639 V/TouchEventViewGroup( 1750): dispatchTouchEvent result = false 09-06 14:01:23.639 V/TouchEventActivity( 1750): onTouchEvent begin 09-06 14:01:23.649 V/TouchEventActivity( 1750): onTouchEvent result = false 09-06 14:01:23.649 V/TouchEventActivity( 1750): dispatchTouchEvent result = false // 这里为什么move事件不往下传了呢。因为down事件没有被消费,如果down事件在viewgroup层被消费,则move事件就只会传到viewgroup层。 09-06 14:01:23.659 V/TouchEventActivity( 1750): dispatchTouchEvent begin action:2 09-06 14:01:23.659 V/TouchEventActivity( 1750): onTouchEvent begin 09-06 14:01:23.659 V/TouchEventActivity( 1750): onTouchEvent result = false 09-06 14:01:23.659 V/TouchEventActivity( 1750): dispatchTouchEvent result = false 09-06 14:01:23.689 V/TouchEventActivity( 1750): dispatchTouchEvent begin action:2 09-06 14:01:23.689 V/TouchEventActivity( 1750): onTouchEvent begin 09-06 14:01:23.689 V/TouchEventActivity( 1750): onTouchEvent result = false 09-06 14:01:23.689 V/TouchEventActivity( 1750): dispatchTouchEvent result = false
就是touch事件的层级传递。我们都知道如果给一个控件注册了touch事件,每次点击它的时候都会触发一系列的ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件。这里需要注意,如果你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发后一个action。
说到这里,很多的朋友肯定要有巨大的疑问了。这不是在自相矛盾吗?前面的例子中,明明在onTouch事件里面返回了false,ACTION_DOWN和ACTION_UP不是都得到执行了吗?其实你只是被假象所迷惑了,让我们仔细分析一下,在前面的例子当中,我们到底返回的是什么。
参考着我们前面分析的源码,首先在onTouch事件里返回了false,就一定会进入到onTouchEvent方法中,然后我们来看一下onTouchEvent方法的细节。由于我们点击了按钮(Clickable),就会进入到第14行这个if判断的内部,然后你会发现,不管当前的action是什么,最终都一定会走到第89行,返回一个true。
是不是有一种被欺骗的感觉?明明在onTouch事件里返回了false,系统还是在onTouchEvent方法中帮你返回了true。就因为这个原因,才使得前面的例子中ACTION_UP可以得到执行。 -
Activity接受所有事件。
adb shell monkey -p com.zifei.on -v 500
自动化测试,一阵狂跑。
2015.09.07
Process.kill(myPid)
适合杀死属于自己包名的进程。
Binder机制中Client如何获得Server远程接口 好文章要多看。
我们要获得MediaPlayerService的远程接口,实际上就是要获得一个称为BpMediaPlayerService对象的IMediaPlayerService接口。
::getMediaPlayerService
过程分析
- 通过
defaultServiceManager
函数来获得Service Manager的远程接口,实际上就是获得BpServiceManager的IServiceManager接口
2015.09.08
发版前客户端调用milink差点改出一个大bug,幸好是虚惊一场。
Miui 7 getNetworkInfo 有可能不正确,明明联网,state确是 DISCONNECTED/BLOCKED 。解决办法,使用别的参数来确定网络是否可用,如 isAvailable,可能跟神隐模式有关。
吹了几个专利 idea 。
2015.09.14
对称加密算法在加密和解密时使用的是同一个秘钥;而非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。
监听屏幕点亮
2015.09.16
RSA的公钥非常长,但能加密的数据又比较少,可以分段加密。
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
所以上行包不带这玩意。
2015.09.17
比如你想用使用某个函数,但不知道这个函数该在怎样的上下文种使用,可以用codota搜这个函数的用法。
2015.09.18
今天彻底换了chrome,有点舍不得firefox。
2015.09.21
ProGuard能够通过移除不需要的代码,重命名类,域与方法等等对代码进行压缩,优化与混淆。使用ProGuard可以使得你的代码更加紧凑,这样能够减少mapping代码所需要的内存空间
2015.09.21
接入MiPush唤醒app。 Done;
blog comments powered by Disqus