
Android
文章平均质量分 69
aaajj
求职中,欢迎联系
展开
-
【Android】setText调用导致的悬浮窗抖动问题
在Android13中,有这么一个bug,写一个可以拖到的悬浮窗,这个悬浮窗里有TextView,在拖到某个位置后,再调用TextView的setText方法,会发现出现了一个窗口动画,悬浮窗跳到了起始位置,从开始的位置又滑动到当前位置,看起来就是出现了一个跳动。在开发者选项里,关闭掉 窗口动画缩放,就没有这个跳动问题了,所以这应该是窗口动画的bug,在调用setText的过程中,view的测量,布局中触发了窗口动画,并且使用了最初的坐标,大致是这样的思路。原创 2025-03-09 19:10:22 · 283 阅读 · 2 评论 -
【Android】悬浮窗的使用例子
这里我们来看看悬浮窗的使用,主要是windowManager.addView方法来添加。在某游戏中,一般都是一队4个人,但是在有的主播直播里,显示栏看上去是5个人,比如。如果没有权限,则引导用户到设置页面手动开启。有2种方式,一个是在投屏的软件画面里拉一个小窗口进去,(PC端操作)另外一个是在手机上显示一个悬浮窗,达到以假乱真的效果,在 Android 6.0 及以上版本中,需要通过。在 Android 中实现悬浮窗功能,可以通过。是一个危险权限,需要动态申请。,定义悬浮窗的 UI。原创 2025-02-27 14:31:11 · 721 阅读 · 0 评论 -
【Android】问deepseek存储访问
这些天deepseek爆火,我们来问问android问题看看,如果问android中的应用怎么访问外部存储,回答的很清楚,但是如果问的深入一些,比如Android中是怎么控制让应用不能读取其他应用的外部存储文件的,回答的比较抽象,只是给出了大概的分析方向。同时,用户可能对具体的技术细节感兴趣,比如UID/GID如何分配,文件描述符的传递机制,以及Binder在跨进程通信中的作用。另外,用户可能想知道这些机制在不同Android版本中的差异,比如Android 10之后的作用域存储如何强化了这些限制。原创 2025-01-28 13:25:27 · 2811 阅读 · 1 评论 -
[Android]service命令的使用
在前面的讨论中,我们说到,如果在客户端懒得使用aidl文件生成的接口类进行binder,可以使用IBinder的transcat方法还有一个更方便的binder调用测试方式,使用service命令。原创 2025-01-12 20:50:48 · 989 阅读 · 0 评论 -
【Android】直接使用binder的transact来代替aidl接口
首先,你需要定义一个接口,并提供相应的服务端实现。这个过程可以通过 AIDL 来完成,但为了演示如何直接使用。原创 2025-01-09 21:36:48 · 635 阅读 · 0 评论 -
[Android]init中添加新的command
在Android的init进程中,command是用于定义启动时要执行的具体命令行指令的关键部分。init进程是Android系统启动的第一个进程,它负责初始化系统的各个组件,并启动必要的服务。command可以在init.rc文件及其包含的其他.rc文件中找到,通常作为on操作块或service定义的一部分。原创 2024-12-28 20:04:38 · 831 阅读 · 0 评论 -
【阅读笔记】Android AMS forcestop停止应用
注意看这个解释信息,如果不需要取消应用的scheduled alarms和jobs,可以使用stop-app。通过am命令force-stop 也可以调用forcestop,查看help信息,很多年前,曾经遇到一个卸载应用导致的重启问题,就是因为卸载的时候,没有及时的执行。ac.removePackage(packageName)导致的。在AMS中,停止指定的应用是一个常用的功能,在代码里可以看到。里面调用到forceStopPackageLocked方法,根据这篇文章作的笔记。原创 2024-12-15 20:09:33 · 459 阅读 · 0 评论 -
【阅读笔记】Android广播的处理流程
会调用到BroadcastQueue.java 的processNextBroadcast,有些广播接收不到,就是在这里面进行了屏蔽。广播的原理很清晰,类似一种观察者模式,控制中心把广播发送给注册者(观察者),但是android中的实现细节较多。关于Android的解析,有很多优质内容,看了后记录一下阅读笔记,也是一种有意义的事情,这里通过一个am命令发送受保护的广播,查看抛出的异常,看相关堆栈。,如果静态注册的应用未启动,还需要等待应用启动后再进行处理。今天就看看“那个写代码的”这位大佬关于广播的梳理,原创 2024-12-01 13:17:53 · 815 阅读 · 0 评论 -
【Android】静态广播接收不到问题分析思路
在Android中,静态广播如果静态广播不能接收,我们可以从整个流程中去分析,是否注册成功了,或者是在发送过程中出现了问题,参考资料中的流程可以去看几遍。这一种也比较直观,查看BroadcastQueue.java可以找到对应的代码,如果没有直观的BroadcastQueue 的log,还是要看看广播发送流程,代码细节很多,还是要仔细查看,还是那句话,"只在此山中,云深不知处"在dump信息中,可以通过查看receiver的信息,如果出现类似下面的log。这里一般不会出现问题,原创 2024-11-25 07:39:02 · 661 阅读 · 0 评论 -
[Android]查找java类中声明为native方法的具体实现方法
nativeWriteInt是Java层Parcel.java中声明的函数名称,而android_os_Parcel_writeInt是JNI层android_os_Parcel.cpp中对应的函数。android_os_Parcel_writeInt方法中又调用了C++层的Parcel类,进而通过JNI实现了Java层对C++层方法的调用。在android代码中,经常可以看到native方法,需要查看其对应的C++方法,这些方法是一一对应的,对应关系是在jni注册里关联起来的。原创 2024-11-10 21:20:17 · 696 阅读 · 0 评论 -
[Android]从FLAG_SECURE禁止截屏看surface
在应用中,设置activity的flag为FLAG_SECURE就可以禁止截屏,截屏出来是黑色的,试验一下,原创 2024-11-03 13:34:33 · 892 阅读 · 0 评论 -
【Android】perfetto使用学习
在开发者选项中的系统跟踪里抓取的perfetto文件是保存在/data/local/traces 里的。如果写一个while线程,一直使用cpu,是怎样的呢,这里我们来试验一下,加深学习。可以看到,这个线程是绿色的,状态是running,一直在运行。主线程中的执行是受vsync信号控制的,即间隔调用的。可以看到,这个进程号,线程号和log中的是一致的。点击Thread后面的箭头,会跳转到线程那里。在一个按钮中开启一个线程。原创 2024-10-27 20:38:20 · 475 阅读 · 0 评论 -
【Android】GraphicBuffer和ANativeWindowBuffer
看上去dequeueBuffer调用把数据保存到了ANativeWindowBuffer中,再通过GraphicBuffer的getSelf处理进行了转换,GraphicBuffer 和 ANativeWindowBuffer是什么关系呢,稍微看一下定义,就可以发现,可以把他们理解为一个东西,GraphicBuffer是surface的内存数据载体,但是,在Surface::lock方法获取内存信息时,在其父类ANativeObjectBase中,可以看到。原创 2024-10-09 20:43:46 · 571 阅读 · 0 评论 -
【Android】多角度看handler--looper的阻塞
作为对比,我们再看看广播中的唤醒,我们知道,在注册的广播接收器收到消息时,即广播的receiver调用的时候,是执行在主线程的,这显然是handler调用唤起的,比如亮屏这样的系统广播,我们猜测是AMS通过广播的相关处理,通过唤醒应用中的binder线程,调用相关方法,里面再调用主线程关联的handler来唤醒主线程looper阻塞,可以看出,looper的阻塞唤醒可以由其他线程的handler消息(本质还是消息队列里的某个fd)和监听的fd上有消息(如input)文件:LoadedApk.java。原创 2024-09-28 16:51:42 · 1038 阅读 · 0 评论 -
自制实战吃鸡手柄原理
2,物理方案,打开游戏的陀螺仪功能,把手机(平板)安装到电机设备上,收到旋转指令时,就对设备进行旋转,由于设备会发生旋转,可以使用投屏到电视或者采集卡显示到电脑的方式来看游戏画面。1, 软件方案,在Android上启动一个服务,接收手柄的指令,把指令转换为MotionEvent事件,这里可以参考input命令的代码。再发散一下,为了游戏时有健身效果,可以添加相应的传感器来获取蹲,跳等动作,来控制游戏中的相应行为,来达到健身和身临其境的效果。枪形手柄使用蓝牙来进行连接,发送操作指令。有2种方案来进行控制,原创 2024-09-01 10:00:35 · 510 阅读 · 0 评论 -
【Arduino】自制声控点击器(吼叫吃鸡助手)
当时的思路是开一个服务,监听麦克风音量,然后注入input命令,但是,在Android中,由于touch的处理方式比较复杂,区分各输入类型,adb input命令的注入会和手指的touch冲突,发生断触,需要从系统级来处理这个融合,在input系列文章中我们进行了讨论,这里不再细说。这里我们考虑物理点击的方式,市面上有一些自动点击设备,体验后发现,使用的时候需要按开始按钮,实时性不强,这个开始按键,如果改成我们需要的声控处理,就恰到好处了。在接地的导线上,加一个开关控制,就可以实现触摸和停止触摸的效果,原创 2024-08-18 19:57:34 · 731 阅读 · 0 评论 -
【Android】系统级应用升级后的安装位置
系统级应用的安装位置一般在codePath=/system 下面,如果手动的去进行adb install覆盖安装,通过dumpsys package可以发现是安装在/data/app/里,如果是通过标准的系统升级方式呢?这里我们来通过升级查看一下,升级前升级后说明和手动安装的情况不一样。是会覆盖安装到/system/priv-app里的在Android中,系统级应用通常是预装在设备上的,并且通常位于目录中。原创 2024-08-05 09:41:24 · 1306 阅读 · 0 评论 -
【Android】MediaCodec学习
在开源Android屏幕投屏代码scrcpy中,使用了MediaCodec去获取和display关联的surface的内容,再通过写fd的方式(socket等)传给PC端,这里我们做另外一个尝试,读取手机中的mp4文件,显示到app的surface上,来学习MediaCodec的使用。playVideo的处理需要在另外一个线程中执行,不能在主线程执行,不然只能显示停止的一个画面。如果返回的索引大于等于0,则说明有可用的输出缓冲区。注意,这里的mp4文件放在了sdcard中,需要获取读取权限。原创 2024-01-28 20:23:26 · 1342 阅读 · 0 评论 -
【Android】app中阻塞的looper为什么可以响应touch事件
这里直接给出答案,input事件传送给了系统IMS,IMS通过inputchannel把input传送给应用,而应用中的主线程looper监控了inputchannel的fd,这里,我们考虑一个问题,Android中的应用是一个looper线程,没有任务时就阻塞着,其他线程通过handler调用等方式向主线程looper发送任务,这里,打不过就加入,把inputchannel的fd也加入到主线程looper的epool监控之中。如果点击应用上的按钮,应用是怎么及时响应的呢,这个构造方法,调用其父类的构造。原创 2024-01-21 16:06:55 · 1208 阅读 · 0 评论 -
从权限跳转看Activity的data android:scheme
请注意,根据不同的Android版本和设备制造商,界面的外观和可用选项可能会有所不同。确保你的应用程序具有适当的权限,以请求用户打开通知助手设置界面。在应用申请悬浮窗权限的时候,可以跳转到相应的设置界面,并且自动切换到应用的条目,高亮显示一下,上述代码将打开通知访问权限设置界面,其中用户可以配置通知助手相关的权限。而申请通知访问权限时,在跳转的页面中没有高亮显示应用的条目,为什么呢,上述代码会打开一个系统设置界面,允许用户授予悬浮窗权限。android悬浮窗权限怎么申请。原创 2023-11-22 21:30:56 · 968 阅读 · 0 评论 -
【Android】关于touch设备TOOL_TYPE_STYLUS
在 Android 中,触控笔(Stylus)是一种特殊的输入设备,它可以提供更精确和细致的输入方式。Android 提供了相应的触控笔事件处理机制,以支持触控笔的使用。触控笔事件与触摸事件略有不同,因为触控笔通常提供了更多的信息,如压力、倾斜角度等。方法,可以接收触控笔事件。你可以根据事件的类型和属性来处理触控笔事件。类表示,它提供了许多有用的方法来获取触控笔事件的信息。这里通过log来查看触控笔的motionEvent,方法可以检测事件的工具类型,通过。方法可以获取触控笔的倾斜角度等。原创 2023-10-14 12:35:08 · 801 阅读 · 0 评论 -
Service onUnbind学习
Service 的onUnbind在所有的连接断开后才执行,就是这么设计的,所有连接断开后才通知service,为destory作准备。注意关键词: all clients have disconnected。那么onBinde是只调用一次么,这也是个问题,可以试验一下看看,多个客户端连接的时候,只调用一次,可能也是进行了类似的缓存操作,另外,service没有提供查看连接数量的方法。查看Service onUnbind的定义。原创 2023-07-31 21:38:03 · 348 阅读 · 0 评论 -
问问GPT:android中怎么使用tensorflow
绘制关键点的具体实现可能因应用程序而异,具体的实现方式取决于应用程序的需求。但是,使用 Canvas API 在屏幕上绘制关键点的基本思路是相同的:创建一个 Paint 对象,设置绘制属性,然后使用 drawCircle() 或者其他绘图方法在屏幕上绘制关键点。总之,在 Android 中使用 TensorFlow,你需要将 TensorFlow Lite 库添加到你的项目中,将训练好的 TensorFlow 模型转换为 TensorFlow Lite 模型,然后使用 Java API 加载和运行模型。原创 2023-06-25 07:48:24 · 1109 阅读 · 0 评论 -
游戏中用脚开飞机实现方案
看看这个图片,有人用脚开飞机,用几个踏板去控制,在游戏中,开飞机的操作比较简单,上升,下降,加减油门,方向左,方向右。android设备中,使用模拟点击就可以实现这个功能,在操作踏板的时候发送对应的touch事件,具体可以参考。原创 2023-06-19 21:18:33 · 172 阅读 · 0 评论 -
【Android】CountDownTimer的使用
最后,我们使用CountDownTimer实现了倒计时功能,并在onTick方法中更新了倒计时文本的内容。这样,就实现了根据给定的包名显示应用图标和倒计时的功能。在onTick方法中,可以更新UI上的倒计时时间,而在onFinish方法中,可以执行倒计时结束后的操作。在上述示例中,我们使用了一个单例对象来表示倒计时器,这样我们就可以在任何地方启动倒计时,而不用担心多次创建倒计时器的问题。在onTick方法中,我们更新了UI上的倒计时剩余时间,而在onFinish方法中,我们更新了UI上的提示信息。原创 2023-05-30 21:31:25 · 2530 阅读 · 0 评论 -
从创建AlertDialog发生crash的WindowManager$BadTokenException看Window和Surface
就这个调用,可以作为一个入口来理解绘图机制,WindowManager在这个过程中创建了Surface,WindowManager作为窗口的管理者出现在这里,其他的绘图处理就交给ViewRootImpl和SurfaceFlinger合成了,详细可参考。这个问题,只有设置了TYPE_APPLICATION_OVERLAY 就可以了,因为ViewRootImpl.setView里会判断type的值,对于不符合条件的,就抛出了异常。在service中,进行AlertDialog调用,如。这里重点关注这个堆栈。原创 2023-03-04 20:42:44 · 192 阅读 · 0 评论 -
Bundle的Parcel化处理
在Android中,使用Intent通过binder在不同进程间传送数据是很方便和通用的,Intent保持数据主要是通过Bundle来存储较多的数据。调用writeParcelableCreator,把类名信息保存起来,所以在恢复对象的时候,可以知道是什么类,Bundle中通过map来存储键值对,所以上面的例子中,使用key值来进行查找,就可以获取到value对象。Bundle的Parcel化读写比较复杂,细节较多,这里看一下大致过程,序列化的过程就是这样,再看看反序列化的关键点,调用到Bundle里。原创 2023-01-21 13:01:54 · 1968 阅读 · 0 评论 -
[Android Input系统]MotionEvent的序列化传送
PC端的客户端支持按键和鼠标滑动操作,手机上的云游戏客户端则是和手机游戏一样的touch触控,客户端的touch操作是怎样处理给服务端的呢,猜测是把touch操作“实时”的传送给了服务器,Android服务器上把这些数据转换为相应的MotionEvent事件。这里再进一步考虑一下,在Input事件分发的时候,InputDispatcher把input事件通过InputChannel发送给对应的应用进程的时候,是怎样传送input事件数据的呢,这里从云游戏的触控操作看起,原创 2023-01-15 17:26:38 · 909 阅读 · 1 评论 -
Android13 wifi无线调试adb连接设置
在进行adb调试的时候,有时候需要使用wifi连接,或者wifi连接较为方便,早些的Android上,需要设置端口等操作,手机和电脑连接同一个wifi后,在手机的开发者选项中,可以看到无线调试选项。在Android13上,无线adb连接更加方便了,可以看到,已经设置了默认的端口,不需要我们设置了,输入命令,连接这个IP和端口。可以在通知栏上关闭连接。原创 2023-01-14 13:17:26 · 4118 阅读 · 0 评论 -
Handler同步屏障学习
通常我们使用Handler的时候,post一个消息(命令)到消息队列,然后通过内部的looper处理机制从队列上依次去执行。这个时候,问题来了,如果有的任务优先级比较高,比如UI的绘制,想要优先执行,该怎么办呢?Handler机制中提供了这个功能,MessageQueue#postSyncBarrier()字面上看,对同步操作设置一个障碍,学习资料Handler同步屏障_xiaopangcame的博客-优快云博客_同步屏障具体代码分析可以查看上面的链接资料,通过postSyncBarrier向消息队列插入原创 2022-12-04 20:10:21 · 399 阅读 · 0 评论 -
android strace使用
这个命令打印出进程的子进程的strace,所以对于应用,传人zygote进程id即可,因为应用是从zygote fork出来的,但是由于现在android上有zygote和zygote64,需要查看下应用进程的父进程是zygote还是zygote64,如果要获取应用打开时的相关strace,可以使用 strace -f -p 命令,再打开chrome,获取其PID,从打印的数据中根据PID进行筛选就可以得到chrome的相关数据。再看看zygote的进程号,原创 2022-11-13 20:05:09 · 1399 阅读 · 0 评论 -
【input学习】App对input事件的反馈与waitqueue
App端通过Looper来监听InputChannel的fd,获取数据后,调用相应的处理方法,最后会再调用InputEventReceiver的finishInputEvent方法,向InputDispatcher进行反馈,表示当前的事件处理完成,InputDispatcher收到反馈后,删除掉waitQueue(wq)中对应的记录。这里我们来看看finishDispatchCycleLocked是怎么处理到waitQueue的,这里进行了waitQueue的dequeue处理,弹出了处理过的事件记录,原创 2022-11-06 19:49:00 · 923 阅读 · 0 评论 -
从MessageQueue的removeMessages来认识anr原理
ANR检查调用超时,显然,需要有相应的检查,没有检查就没有所谓的超时,比如你上班早退了,会有人找你,你旷工,会有人找你,因为这些有监管,而如果你上班超时,到点还不走,却没有人找你,因为对这个没有监管。前面接触了handler,MessageQueue,Looper,这里趁热打铁,通过ANR的原理继续来熟悉handler相关处理。2.扫雷,任务及时完成后,调用removeMessages清理掉指定的message(根据message编码和对象来区分),1. 埋雷,发送延时消息。原创 2022-10-31 21:27:00 · 734 阅读 · 0 评论 -
MessageQueue和Looper学习
而Looper中使用epoll_wait来进行阻塞,在队列头部放入数据后,进行wake操作,通知Looper可以检查了,于是epoll_wait退出阻塞,判断队列头部数据的时间是否原创 2022-10-29 19:38:58 · 1009 阅读 · 0 评论 -
sendMessageDelayed学习
这里考虑这样一个场景,比如有3个任务,需要间隔20ms来执行,(比如我们来构造3个连续的点击事件),这个时候就需要考虑怎样发起延迟调用,直接使用sleep也可以实现,但是看上去似乎不是那么优雅,会导致当前线程的sleep。在使用handlre消息队列执行任务时,常规的调用是调用post立即执行,任务按照时间顺序来执行,主要是调用了底层的epoll_wait来实现的,epoll_wait方法有时间参数。Handler中已经实现了这样的功能来方便调用,为什么可以根据传人的时间去调起任务呢,原创 2022-10-22 20:59:07 · 885 阅读 · 0 评论 -
[input分发]从MotionEvent的相对坐标来看view中touch的分发
我们可以再对多窗口进行试验,在onTouchEvent中可以发现,touch的坐标MotionEvent的getX,getY打印出来是坐标是相对于窗口的坐标,而不是屏幕原点的坐标。在前面的讨论中,我们了解到,在InputDispatcher里进行分发处理的时候,如果有2个窗口,会进行splitMotionEvent操作,对MotionEvent进行分割加工,只传递窗口自身的事件给对应的窗口。// 判断触摸点是否产生变化,例如有新的触摸点按下或旧触摸点抬起。// 触摸点ID集合无变化,则不需要进行事件拆分。原创 2022-10-16 13:39:14 · 346 阅读 · 0 评论 -
【input系统】MotionEvent的分解
在打开多窗口的时候,比如A,B两个应用窗口,我们通过onTouchEvent查看log可以发现,在A窗口上的点击事件不会传给B窗口,当有多个点击事件时,A,B接收到的事件是不一样的,也就是说,在InputDispatcher的notifyMotion中的一个MotionEvent,在传送给app的时候,会根据窗口进行拆分。可以看出,touch事件(MotionEvent)的传送多么的不容易,那么多的操作,多次加工,千辛万苦才传给了接收者。在应用中也有类似的拆分处理,原创 2022-09-29 21:03:25 · 640 阅读 · 0 评论 -
[Android]从app的trace打桩原理回顾zygote的fork
其实在应用app诞生的时候,就已经具备了这个功能,设置了回调函数atrace_update_tags,因为这个设置是在zygote里就进行好的,zygote 进程fork出app进程后,app进程已经天然的具备这个功能。应用中看上去并不需要设置属性变化的回调函数,为什么接收到来自AMS的属性变化binder通知后,自动的就可以执行回调函数,获取到相应的属性值变化呢?通过这样的方式,只要引用了这个库,在main函数开始,就会执行traeInit方法,来设置属性变化的回调函数。里,已经引用了trace。原创 2022-09-18 21:49:02 · 1234 阅读 · 0 评论 -
【systrace学习】atrace打开各系统层tag开关的原理
细节很多,这里回顾一下大体过程,atrace里设置tag,标识哪些tag可以进行写trace,然后写到属性值debug.atrace.tags.enableflags里,atrace又进行了binder调用所有系统服务的SYSPROPS_TRANSACTION对应的方法,告诉它们,属性值变化了,可以调用属性变化回调函数了。查看atrace_update_tags的定义,在里面读取属性"debug.atrace.tags.enableflags"的值,更新了atrace_enabled_tags的值,原创 2022-09-10 16:22:02 · 3548 阅读 · 0 评论 -
[Android Input系统学习]从mouse事件再看input分发
但是,我们较为熟悉的事件接收方法View#onTouchEvent里并没有调进去,在onTouchEvent里添加log,在点击的时候会有输出,但是滑动时没有输出,mouse设备的滑动难道不一样?较为直观的分析方法是打开InputDispatcher里的log开关,可以看到,滑动的时候,还是会走到notifyMotion方法,我们还可以抓取systrace来查看方法调用流程。可以看出,mouse设备的事件分发流程和屏幕touch事件的流程是一样的,只是处理细节不一样。原创 2022-09-10 12:02:48 · 1082 阅读 · 0 评论