android笔记

来源:互联网 发布:mac删除快捷键 编辑:程序博客网 时间:2024/06/07 16:23

1. 很多类中有dump方法,可以方便调试

2. aidl进行进程间通信时,如果参数时Ibinder,则服务端接收到的就是该对象,如果是继承了stub的对象,则为其代理,以IWindowManager.aidl为例

public void disableKeyguard(android.os.IBinder token, java.lang.String tag) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder(token);case TRANSACTION_disableKeyguard:{data.enforceInterface(DESCRIPTOR);android.os.IBinder _arg0;_arg0 = data.readStrongBinder();<pre name="code" class="java">public void exitKeyguardSecurely(android.view.IOnKeyguardExitResult callback) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeStrongBinder((((callback!=null))?(callback.asBinder()):(null)));mRemote.transact(Stub.TRANSACTION_exitKeyguardSecurely, _data, _reply, 0);case TRANSACTION_exitKeyguardSecurely:{data.enforceInterface(DESCRIPTOR);android.view.IOnKeyguardExitResult _arg0;_arg0 = android.view.IOnKeyguardExitResult.Stub.asInterface(data.readStrongBinder());注意前者实际传参是binder类对象,后者是继承了 android.view.IOnKeyguardExitResult.stub的对象

3.注意util类,例如textutils类

4.

查看native内存泄露的方法:

1)    修改eclipse的配置文件,~/android/ddms.config,

2)    增加一行 native=true

3)    打开eclipse, 调整到DDMs状态

4)    通过USB连接终端,保证adb接口可用。

5)    有界面选项卡,刷新查看top N的几个native进程的内存增长

方法2:

通过设置libc.debug.malloc属性,取值如下:

1 - perform leak detection

5 - fill allocated memory to detect overruns

10 - fill memory and add sentinels to detect overruns

20 - use special instrumented malloc/free routines for the emulator

一般操作步骤:

>adb shell

#setprop  libc.debug.malloc 1

# stop

#start  //重启上层业务

观察logcat中会有类似打印:

I/libc(xxxx): xxxx using MALLOC_DEBUG = 1 (leak checker)

 

5.

Native Crash

1.   首先先认识Tombstone文件,可以帮我们分析native crash的问题

a)        Tombstone

中文译, “墓碑”,顾名思义,就是在进程死掉后,记录他的名字和临死前的“事迹”。这里“事迹”主要是指进程寄存器内容和调用栈;

一般来说,在linux系统上,当进程访问了非法地址后,只有kernel才能检测到,此时kernel会向对应进程发送SIGSEGV信号,要求进程处理,一般进程收到后的默认处理是直接退出;这个默认动作是在libc中写死的,当然也可以自己去捕获这个信号,做些其他处理。那么,androidlibcbionic,就做了不一样的处理,see: bionic/linker/debugger.c:123, 默认一些严重错误信号的处理都被debugger_signal_hander截获处理,这个函数仅连接unix域“Android:debuggerd”debuggerd Service(see system/core/debuggerd.c),交由debuggerd(在init.rc中启动/release/debug版本都有)根据发送他过去的tid,使用ptrace函数(man ptrace),打印程序当前的调用栈和寄存器,并存入tombstone文件,文件路径/data/tombstone/***因为,这个功能是在android libc中存在的,所以,所有native进程,都具有这个debug特点。

举一反三:使用kill发送一个异常信号给对应的进程,也可以把当前调用栈打出来并推出吧。这对解决进程挂死有些用处,限native应用。

b)        对调用栈的分析

调用栈打印时会减去内核映射的虚基地址,那么调用栈中的地址就是符号表中的相对地址,这对我们分析问题很有利。使用的工具是:

Arm-eabi-addr2line

Arm-eabi-objdump

用法:

Arm-eabi-addr2line –f –e 符号表调用栈地址

输出:函数地址和出错文件的代码行

定位:通过走读代码,结合场景上下文分析,应该不难定位;

arm-eabi-objdump –D 符号表或者可执行文件 > dump.txt

输出: dump.txt是反汇编后代码,可以结合arm汇编知识,查看此处问题

6

android存异常日志的地方:

/data/system/dropbox/data/dontpanic/err/data/tomstonedata/anrdump&log

 

monkey crash 有7种 FC ANR WatchDog 属于应用层面的crashtombstone cc/c++死 属于native层 modem 属于cp层apanic 属于内核层

前面2种是最常见的tombstone 分为2种 一种为应用错误 一种为系统错误 需要具体定位分析monkey测试除了以上几个文件夹需要拷贝其实还有一个monkeyscreenlog以及dumpsys.log还有一个bugreport这些也需要拷贝出来分析的FC和ANR的错误可以直接看/data/system/dropbox里面的文件 有对应的关键字 例如 anr dropbox里面event_data 就只有 start= XXXXX end=XXXXX

7 linux下ADB增加权限

/etc/udev/rules.d/51-android.rules文件中增加SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device",MODE="0666"

8 One of the most useful pieces of information you can get from a network interface is the list of IP addresses that are assigned to it. You can obtain this information from a NetworkInterface instance by using one of two methods. The first method, getInetAddresses(), returns an Enumeration of InetAddress. The other method, getInterfaceAddresses(), returns a list of java.net.InterfaceAddress instances. This method is used when you need more information about an interface address beyond its IP address. For example, you might need additional information about the subnet mask and broadcast address when the address is an IPv4 address, and a network prefix length in the case of an IPv6 address.

The following example program lists all the network interfaces and their addresses on a machine:

   import java.io.*;   import java.net.*;   import java.util.*;   import static java.lang.System.out;      public class ListNets {          public static void main(String args[]) throws SocketException {           Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();           for (NetworkInterface netint : Collections.list(nets))               displayInterfaceInformation(netint);       }          static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {           out.printf("Display name: %s\n", netint.getDisplayName());           out.printf("Name: %s\n", netint.getName());           Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();           for (InetAddress inetAddress : Collections.list(inetAddresses)) {               out.printf("InetAddress: %s\n", inetAddress);           }           out.printf("\n");        }   }  

The following is sample output from the example program:

Display name: TCP Loopback interfaceName: loInetAddress: /127.0.0.1

Display name: Wireless Network ConnectionName: eth0InetAddress: /192.0.2.0

9 模拟按键的方法

adb shell input keyevent <keycode> 
 其中<keycode>表示按键代码,它值在frameworks/base/include/ui/KeycodeLabels.h头文件中定义, 对于文字可以用text,eg: input text "10086"         

10. 注意要统计代码耗时,不能使用中自动打印的时间,而是应该通过currenttimeinmills或uptime的差来获得

11有时需要通过wakelock避免休眠

12 分析log中的error

adb logcat -b main -b system -b radio -v time | grep -A 50 -B 50  -E "Exception|Shutting down VM|fatal|FATAL|error|Error|system.err|System.err|died" > a1.log 

在vim中的配置

function! Logcheck()        let s:file = expand('%:p')        let s:pattern = 'Exception|Shutting down VM|fatal|FATAL|error|Error|system.err|System.err|died'        execute "Ack \"" . s:pattern . "\" " . s:fileendfunctionnnoremap <silent> <Leader>lc  :call Logcheck()<CR>

13java中enum枚举的使用注意点,当进行==比较时必须带上类名.常量名,而在switch case中的case label中则不能带类名,只需要常量名即可

14 .gitconfig的配置
[user]email = xxxxname = xxx[core]gitProxy = proxy(这是一个脚本)editor = vim[alias];lp = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %Cblue<%cN %cE>%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative --name-status    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %Cblue<%cN %cE>%Creset %s %Cgreen(%cD)%Creset' --abbrev-commit    lgn = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %Cblue<%cN %cE>%Creset %s %Cgreen(%cD)%Creset' --abbrev-commit --name-status[diff]tool = diffuse[http]proxy = http://账户:密码@地址:端口

proxy脚本:
#! /bin/bash#connect-proxy -H 地址:端口 $@exec /usr/bin/corkscrew 地址 端口 $* ~/bin/auth

auth文本
账户:密码

15 各种代理
apt代理
/etc/apt/apt.conf
Acquire::http::Proxy "http://账户:密码@代理地址:代理端口";

wget代理
~/.wgetrc
http-proxy=http://账户:密码@代理地址:代理端口/

curl代理
~/.curlrc
--proxy=http://账户:密码@代理地址:代理端口/

.bashrc .zshrc
export http_proxy="http://账户:密码@代理地址:代理端口/"






0 0
原创粉丝点击