[置顶] android 日记
Q: 去掉copen的filename|123 col 80|
A: vim ~/.vimrc
"hide filename,and col of quickfix
fun! Copen()
copen
set conceallevel=2 concealcursor=nc
syntax match qfFileName /.\{-\}|.\{-\}|\s/ transparent conceal
endfun
nnoremap <silent> <F11> :call Copen() <CR>
Q: logcat 二次过滤。有时我们需要把全部打印存下来做离线分析,这时需要做再次过滤。
A: 使用vim。logcat -v time -s tag1:
[14:02:40 375]D/tag1( 3404): set status
vim regex 完整描述:
^\[\d\d:\d\d:\d\d\s\d\d\d\][DIE]\/tag1(\s\w\+):\s\+\(.*\)
[DIE]\/tag1\|tag2
说明:
加括号是为了便于引用,比如有一个3列的表,
1,3列交换:
:%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
.*是greedy的,non-greedy,比如查找单引号包含的:
'.\{-\}'
删除当前行末空白:
s:\s\+$::
删除logcat -v time部分:
%s:^\[\d\d\:\d\d\:\d\d\s\d\d\d\]::g
:range s:pattern:string:cgi
range 可以是行范围123,456或者%所以行。
c -- 表示需要确认, g -- 全部而不是第一次, i -- 不区分大小写。
Q: 正常情况下打印出堆栈:
A: Log.d(TAG,Log.getStackTraceString(new Throwable()));
Q: logcat 参数:
A:
system/core/logcat
logcat -g #get log size
-f /data/logfile
-r 1024 -n 8 #save 8 rotated files of 1 MB each.
-s System.out #set this tag silent
-d #dump
-c N #last N lines
Q: Binder例子
A: 纯java --http://download.csdn.net/detail/deyangliu/8606749
java端通过JNI调用, native端实现ashmem -- https://github.com/vecio/AndroidIPC
Q.以MediaPlayerService为例, Android 进程间通信的分层结构。
A: app-framework-driver,先简单这样理解:
# app:客户端获取BpBinder之后,就可以RPC了。
sp<IBinder> binder =
defaultServiceManager()->getService(String16("media.player"));
sp<MediaPlayerService> ms = interface_cast<IMediaPlayerServer>(binder);
ms.setDataSource("test.mp4");
ms.start();
# app:服务端注册服务,然后建立线程池,监听处理请求,发送回复
sp<ProcessState> proc(ProcessState::self());
defaultServiceManager()->addService(String16("media.player"), new
MediaPlayerService);
IPCThreadState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
# framework: 只需服务端实现者关注
BpBinder::transact(CMD, data, &reply) -->
IPCThreadState::
self()->transact()
* executeCommand
S:BBinder::transact --> BnMediaPlayService::onTransact;
* writeTransactionData/waitForResponse
* talkWidthDriver --> ioctl
# driver: 读写进程的共享内存
/dev/binder
Q. 如果我想做一个库,给第三方用, C语言的话,给*.a和*.h头文件就行了。但是java没有所谓的“头文件”概念,那第三方如何知道我实现的public method signature呢?
A: 参考[1], jar -tffor_third_lib.jar 列出有哪些class, 然后,
javap -classpath for_third_lib.jarcom.abc.hello
第三方调用代码开头加上 import com.abc.hello; 当然IDE里面是自动的,不用你敲命令。
Q. generate empty *.so. 目的是防止配置不对。
A.LOCAL_SRC_FILES:= 置为空即可。这样readelf -a 只有crtbegin_so(__cxa_finalize...)。
Q. 如何强制重新编某个模块?
A. mmm -B path/to/dir --print-directory showcommands
Q: sdl2 好像只用到jni接口,怎样理解JNI和binder?
A: java 和c交互场景:
System.loadLibrary("xx_jni.so"); --> dvmLoadNativeCode -->JNI_OnLoad();
public native XXX(String text);
JNI_OnLoad(JavaVM* vm, void* reserved){
Q:如果动态库里面没有这个函数定义会如何?
A:参考dalvik/vm/Native.c,没有定义也行,
这也解释了SDL_android_main.c没有定义也是OK的。
}
Java_org_XXX(JNIEnv* env, jclass cls, jstring text){
const char *utf = (*env)->GetStringUTFChars(env, text, NULL);
}
Android_JNI_ShowMessageBox(char *msg){
JNIEnv *env = Android_JNI_GetEnv();//里面的注释说明android java thread就是kernel thread, 受内核调度。
jstring message = (*env)->NewStringUTF(env, msg);
(*env)->CallIntMethod(env, ..., message);
}
所谓JNI就是跨越语言边界时的本地接口"(*env)->xx"。它只是规定本进程内不同语言的通信方式。
跨进程通信就是binder提供的。
Q: [gburca] 的可读性非常好,给的两个链接写的非常好。不过有个问题:
server loop 是在哪里体现的?
A:
defaultServiceManager()->addService(String16("Demo"), new Demo());
android::ProcessState::self()->startThreadPool(); //就是这里体现的。
如果看过线程池实现代码就会知道:就是在一个while循环里面调talkWithDriver()阻塞,
如果有消息数据来,IPCThreadState::executeCommand()-->
binder_transaction_data tr;
mIn.read(&tr, sizeof(tr));
Parcel buffer;
sp<BBinder> b((BBinder*)tr.cookie);
b->transact(tr.code, buffer, &reply, 0);
class BnInterface : public INTERFACE, public BBinder
BBinder 则是当 IPCThreadState 实例收到 BD 消息时,通过 BBinder 的 transact 的方法将其传递给它的子类 BnSERVICE 的 onTransact 函数执行 server 端的操作。
client不能通过ActivityManager.getRunningServices()取得,
只能通过
sp<IBinder> binder = sm->getService(String16("Demo"));
sp<IDemo> demo = interface_cast<IDemo>(binder);
Q: java客户端通过binder设置listenner,服务端如何处理?
A:
Bp-->Bn 是客户端到服务端的单向信道。
反之也可以新建BpServer-->BnClient。
Q: how to understand virtual function is resolved at runtime?
A: 假设Cat, Dog 都继承Animal,三者都实现了eat(),定义全局函数
void func(Animal *xyz) { xyz->eat(); }
不加virtual关键字, func(cat)只会调Animal的。
我们希望func(cat)时调cat->eat(); func(dog)时调dog->eat();
virtual关键字使得func()在Runtime时能跟据输入参数选择不同的调用。
java 默认就是virtual的行为,例子见[geeks-final]
Q: how to implement virtual function calling ?
A: 上面的"选择“并不是要一个循环去遍历,而是用空间换时间,
每个对象都有一个vptr, 在construct时指向vtable, 图例见[geeks-polymorphism]
从语法上看是动态的,从语义-内存地址上看是静态的。
Q: C也可以做到,那为什么要这样折腾?
A: 从概念层没有差异,只有一个优点:减少代码。其他例子:
实现某个Data Structure;
使用“确定性析构”处理错误返回;
Q: 多个线程引用同一对象,如果确保对象正确销毁?
A: 如果线程A把对象销毁了,对象B引用就是一个空悬指针
增加一层抽象:
shared_ptr<T> 引用计数降为零时立即销毁对象。
weak_ptr<T> 不增加对象的引用计数。
为了避免循环引用:
资源的owner持有指向child的shared_ptr, child持有指向owner的week_ptr
还顺带解决了 double free, memeory leak。
Q: how to add callbacks in androd binder interface?
A:
Q: 开机画面?
A: [laoluo-logo] 有三个地方:
kernel --> init : kernel/goldfish/drivers/video/logo/
--> Zygote : system/core/init/logo.c "/initlogo.rle"
--> SystemServer --> SurfaceFlinger, PacketMS : frameworks/base/cmds/bootanimation
--> Launcher
Q: binder 效率?
A:
一般的IPC机制是先把数据从源进程的用户空间拷贝到内核空间,然后再从内核空间拷贝到目标进程的用户空间,有两次数据拷贝,而Binder只有第一次[laoluo-binder]:
binder对象只是在其他进程对应的binder driver数据结构中建立一个handle。
共享内存最快只需要零次拷贝。传统IPC访问接入点是开放的,无法建立私有通道[universus-ds]。
Android为每个安装好的应用程序分配了自己的UID。
Q. ubuntu 14.04 xiaomi 2s adb devices不识别
A. 参考[mad79]:
sudo gvim /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="0x2717", MODE="0666", GROUP="plugdev"
sudo chmod a+r /etc/udev/rules.d/51-android.rules
gvim ~/.android/adb_usb.ini
0x2717
sudo service udev restart
adb kill-server
adb devices
这里idVendor=0x2717是通过"lsusb -v"可查到的。
Q. root后adb shell默认不是root用户时,如何将文件放入手机系统中[android-test]
A. adb push tcpdump /sdcard/
su
mount -o remount,rw /
ls -l /data/local
cat /sdcard/tcpdump > /data/local/tcpdump
chmod 700 /data/local/tcpdump
/data/local/tcpdump -p -s 0 -w /sdcard/1.pcap
shell命令cp和rm在这里都是不支持的,都会报错,所以直接用cat来拷贝就可以了。
Q: 小米2s 通讯录 存 手机卡
(以为是2g手机卡通讯录丢失)
A: 通讯录界面-菜单键-导入/导出-从sim卡导入。
[android-test] http://www.douban.com/note/264414832/
[mad79] http://www.mad79.de/archives/853
[universus-ds] http://blog.csdn.net/universus/article/details/6211589
[laoluo-logo] http://blog.csdn.net/luoshengyang/article/details/7691321
[laoluo-binder] http://blog.csdn.net/luoshengyang/article/details/6629298
[geeks-final] http://www.geeksforgeeks.org/g-fact-43/
[geeks-polymorphism] http://www.geeksforgeeks.org/virtual-functions-and-runtime-polymorphism-in-c-set-1-introduction/
[1]http://stackoverflow.com/questions/976388/how-to-get-method-signatures-from-a-jar-file
[gburca] https://github.com/gburca/BinderDemo
更多相关文章
- 学习笔记 Android 使用AIDL实现进程间通信
- android实现Parcelable序列化对象
- Android Intent传递对象和集合
- Android利用Looper在子线程中改变UI
- android 中,关于线程安全退出的问题(from stack overflow)
- 多线程实现android更新进度条
- android intent 传递对象需要序列化实现Parcelable接口
- 在android中获取系统后台运行的进程