http://192.168.12.228:359/c/android/vendor/+/7272
json
上面好好看看
遗留问题
E:\code\lite\asu\apps\AsuTvSettings\src\com\asu\settings\keystone\raysees\RayseesKeystone.java 这个文件好好看看,lite上的
调用瑞时接口获取tof数据,用的是进程间的AIDL通讯。
gx code
scanningMultPts模式下persist.sys.tof.loop 采集多少次数据
persist.sys.tof.setroi.num 设置zone的数量
persist.sys.tof.offset.compensate 是否做tof补偿
lite当前的逻辑是在MiKeyServer里取平均后返回tof的值。
persist.sys.keystone.type // 1:asu
persist.sys.asualg.debug 是否打印MiKeyServer里的log
查看当前APK版本号:
$ dumpsys package com.asu.kstcal | grep versionName
$ adb shell
$ ps -ef | grep asu
$ ps -T -p 3531(APP PID) // 查看进程里的所有线程
$ ps -T -p 3531 // 实时刷新进程里的线程情况
Android APP开发总结
adb shell am startservice 时每次启动的是一个实例,
adb shell am stopservice时并不会自动销毁服务里自己创建的实例,当前进程和线程依旧存在,需要自己释放。
连续运行下面代码,会提示java.net.BindException: bind failed: EADDRINUSE (Address already in use)
serverSocket = new ServerSocket(9000); LogUtil.d(TAG, "Wait for Client Socket Connect..."); socket = serverSocket.accept(); // 这里开始阻塞,如果有人连上,则开始发送信息
现在的逻辑是serverSocket只要被连接一次,就自动close。
一共三个线程:监听线程serverSocket,接收线程和发送线程。
accept阻塞时,interrupt没有起作用????
这里分两种情况:
1.监听连接成功后,再重新创建线程时,接收线程是否被重复创建。同一台机器多次标定会出现。
因为上位机标定完成后,会close socket,所以标定结束后,Android端不会再有线程存在,因此每次标定,都需要重新创建线程。
2.监听没有连接成功过,这个时候再次创建线程时,新线程会因为端口被占用创建失败,原监听线程一致存在。
MiKeyServer在哪里注册的???
And
Android Log - ALOGV
这篇文章讲的比较详细
Android AIDL
BpInterface和BpBinder中的p表示的意思就是proxy,表示中间的调用和代理,不会具体实现功能,BnInterface和BnBinder中的n表示的意思就是native 是最终实现的地方。
这里需要注意:
通过AIDL也可以访问kernel层的节点,例如: MiKeyServer(); 这是典型的创建本地可执行服务,
APP层通过AIDL Binder与MiKeyServer通讯
Binder通讯-AIDL有多种方式:
1. APP与Native层的AIDL通讯
APP层与Native层的通讯方式
服务端
BnMiKeyServer::onTransact
客户端:
class BpMiKeyServer : public BpInterface<IMiKeyServer>
MiKeyServer的实现与下面文章类似。
Android系统进程间通讯之Binder机制(二)_implement_meta_interface-CSDN博客
system/sepolicy/private/file_contexts 定义了mikeyserver
2. APP层的AIDL通讯
Android binder通信实现进程间通信_android apk之间的通信-CSDN博客
上面文章对AIDL讲的特别详细,进程内部和进程间,是否使用AIDL等情况都进行了分析。
client端都要调用bindService
Android Binder机制浅谈以及使用Binder进行跨进程通信的俩种方式(AIDL以及直接利用Binder的transact方法实现)_安卓 binder-CSDN博客
Android HIDL
Android HAL层添加HIDL实例实现串口通信_android 新增hidl接口-CSDN博客
Android TCP
https://blog.51cto.com/u_16099296/6662022
使用USB数据线连接PC端和Android端进行数据的交互_android设备通过usb线连接c#进行socket通信-CSDN博客
Android端通过usb和pc端互传json数据_jsonrpc通过usb连接手机-CSDN博客
标定APP开发调试记录-权限问题
PC与Android交互命令
显示标定图片
adb shell am start-foreground-service -n com.asu.kstcal/com.asu.kstcal.KstCalService -a com.asu.kstcal.KstCalService --ei type 7 --ei flag 2
启动Tcp标定服务
启动接收网络接收线程
adb shell am start-foreground-service -n com.asu.kstcal/com.asu.kstcal.KstCalService -a "com.asu.kstcal.KstCalService" --ei type 2 --ei flag 8
AndroidStudio对APP做系统签名
Android11版本不获取系统权限只能保存文件到APP自己目录,不能保存到其他目录,例如data或sdcard目录
Android Studio进行系统签名:
1.拷贝T950D4.keystore到APP目录,跟build.gradle在相同目录
2.必须要在build.gradle里进行APP签名
signingConfigs {
android_app {
storeFile file("T950D4.keystore")
storePassword "roward"
keyAlias 'AMLT950'
keyPassword "roward"
}
}
3.修改AndroidMenifest.xml
android:sharedUserId="android.uid.system"
权限问题
在服务里显示图片是比较困难的可以用下面方法,调试过程中遇到了权限问题。
APP必须做系统签名,否则无法通过addView这种方式显示图片。
多线程+消息机制+线程间通讯
上面文章找时间验证下
Android : thread的结束,挂起和恢复_安卓 new thread运行结束-CSDN博客
Android : thread的结束,挂起和恢复_安卓 new thread运行结束-CSDN博客
多线程开发:
全面详解Android实现多线程的几种方式(史上最全,最详细)_贺兰猪的博客-CSDN博客_android 多线程
消息机制+线程间通讯:HandlerThread
zhuanlan.zhihu.com/p/424513321
Android多线程之HandlerThread详解_Big Skipper的博客-CSDN博客_android new handlerthread
HandlerThread继承自Thread,内部实现了初始化了Looper,并创建了消息队列,接着调用了Looper.loop()开启了消息循环,这样HandlerThread就可以处理通过Handler传递过来的Message了,因为HandlerThread中的run方法是无限循环,当有消息过来时处理消息,没有消息时就会阻塞。当明确不需要HandlerThread时,可以调用quit或者quitSafely (API 18以上使用)来尝试终止线程。
Hanlder Looper Queue HandlerThread
Andriod提供了 Handler 和 Looper 来满足线程间的通信。 Handler 先进先出原则。 Looper 类用来管理特定线程内对象之间的消息交换 (MessageExchange) 。
1)Looper: 一个线程可以产生一个 Looper 对象,由它来管理此线程里的 MessageQueue( 消息队列 ) 和对消息进行循环。
2)Handler: 你可以构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 MessageQueue 里 ; 或者接收 Looper 从 Message Queue 取出 所送来的消息。
3) Message Queue( 消息队列 ): 用来存放线程放入的消息。
4) Message:是线程间通讯的消息载体。
Android的消息机制主要指的是Hanlder的运行机制、Handler所附带的MessageQueue和Looper的工作过程,三者是一个整体的,只不过我们开发过程中接触比较多的是Hanlder而已
Hanlder创建的时候会采用当前线程的Looper来构造消息循环系统,那么Hanlder内部获取当前线程的Looper,就要使用到ThreadLocal了。ThreadLocal可以在不同线程中互不干扰的的存储并提供数据,通过ThreadLocal可以轻松的获取到每个线程的Looper。
当然需要注意的是,线程是默认没有Looper的,如果需要使用Hanlder就必须为该线程创建Looper。我们经常用的主线程,也叫UI线程,其实是ActivityThread,在创建时候就被初始化Looper了,这也是主线程总默认可以使用Handler的原因
其实Looper的作用就是把handler发送的消息放到Queue中,并把消息广播给所有与这个Queue相关的handler,而Queue一般是主线程开启的时候就给这个线程分配了一个,所以你要与UI 主线程通信必须用于这个Queue相关联的handler对象才行,一般handler对象在哪个线程中创建的就与哪个线程的queue关联,所以在UI 线程中创建的handler对象就与UI线程通讯,这样我们就可以在子线程中发送消息给主线程,实现更新UI的功能。
如果我们创建一个Handler对象而没有给它指定它的Looper,那么它默认会使用当前线程的Looper。
HandlerThread的特点
HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper。 HandlerThread能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。这样Handler.sengMessage 就被切换到HandlerThread中执行
HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。
HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
遗留问题:
createCaptureSession/setRepeatingRequest/openCamera/setOnImageAvailableListener时都传了一个handler,同时这个handler关联了thread。这个地方记着看下
extends Handler时的内存泄漏问题
handleMessage用到了多态的概念
整理了一个例程,后期分享。
参考文档
【Android】Handler和Handler Thread心得_Tech Ranger的博客-CSDN博客_android handler handlerthread