SDK Introduction - housekeeper-software/soft GitHub Wiki

android SDK

andoird SDK的基本构成

java和native的关系

android SDK如同android Framework的实现,业务逻辑全部由Java端驱动。在每个Java类中有一个: private long mNativeJavaObj; 这个变量在native层操作,保存native层对象的指针。当Java对象销毁的时候,这个值会被native层清空。 如同framework,Java层销毁一个对象,比如顺序经过: stop,release。 重载java对象的finalize方法,它的实现与release一致。如果已经显式的调用release,则finalize中什么都不做。 stop方法必须在UI线程调用,否则对象销毁会出现问题。原因是java GC的时候可能不在UI线程,导致native层销毁异常。 在java层,stop和release可以顺序调用。在IOS上未必(详细可参考IOS SDK说明)

native如何通知java

native工作在子线程,java层对native层的调用会转发到子线程;但是native层回调java方法是在子线程中发生的,因为,java层收到回调,必须转发到UI线程。 java初始化native对象的时候,要创建一个指向自身的弱指针传递给native。当native层回调发生时,将这个弱指针传给java,java要判断这个弱指针指向的对象是否有效,如果无效则忽视。 native层全部调用java对象的静态方法实现回调,即使对象已经销毁,回调依然可以进行。通过回调中提供的弱指针来判断是否需要处理。

java操作native传回的对象

有时候,native会传递一个对象到java层,比如Bitmap。此刻,java层的处理不能转发到UI线程,必须在native的工作线程中同步处理,当离开callback的时候,必须释放对native传回来对象的引用关闭。 如果native传会来一个Bundle,此刻java层可以强引用之,native层传给java之后就已经解除了与Bundle的引用关系。Bundle只是为了将native层的回调数据打包给java层。

IOS SDK构成

IOS SDK接口、逻辑、方法基本等同于Android。但是,IOS在操作音频、摄像头、视频方面和java不同。如果涉及到这个地方,比如门禁通话、媒体格式转换、访客记录回放,都会涉及到上述的媒体资源。 native层在初始化和终止媒体资源的时候,需要用到UI线程。所以,这些对象的释放需要分步骤处理: 1)先在UI层调用stop,stop是异步操作,只是通知native可以终止了。然后立即返回到UI。 2)native在销毁对象的时候,可能会转到UI线程1-2次,销毁结束之后会通过callback通知OC 3)此刻OC可以release这个对象 如果将protocol绑定到View中,可能会影响View正常的销毁逻辑,此刻,可以将protocol在另外一个无关的类中实现,并再次将native的callback转发到当前工作的View中,这样不会影响到View的正常销毁。

移动端的潜在问题

正在通话中,app切换到后台一段时间,然后再切换到前台,此刻声音和画面可能会出现异常,需要一点时间画面才能恢复正常,但声音的延迟不能被抵消掉,这个延迟会一直存在。 原因是,app切换到后台之后,系统降低了app的线程优先级,导致媒体数据的积压,此刻可能表现为声卡不断被饿死,画面更新缓慢。切换到前台之后,底层累积的音频数据太多,造成了时延,但画面可以快速显示完成,又恢复正常。

一体机的潜在问题

一体机安装有代理和终端两个app,代理一直在后台,要确保其优先级不被系统降低,否则数据转发就会出现巨大的时延,导致前台的声音视频卡顿。

其他问题

用户切换网络之后,native的连接并不会马上断开,而此刻与底座的通讯已经物理上断开,但TCP依然会保持一段时间。此刻会出现终端找不到代理的情况,可以stopproxy,再startproxy来加快发现过程。