对android M中Call的概要总结(目录结构/界面组成/call状态转化上报/常见log分析)

IMS基本知识 IMS基本知识简介ImsServiceImsManagerIMS 启动IMS建立失败可能的原因 简介 IMS在CS通话的基础上增加了telephony/ims、net/ims、vendor/ims和IMS相关的Media模块。 telephony/ims:主要包括了对外接口ImsPhone,通话管理中心ImsPhoneCallTracker,某一路通话ImsPhoneCall,某一路通话连接ImsPhoneConnection。需要实现的提供IMS相关服务的ImsService。 net/ims:主要包 阅读详情

主要内容
1. Call涉及的目录结构及框架结构
2. InCallUI层的基本架构(所涉及的Presenter、Fragment及Activity)
3. Call的几种状态(对应phone状态)及上报流程
4. GSM与IMS MO流程的差异
5. 分析问题的常用log

希望你在看完本篇以后能够:
1.快速找到Call界面某个小时内容对应的fragment及presenter
2.结合log快速定位当前call的状态
PS:内容均为博主个人经验总结,如有出错的地方欢迎指正。

1. Call涉及的目录结构及框架结构

1.1 目录结构

packages/ apps/Dialer/
packages/apps/InCallUI

packages/services/Telecomm
packages/ services/Telephony

framework/base/telecomm
framework/opt/telephony
(vendor/…/ ims Ims Call)

Dialer    
    拨打电话的入口,来电不会经过Dialer。但是拨打电话的出口不光是Dialer,在联系人和短信里也有拨打电话的出口。代码运行在dialer进程。
InCallUI
    负责显示通话界面的信息,来电信息。dialer进程。
Telecomm
    处理Intent,发送广播,设置call的状态,audio状态。system_process和telecomm:ui进程。
Telephony
    向下层传递拨号,注册了很多广播,申请很多权限(service data sms wap network)。 phone进程
telecomm 
    提供placeCall的接口(自android M开始),创建outgoingCall的connection,通知上层成功建立connection
telephony
    拨号 也就是dial命令的下发,但是如果是Ims网络就会有下面一步
Vendor/ims
创建ImsConnection,ImsCall,拨号。phone进程。

1.2 框架结构

这只是框架上的一个大致结构


在实际的流程中并不一定是自上而下或者 自下而上的,也有可能跳过某个模块直接 传递信息。
比如在Dialer拨号的时候,就是直接调用 framework/base/telecmm中 TelecomManager的placeCall接口拨打 电话。

2. InCallUI层的基本架构(所涉及的Presenter、Fragment及Activity)

2.1InCallUI内有多个对应的Presenter和Fragment

Presenter和Fragment的关系: Fragment直接控制界面上的控件,并处理一些简单的逻辑,对应的Presenter处理稍复杂的逻辑。
CallCardFragment
CallCarfPresenter
    CallButtonFragment
    CallButtonPresenter
CallCard和CallButton是绑定在一起显示的,有CallCard就一定会有CallButton
CallCard显示拨打的电话的信息,包括联系人姓名,号码,通话时长,通话类型等(稍后有展示),CallButton包括可以对当前通话进行的操作,如通话保持,通话静音,通话录音等。

VideoCallFragment
VideoCallPresenter
主要是视频内容,在进入退出视频模式时同时处理camera、audio相关信息。

AnswerFragment
AnswerPresenter
显示新来电,或者视频升级请求,重点在于对不同类型的通话显示不同的选项(也可根据运营商进行不同配置)。

DialpadFragment
DialpadPresenter
拨号盘,添加通话的时候显示。一般没什么问题,之前有该显不显的问题,同时dialpad的显示会影响endCallButton的大小,两者是同步变化的。
 
ConferenceManagerFragment
ConferenceMangerPresenter
没遇到过这里的问题,只是准备PPT的时候才看到这个。


InCallActivity启动的时候,在显示完动画后,调用showCallCardFragment()显示CallCardFragment(CallCardFragment本身也有动画)然后Fragment内new Presenter。
其他几个也有各自的显示流程,不一定是在InCallActivity的动画显示后立刻show出来。
另: VideoCallFragment不是通过 showFragment()显示的。

2.2 通话界面布局分析 

注:界面被轻量定制,并非和原生完全一样。


图1 CallCardFragment和CallButtonFragment
图中除了priamry_card_info.xml和call_button_fragment.xml是布局文件,其他标注均为控件id。
AnswerFragment和DialpadFragment共用一个FramLayout
@+id/answer_and_dialpad_container
在显示的时候覆盖在CallCard的上层,比如CallCard中的photo(联系人头像)就是被dialpad给覆盖。

图2 VideoCallFragment ( 真人出境啦 )
左侧为普通视频电话,右侧为视频会议电话。
注意,虽然右侧看起来像是有4个小窗口显示内容,但实际上和左边一样只有两个控件显示视频,只不过右侧上方的视频内容被分成了3块。我们把黑色的背景色调成蓝色,就容易区分出是两个控件了。
至于为什么两张图incomingVideo的位置不一样,CallCard一个显示一个没显示,是因为,点击屏幕(或者等5s)后CallCard会隐藏,然后incomingVideo会自动调整位置到中央。

 
图3 AnswerFragment
 更多的界面就不一一详细说明了。
如果你看到了不常见的控件,那它在代码中的位置,和临近位置的控件的代码位置也是临近的(有点拗口= =)。
 

2.3 InCallPresenter和InCallActivity

这个为什么要单独列成一条呢?因为这个Presenter比前面几个Presenter都重要,它连结这界面的各个部分。
InCallPresenter
从CallList中获取更新然后通知到InCallActivity,由InCallActivity控制界面显示。
同时各个Fragment和Presenter可以获得InCallPresenter的实例,进而更新/获得数据。 单独的Presenter负责对应的界面的逻辑,InCallPresenter负责整个界面的显示,协调各个Fragment/Presenter之间的工作。
以视频电话全屏为例,在VideoCallPresenter中有隐藏CallCard进入全屏模式的需求,在VideoCallPresenter中会通过InCallPresenter调用CallCardPresenter的onFullscreenModeChanged()方法,进而调用CallCardFragment的方法隐藏CallCard
InCallActivity
InCallActivity是InCallUI的主体,可以说所有的类都是围绕着或者是为了这个Activity工作的, 各个Fragment附着在InCallActivity上,InCallPresenter通过InCallActivity提供的 get***Fragmment的方法,获得具体Fragment对象, 更新界面。
Fragment是通过InCallActivity创建和显示的,但是各个Presenter和InCallPresenter之间的交互 不一定全都经过InCallActivity(比如可以通过listener调用)
 
图4 InCallUI基本架构
我们举两个例子 来说明界面上更新走过的流程:
1.设置CallStateLabel上的文本,比如"requesting video",代码的执行经过InCallPresenter> CallCardPresenter> CallCardFragment,跳过了InCallActivity;
2.弹出dialog,比如“网络不可用” ,代码执行经过IncallPresenter > InCallActivity
还有另外一个比较重要的没有体现在图上的类叫做 TelecomAdapter。
它的职责主要是把界面上操作的命令向下层传递,具体点就是把对call的操作传给Telecomm,包括接听,挂断,拒接,静音,切换audioRoute等。

3. Call的几种状态(对应phone状态)及上报流程

3.1 Call的状态

下面这张图不用记,知道有这么多就行了。
不同模块的call的状态不一样,有些能对应上,有些是独有的对应不上的。
比较重要的是InCallUI里的 Call.State和InCallPresenter的内部类 InCallState
InCallPresenter控制着界面显示,这里的InCallState就是界面显示的依据。
TelephonyManager向外提供访问手机状态的接口 ,只有三种状态。


图5 Call的状态

下图表现的是InCallUI Call状态的转化以及对应的TelephonyManager.CALL_STATE_***状态

图6 InCallUI 中的Call状态转化
其中CONNECTING/SELECT_PHONE_ACCOUNT这两个是 二者取其一。如果是双卡手机并设置每次询问,则拨号后的状态为SELECT_PHONE_ACCOUNT,如果有是单卡或者默认某一张卡拨打,则状态为CONNECTING,并且这个状态很短暂,很快就转换为DIALING。
 

3.2 上报流程

都是以 UNSOL_RESPONSE_CALL_STATE_CHANGED消息上报为开始,
//CS

   
  1. 09-09 10:52:42.093 D/RILJ    ( 4017): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED [SUB1]//PS 07-18 15:31:58.120 
//PS

   
  1. D/ImsSenderRxr( 4499): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED  [id=1,DIALING,toa=129,norm,mo,0,voc,noevp,,cli=1,,3Call Details = 3 2 callSubState 0 videoPauseState2 mediaId0 Local Ability  Peer Ability  Cause code 0,CallFailCause Code= 501,CallFailCause String= null, ECT mask: 0] [SUB0]
流程中多次用到RegistrantList消息处理机制,比较关键的一个地方是TelephonyConnection里,在外拨(或者来电)设置连接的时候注册了一个消息
getPhone().registerForPreciseCallStateChanged(mHandler, MSG_PRECISE_CALL_STATE_CHANGED, null);当收到这个消息的时候会调用updateState()更新状态。
updateState
在Telephony更新call的状态的时候不同的状态对应不同的方法,如setActiveInternal()
 
图7 ims call state update(简图)
上图也印证了之前说的,虽然层次上packages叠在framework上面,但实际上他们并不是严格按照相邻的顺序去调用。有可能隔着一层就调用了,也可能反复调用。
下图以IMS电话接通状态上报为例
(图略)
 图7 ims call state update(详图)

4. GSM与IMS MO流程的差异

  • 最大的区别是 IMS通话最后是通过高通私有代码ims.app中拨出去的。
  • IMS MO也要经过GSMPhone,判断到IMS网络可用以后会调用到ImsPhone中的dial()方法。
  • ImsSenderRxr.java相当于CS call中的RIL.java,DIAL的命令也是在此发送
      07-18 15:35:04.977 D/ImsSenderRxr( 4499): [0247]> DIAL[SUB0]
  • ImsPhone中的log是在radio log中打印,但是ImsSenderRxr的log是在main log打印。
  • 在ImsPhone的后续步骤中,会创建ImsPhoneConnection和ImsCall。
 
对比图
(图略)
图8 GSM MO和IMS MO 对比(注:34画错了,不该指向ImsPhone,请读者忽略)
箭头指向为对应步骤,可以很明显的看到Ims的MO流程在这部分更复杂一些。针对IMS网络下的通话,专门建立了ImsPhoneConnection ImsCall。

5. 分析问题的常用log

5.1InCallUI
前面说过InCallUI的界面显示是以InCallState的状态为根据的,而查看InCallState的关键字是 Phone switching state:

   
  1. 14:42:29.721 I/InCall  (24960): InCallPresenter - Phone switching state: NO_CALLS -> NO_CALLS
  2. 14:42:29.864 I/InCall  (24960): InCallPresenter - Phone switching state: OUTGOING -> OUTGOING
  3. 14:42:30.262 I/InCall  (24960): InCallPresenter - Phone switching state: OUTGOING -> PENDING_OUTGOING
  4. 14:42:31.194 I/InCall  (24960): InCallPresenter - Phone switching state: PENDING_OUTGOING -> OUTGOING
  5. 14:42:34.975 I/InCall  (24960): InCallPresenter - Phone switching state: OUTGOING -> INCALL
  6. 14:42:35.630 I/InCall  (24960): InCallPresenter - Phone switching state: INCALL -> INCALL
InCallUI会根据这个状态显示界面信息。
这个状态一般是跟CallList里的call同步,但也有例外,就是会 撤回状态,关键字 Undo the state change
Log.i(this, "Undo the state change: " + newState + " -> " + mInCallState);
14:42:35.998 I/InCall  (24960): InCallPresenter – Undo the state change: INCOMING ->NO_CALLS
这时候就出现了界面显示和实际情况不一样,上面的log就对应来电没有界面。
注意 :INCALL包括DISCONNECTING和DISCONNECTED,虽然这两个是短暂的状态,但是看到的最后几个INCALL状态可能call已经断开了。

CallList中的onUpdate(),这是常见的看InCallUI中call的数量和状态的地方,关键字 CallList - onUpdate  

   
  1. 17:13:21.514 I/InCall  ( 4166): CallList - onUpdate - [Call_0, CONNECTING, [Capabilities:
  2. 17:13:21.568 I/InCall  ( 4166): CallList - onUpdate - [Call_0, DIALING, [Capabilities: CAP
  3. 17:13:29.997 I/InCall  ( 4166): CallList - onUpdate - [Call_0, ACTIVE, [Capabilities: CAPA
  4. 17:13:30.255 I/InCall  ( 4166): CallList - onUpdate - [Call_0, ACTIVE, [Capabilities: CAPA
  5. 17:13:39.896 I/InCall  ( 4166): CallList - onUpdate - [Call_1, CONNECTING, [Capabilities:]
  6. 17:13:43.179 I/InCall  ( 4166): CallList - onUpdate - [Call_1, CONNECTING, [Capabilities:
  7. 17:13:43.266 I/InCall  ( 4166): CallList - onUpdate - [Call_1, DIALING, [Capabilities: CA
  8. 17:13:43.451 I/InCall  ( 4166): CallList - onUpdate - [Call_1, DIALING, [Capabilities: CA
  9. 17:13:43.471 I/InCall  ( 4166): CallList - onUpdate - [Call_0, ONHOLD, [Capabilities: CAP
  10. 17:13:43.492 I/InCall  ( 4166): CallList - onUpdate - [Call_0, ONHOLD, [Capabilities: CAP
5.2 Telecom
另外自android 6.0开始,Telecomm加了一个关键字为 Event 的log,会打印在Telecom内执行的关键步骤的log。打印出来如下

   
  1. 17:22:05.385 I/Telecom (  769): Event: Call 8: CREATED, null
  2. 17:22:05.394 I/Telecom (  769): Event: Call 8: SET_CONNECTING, ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService},
  3. 17:22:05.449 I/Telecom (  769): Event: Call 8: AUDIO_ROUTE, EARPIECE
  4. 17:22:09.161 I/Telecom (  769): Event: Call 8: BIND_CS, ComponentInfo{com.android.phone…
  5. 17:22:09.240 I/Telecom (  769): Event: Call 8: CS_BOUND, ComponentInfo{com.android.phone…
  6. 17:22:09.241 I/Telecom (  769): Event: Call 8: START_CONNECTION, tel:*****
  7. 17:22:09.399 I/Telecom (  769): Event: Call 8: SET_DIALING, successful outgoing call
  8. 17:22:17.395 I/Telecom (  769): Event: Call 8: SET_ACTIVE, active set explicitly
  9. 17:23:03.636 I/Telecom (  769): Event: Call 8: REQUEST_DISCONNECT, null
  10. 17:23:04.211 I/Telecom (  769): Event: Call 8: SET_DISCONNECTED, disconnected set explicitly> DisconnectCause [ Code: (LOCAL) Label: () Description: () Reason: (LOCAL) Tone: (27) ]
  11. 17:23:05.612 I/Telecom (  769): Event: Call 8: DESTROYED, null
DisconnectCause  是常用的查看通话断开原因的log。  
注意:Telecom的log是在system_process进程打印,用adb命令抓log的时候要加上-b system
5.3 MT 来电
在main log中我常看

   
  1. 00:01:21.154 D/Telephony( 1389): PstnIncomingCallNotifier: handleNewRingingConnection
如果这条看不到还可以查CallsManager中的setCallState,可以从状态转化中看到来电状态。

   
  1. 14:42:34.888 I/Telecom ( 2920): CallsManager: setCallState DIALING -> ACTIVE, call: [100747014, DIALING,
5.4 MO DIAL
IMS(PS)

   
  1. 18:30:35.325 D/ImsSenderRxr( 3325): [0056]> DIAL[SUB0]
  2. 18:30:35.365 D/ImsSenderRxr( 3325): [0056]< DIAL [SUB0
有DIAL回传才表示拨号成功
GSM(CS)

   
  1. 17:29:56.206 D/RILJ    ( 4017): [6301]> DIAL [SUB1]
  2. 17:29:56.250 D/RILJ    ( 4017): [6301]< DIAL  [SUB1]
5.5 HANGUP

  
  1. 15:32:37.899 D/ImsSenderRxr( 4499): [0240]> HANGUP[SUB0]
  2. 15:32:37.995 D/ImsSenderRxr( 4499): [0240]< HANGUP [SUB0]
5.6 IMS
在IMS网络下通话的很多log是在main log中打印的,其中几个比较关键的类包括ImsSenderRxr、ImsServiceSub,以这两个类名为关键字在log中搜索就好了,或者以关键字/ImsSe把这两个一起搜出来


  
  1. 18:30:37.522 D/ImsSenderRxr( 3325): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED  [id=1,DIALING,toa=129,norm,mo,0,voc,noevp,,cli=1,,3Call Details = 3 2 callSubState 0 videoPauseState2 mediaId5 Local Ability  Peer Ability  Cause code 0,CallFailCause Code= 0,CallFailCause String= null, ECT mask: 0] [SUB0]
  2. 18:30:37.522 D/ImsServiceSub( 3325): Message received: what = 1
  3. 18:30:37.522 D/ImsServiceSub( 3325): >handleCalls
  4. 18:30:37.523 D/ImsServiceSub( 3325): handleCalls: dc = id=1,DIALING,toa=129,norm,mo,0,voc,noevp,,cli=1,,3Call Details = 3 2 callSubState 0 videoPauseState2 mediaId5 Local Ability  Peer Ability  Cause code 0,CallFailCause Code= 0,CallFailCause String= null, ECT mask: 0

希望阅读完对您有所帮助,也欢迎给出意见和建议。
 
//CS

   
  1. 10:52:42.093 D/RILJ    ( 4017): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED [SUB1]
//PS

   
  1. 15:31:58.120 D/ImsSenderRxr( 4499): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED  [id=1,DIALING,toa=129,norm,mo,0,voc,noevp,,cli=1,,3Call Details = 3 2 callSubState 0 videoPauseState2 mediaId0 Local Ability  Peer Ability  Cause code 0,CallFailCause Code= 501,CallFailCause String= null, ECT mask: 0] [SUB0]
C/C++安卓手游内存逆向与Call实战:从零构建自动化脚本框架 本文详细介绍了C/C++在安卓手游内存逆向与Call调用中的实战应用,从基础概念到自动化脚本框架的构建。内容涵盖内存逆向、Call调用、Hook技术等核心技能,并提供环境搭建、工具准备、内存读写、函数调用分析等实用教程,帮助开发者掌握手游逆向工程的全套技术体系。 阅读详情

相关推荐

Agent Runtime 重构:Session-as-Event-Log 与无状态 Harness 实践

AI Agent 运行时(runtime)正经历类似操作系统虚拟化的范式迁移——核心不再是‘能否执行’,而是‘如何可靠、可审计、可恢复地执行’。其底层原理在于将状态管理从模型上下文(context)中解耦,转为持久化、因果可追溯的事件日志(Event-Log),并由无状态执行器(Harness)驱动沙箱按需调度。这一设计显著提升长流程任务的容错性与合规性,支撑金融、医疗等高监管场景下的可信自动化。技术价值体现在失败可重放、凭证零留存、跨工具异构兼容;典型应用场景包括多系统协同的智能工单处理、临床数据核查、退

319

RIL 机制---消息RILJ中的处理

9,RILJ 接收子线程要完成的就是对接收数据的处理操作。还分为两步去分析: 1、如何接收的消息; 2、消息的处理流程。 9.1数据接收过程  接收子线程RILReceiver的run方法主要代码如下, class RILReceiver implements Runnable { byte[] buffer; RILReceiver() {

Jack的博客 3715

安卓逆向与固件分析实战:从黑盒到白盒的系统化指南

在嵌入式系统与移动安全领域,固件分析是理解设备底层工作原理的核心技术。其基本原理是通过提取、解析和修改设备固件,将厂商封装的“黑盒”系统转化为可被深入分析的“白盒”。这项技术的核心价值在于,它不仅是安全研究员进行漏洞挖掘和渗透测试的必备技能,也是嵌入式开发者进行定制开发、功能扩展和性能优化的基础。在实际应用场景中,固件分析广泛应用于智能设备安全评估、物联网设备研究、安卓系统定制以及硬件功能逆向等方向。本文聚焦于使用Kalitools工具集进行安卓逆向与固件分析,详细介绍了从固件提取、镜像解包到二进制逆向的完

weixin_33672400的博客 373

Dialer中界面组成、Call对象和log分析

主要内容 1. Call涉及的目录结构及框架结构 2. InCallUI层的基本架构(所涉及的Presenter、Fragment及Activity) 3. Call的几种状态(对应phone状态)及上报流程 4. GSM与IMS MO流程的差异 5. 分析问题的常用log 希望你在看完本篇以后能够: 1.快速找到Call界面某个小时内容对应的fragment及presenter 2.结合log快速定位当前call的状态 1. Call涉及的目录结构及框架结构 1.1 目录.

mike_jungle的博客 2267

面向AI编程智能体的自主无头Android调试器Debroid解析

在Android开发与调试领域,传统IDE调试方式高度依赖图形界面和人工判断,而AI编程智能体却常运行在无显示器的服务器或CI环境中,这种割裂让AI Agent难以自主完成移动应用的调试闭环。无头(headless)调试器的出现,将原本需要人眼观察、手动点击的能力转换为结构化API与数据输出,从而为自动化测试和智能编程工具提供了新的可能性。Debroid正是这样一款定位为“面向AI编程智能体的自主Android调试器”的工具,它通过设备管理、日志采集、崩溃堆栈分析、UI层级感知等核心能力,让AI Agent

weixin_33834628的博客 1222

Android 14 AOSP编译实战:Ubuntu环境搭建、源码下载与系统构建全流程

操作系统构建是现代软件开发中的核心环节,它涉及将源代码转化为可运行系统的完整流程。其原理基于构建系统(如AOSP的Soong/Ninja)对依赖关系的解析与并行编译,技术价值在于提供了从底层理解系统运作、深度定制和性能优化的能力。这一技术广泛应用于系统开发、ROM定制和嵌入式设备等领域。本文聚焦于Android 14系统构建,详细解析在Ubuntu环境下完成AOSP源码下载、环境配置、编译构建到运行调试的全链路实践,其中涉及**源码同步**的网络优化策略与**增量编译**的效率提升技巧,为开发者提供从零到一

clijovtbq401783153的博客 434

通话类型转换流程之AudioCall到VideoCall

这里的通话类型指的是语音通话和视频通话,转换包括upgrade/ downgrade升降级,就是语音通话升级为视频通话、视频通话降级为语音通话。升级为视频通话一般就是包括如下图示的4步,MO发起请求,MT接收请求,MT响应请求,MO接收响应。在实际开发中,无论是需求还是解bug,重点需要关注的是Dialer App中和framework中的流程,Vendor中的高通私有类的流程了解即可,一般不会修改到,对关键log信息要熟悉,便于对此类问题的分析。代码主要包含如下几个路径,时序图最上面也有标识出。

嘿v小米的博客 2334

Hermes+Bridge安卓无障碍自动化:不Root不ADB的稳定操控方案

AccessibilityService是Android 10+系统中唯一无需Root、无需ADB调试、跨App稳定的官方UI交互接口,其设计初衷为辅助功能,却成为工业级安卓自动化的合规基石。基于事件驱动机制,它通过AccessibilityEvent捕获通知、点击等用户行为,规避了ADB轮询失效、截图识别不准等痛点。Hermes框架深度聚焦该API的稳定性与低资源占用,配合Bridge进程间通信模块和Termux沙盒环境,构建出轻量、可控、可审计的自动化执行链。该方案广泛适用于RPA流程集成、IoT设备远

cuhongjiao7003的博客 320

Ims开机注册流程

Ims开机注册流程

嘿v小米的博客 4568

MiniMax M2.5 本地部署实战:替代 Claude 的高确定性代码助手

大语言模型在开发者工作流中的落地,核心不在通用能力,而在协议兼容性、本地可控性与领域适配性。OpenAI 兼容接口已成为国产模型工程化接入的事实标准,而 MiniMax M2.5 通过原生支持 v1/chat/completions 协议、一键 CLI 部署工具 `mimo` 及深度强化的代码理解能力(如 git diff 解析、TypeScript AST 推理),显著降低了 AI 编程基础设施的运维成本与使用门槛。其本地化运行模式规避了网络抖动、API 限频与跨境延迟等不确定性,使代码生成、重构与测试等

anwenzhao0749的博客 400

Gemma4本地部署实战:Mac与Android一键运行大模型

大语言模型(LLM)本地化部署正从开发者专属走向大众普及,其核心在于降低硬件门槛与操作复杂度。Gemma4作为Google推出的边缘优化模型,通过E2B/E4B等轻量架构设计,原生适配CPU、Apple Silicon及Android NPU,显著提升终端推理效率;Ollama作为统一运行时引擎,封装了CUDA、MLX、Vulkan等后端差异,实现‘一条命令启动’的极简体验。技术价值体现在无需编译、免配环境、自动量化与跨平台一致性,广泛应用于个人知识管理、编程辅助、教育辅导及多模态内容生成等场景。本文聚焦G

weixin_34335458的博客 429

安卓学习笔记-unity调用原生opencv的sdk

保存本地图片的方法我是在网上扒的,网上在安卓10以后都可以访问到DCIM文件夹了,他们也大多都是使用的这个方法,但unity是不支持访问这些路径的,所以我还是改成了保存到报名下的私有路径中,这样unity就可以直接通过Application.persistdatapath这个api去访问文件了。,然后打包运行,会出现一个显示相机画面的界面,检测到人脸就会自动在人脸的部分绘制一个框框,这和unity的插件效果是一致的,然后打包到安卓主板(3588和3568)上进行测试,也是可以正常检测到的。

pure81的博客 2079

基于GitHub Actions与智能分析的自动化测试流水线构建指南

持续集成与持续交付(CI/CD)是现代软件工程的核心实践,旨在通过自动化构建、测试和部署流程,实现快速、可靠的软件交付。其核心原理在于将代码变更自动集成到共享主干,并通过一系列自动化验证确保质量。GitHub Actions作为主流的CI/CD平台,提供了开箱即用的工作流编排能力,极大地降低了自动化门槛。在自动化测试领域,传统的测试执行往往只产出简单的通过/失败结果,缺乏对失败根因和性能变化的深度洞察,这成为了提升研发效率的瓶颈。为此,将智能分析能力嵌入CI/CD流水线,对测试日志、性能指标进行多维度聚合与

weixin_34006468的博客 496

安卓启动性能优化:使用bootchart工具进行系统启动时间分析与调优

系统启动时间是衡量操作系统性能的关键指标之一,尤其在嵌入式设备和移动平台中直接影响用户体验。其优化基础在于对启动过程的精确测量与分析,通过监控内核初始化、进程调度和资源分配等底层机制,定位性能瓶颈。在Linux/Android生态中,proc文件系统提供了实时获取进程状态和系统统计信息的接口,这为启动分析工具的实现奠定了原理基础。bootchart正是基于此机制,通过定期采集/proc下的进程列表、CPU占用和磁盘I/O等数据,将系统启动过程可视化,帮助开发者理解服务启动顺序和资源竞争情况。该工具的技术价值

weixin_33858336的博客 354

轻量级端侧声纹验证系统:从模型到Android落地全链路

声纹验证是一种基于生物特征的身份认证技术,其核心是将语音映射为固定维度的声纹嵌入向量,并通过相似度比对完成身份判别。该技术依赖于语音信号的时频表征能力与深度学习模型的判别性建模能力,具备离线可用、隐私友好、低延迟等工程优势。在移动端落地时,需综合权衡模型轻量化、预处理鲁棒性、推理框架兼容性及系统级资源约束。Log-Mel Spectrogram因其符合人耳听觉特性且抗口音干扰能力强,成为主流前端特征;CNN-LSTM混合结构则兼顾局部纹理提取与时序建模需求,在骁龙660等中端芯片上实现68ms端侧推理。Te

weixin_30443731的博客 395

Android5.0来电界面InCallUI源码

Android5.0来电界面InCallUI源码

Android内存泄漏排查实战:从OOM崩溃到MAT深度分析

内存泄漏是Java和Android开发中常见且棘手的问题,它会导致应用内存占用持续增长,最终引发OutOfMemoryError崩溃。其原理在于,由于错误的引用关系,本该被垃圾回收器回收的对象却无法被释放,从而长期占用堆内存。解决内存泄漏对于提升应用稳定性和用户体验至关重要,尤其在图片加载、页面导航等高频场景中。通过分析堆转储文件,可以精准定位泄漏对象及其引用链。Memory Analyzer Tool(MAT)作为一款强大的独立堆分析工具,能够深入解析hprof文件,帮助开发者识别由静态字段、匿名内部类或

weixin_33924312的博客 417

用Python和sklearn预测NBA比赛胜负:从数据清洗到模型优化的完整流程

本文详细介绍了如何使用Python和sklearn构建NBA比赛胜负预测模型,涵盖从数据清洗、特征工程到模型优化与部署的完整流程。通过对比随机森林、XGBoost等主流算法,提供实战技巧和解决方案,帮助数据爱好者掌握体育数据分析的核心技术。

weixin_30823001的博客 131

关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

经常会有朋友问我这个问题:“能不能一个App只提供一套切图适应所有的分辨率呢?”我觉得有必要写一篇文章来研究一下这个问题,所以就有了这篇文章。本篇内容主要探讨以下场景:同一张图片,放置在不同的drawable文件夹,在同一设备上运行,对图片大小及内存占用有什么影响。 测试环境 采用锤子T1手机(1080*1960,xxhdpi)进行测试 对于内存的查看,使用AS自带的内存

IT界寿险规划师的博客 816

图机器学习(9)——图正则化算法

网络信息能够有效约束模型行为,确保相邻节点的输出保持平滑过渡——这种特性在半监督场景中尤其重要,可实现未标注节点的信息传播。更进一步,这种机制也可用于正则化学习过程,从而提升模型在未见样本上的泛化能力。在本节中,我们探讨了在学习阶段应用正则化技术的方法,用于显著提升模型的鲁棒性,使其具备更优异的泛化能力。

盼小辉丶的博客 8918

三步实现Java分布式追踪:像“开灯”一样简单

摘要: 本文通过三步实现Java分布式追踪: 引入依赖:配置Spring Cloud Sleuth+Zipkin,自动埋点无需代码侵入; 启动服务:REST接口自动生成Trace/Span ID,日志可验证; 可视化分析:通过Zipkin UI查看调用链耗时和拓扑关系。 亮点:AOP自动埋点、零业务代码修改、支持多服务链路追踪,助力快速定位性能瓶颈。适用于微服务诊断,生产环境可调整采样率平衡性能。(150字)

墨夶的博客 2710
上一篇: IMS Modify Call (3) accept reject timeout 接受/拒接/超时 视频升级请求
下一篇: 使用dumpsys查看android系统服务信息
十橙
博客等级 码龄24年 312粉丝 95原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值