android

2163阅读 0评论2011-06-27 yuzaipiaofei
分类:

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 st1\:*{behavior:url(#ieooui) } /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;}

自行封装Android cutils.Log. 40

  的历史

Google2005年收购了Android这家做移动终端开源操作系统的公司,然后在2007年主导建立了OHA(开放手机联盟),这个联盟集结了包括从芯片厂商到运营商等产业重要力量。Google希望:通过开源的方式改变手机操作系统平台各自为政的状况,一统江湖。

 

为了建立Android平台的独特性,终端厂商唯一能花力气的就是用户界面(UI),几大主要厂商几乎都已经有了固定特色的界面,包括HTC Sense、摩托罗拉 Blur、索爱 Rachael UI

 

2009OHA成员中国移动推出了基于Android进行二次开发的oPhone操作系统(OMS),在保持了100%兼容的同时,在开放初期,还大量集成了中国移动的增值服务,使其更适合中国用户的使用习惯。

 

的特点

第三方应用完全可以通过JNI调用自己的C动态库

 

各版本区别

 


 

 

 

 

 

https://market.android.com/

 

 

 

源码目录

文章分类:移动开发

Android 2.1 |-- Makefile |-- bionic bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts Android兼容性测试套件标准) |-- dalvik dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external android使用的一些开源的模组) |-- frameworks

 

 Android 2.1

|-- Makefile

|-- bionic                        bionic C库)

|-- bootable                (启动引导相关代码)

|-- build                        (存放系统编译规则及generic等基础开发包配置)

|-- cts                        Android兼容性测试套件标准)

|-- dalvik                        dalvik JAVA虚拟机)

|-- development        (应用程序开发相关)

|-- external                android使用的一些开源的模组)

|-- frameworks                (核心框架——javaC++语言)

|-- hardware                (部分厂家开源的硬解适配层HAL代码)

|-- out                        (编译完成后的代码输出与此目录)

|-- packages                (应用程序包)

|-- prebuilt                x86arm架构下预编译的一些资源)

|-- sdk                        sdk及模拟器)

|-- system                        (底层文件系统库、应用及组件——C语言)

`-- vendor                (厂商定制代码)

 

bionic 目录

|-- libc                        C库)

|   |-- arch-arm        ARM架构,包含系统调用汇编实现)

|   |-- arch-x86        x86架构,包含系统调用汇编实现)

|   |-- bionic                (由C实现的功能,架构无关)

|   |-- docs                (文档)

|   |-- include                (头文件)

|   |-- inet                (?inet相关,具体作用不明)

|   |-- kernel                Linux内核中的一些头文件)

|   |-- netbsd                (?nesbsd系统相关,具体作用不明)

|   |-- private                (?一些私有的头文件)

|   |-- stdio                stdio实现)

|   |-- stdlib                stdlib实现)

|   |-- string                string函数实现)

|   |-- tools                (几个工具)

|   |-- tzcode                (时区相关代码)

|   |-- unistd                unistd实现)

|   `-- zoneinfo        (时区信息)

|-- libdl                        libdl实现,dl是动态链接,提供访问动态链接库的功能)

|-- libm                        libm数学库的实现,)

|   |-- alpha                apaha架构)

|   |-- amd64                amd64架构)

|   |-- arm                arm架构)

|   |-- bsdsrc                (?bsd的源码)

|   |-- i386                i386架构)

|   |-- i387                i387架构?)

|   |-- ia64                ia64架构)

|   |-- include                (头文件)

|   |-- man                (数学函数,后缀名为.3,一些为freeBSD的库文件)

|   |-- powerpc        powerpc架构)

|   |-- sparc64                sparc64架构)

|   `-- src                (源代码)

|-- libstdc++                libstdc++ C++实现库)

|   |-- include                (头文件)

|   `-- src                (源码)

|-- libthread_db        (多线程程序的调试器库)

|   `-- include                (头文件)

`-- linker                        (动态链接器)

`-- arch                (支持armx86两种架构)

 

bootable 目录

.

|-- bootloader                                (适合各种bootloader的通用代码)

|   `-- legacy                                (估计不能直接使用,可以参考)

|       |-- arch_armv6                V6架构,几个简单的汇编文件)

|       |-- arch_msm7k                (高通7k处理器架构的几个基本驱动)

|       |-- include                        (通用头文件和高通7k架构头文件)

|       |-- libboot                        (启动库,都写得很简单)

|       |-- libc                        (一些常用的c函数)

|       |-- nandwrite                nandwirte函数实现)

|       `-- usbloader                usbloader实现)

|-- diskinstaller                        android镜像打包器,x86可生产iso

`-- recovery                                (系统恢复相关)

    |-- edify                                (升级脚本使用的edify脚本语言)

    |-- etc                                init.rc恢复脚本)

    |-- minui                                (一个简单的UI

    |-- minzip                                (一个简单的压缩工具)

    |-- mtdutils                        mtd工具)

    |-- res                                (资源)

    |   `-- images                        (一些图片)

    |-- tools                                (工具)

    |   `-- ota                        OTA Over The Air Updates升级工具)

`-- updater                        (升级器)

 

build目录

.

|-- core                                (核心编译规则)

|-- history                                (历史记录)

|-- libs                               

|   `-- host                        (主机端库,有android cp”功能替换)

|-- target                                (目标机编译对象)

|   |-- board                        (开发平台)

|   |   |-- emulator        (模拟器)

|   |   |-- generic                (通用)

|   |   |-- idea6410        (自己添加的)

|   |   `-- sim                (最简单)

|   `-- product                (开发平台对应的编译规则)

|       `-- security        (密钥相关)

`-- tools                                (编译中主机使用的工具及脚本)

    |-- acp                        Android "acp" Command

    |-- apicheck                api检查工具)

    |-- applypatch                (补丁工具)

    |-- apriori                        (预链接工具)

    |-- atree                        tree工具)

    |-- bin2asm                bin转换为asm工具)

    |-- check_prereq        (检查编译时间戳工具)

    |-- dexpreopt                (模拟器相关工具,具体功能不明)

    |-- droiddoc                (?作用不明,java语言,网上有人说和JDK5有关)

    |-- fs_config                This program takes a list of files and directories

    |-- fs_get_stats                (获取文件系统状态)

    |-- iself                        (判断是否ELF格式)

    |-- isprelinked                (判断是否prelinked

    |-- kcm                        (按键相关)

    |-- lsd                        List symbol dependencies

    |-- releasetools                (生成镜像的工具及脚本)

    |-- rgb2565                rgb转换为565

    |-- signapk                apk签名工具)

    |-- soslim                        strip工具)

`-- zipalign                zip archive alignment tool

 

dalvik目录 dalvik虚拟机

.

|-- dalvikvm                        main.c的目录)

|-- dexdump                        dex反汇编)

|-- dexlist                                List all methods in all concrete classes in a DEX file.

|-- dexopt                                (预验证与优化)

|-- docs                                (文档)

|-- dvz                                (和zygote相关的一个命令)

|-- dx                                dx工具,将多个java转换为dex

|-- hit                                (?java语言写成)

|-- libcore                                (核心库)

|-- libcore-disabled                (?禁用的库)

|-- libdex                                dex的库)

|-- libnativehelper                Support functions for Android's class libraries

|-- tests                                (测试代码)

|-- tools                                (工具)

`-- vm                                (虚拟机实现)

 

development 目录                (开发者需要的一些例程及工具)

|-- apps                                (一些核心应用程序)

|   |-- BluetoothDebug        (蓝牙调试程序)

|   |-- CustomLocale        (自定义区域设置)

|   |-- Development        (开发)

|   |-- Fallback                (和语言相关的一个程序)

|   |-- FontLab                (字库)

|   |-- GestureBuilder        (手势动作)

|   |-- NinePatchLab        (?)

|   |-- OBJViewer                OBJ查看器)

|   |-- SdkSetup                SDK安装器)

|   |-- SpareParts                (高级设置)

|   |-- Term                        (远程登录)

|   `-- launchperf                (?)

|-- build                                (编译脚本模板)

|-- cmds                                (有个monkey工具)

|-- data                                (配置数据)

|-- docs                                (文档)

|-- host                                (主机端USB驱动等)

|-- ide                                (集成开发环境)

|-- ndk                                (本地开发套件——c语言开发套件)

|-- pdk                                Plug Development Kit

|-- samples                        (例程)

|   |-- AliasActivity        (?)

|   |-- ApiDemos                API演示程序)

|   |-- BluetoothChat        (蓝牙聊天)

|   |-- BrowserPlugin        (浏览器插件)

|   |-- BusinessCard        (商业卡)

|   |-- Compass                (指南针)

|   |-- ContactManager        (联系人管理器)

|   |-- CubeLiveWallpaper        (动态壁纸的一个简单例程)

|   |-- FixedGridLayout        (像是布局)

|   |-- GlobalTime                (全球时间)

|   |-- HelloActivity        Hello

|   |-- Home                        Home

|   |-- JetBoy                        jetBoy游戏)

|   |-- LunarLander        (貌似又是一个游戏)

|   |-- MailSync                (邮件同步)

|   |-- MultiResolution        (多分辨率)

|   |-- MySampleRss        RSS

|   |-- NotePad                (记事本)

|   |-- RSSReader                RSS阅读器)

|   |-- SearchableDictionary        (目录搜索)

|   |-- SimpleJNI                JNI例程)

|   |-- SkeletonApp        (空壳APP

|   |-- Snake                        snake程序)

|   |-- SoftKeyboard        (软键盘)

|   |-- Wiktionary                (?维基)

|   `-- WiktionarySimple(?维基例程)

|-- scripts                                (脚本)

|-- sdk                                sdk配置)

|-- simulator                        (?模拟器)

|-- testrunner                        (?测试用)

`-- tools                                (一些工具)

 

external 目录

.

|-- aes                        AES加密)

|-- apache-http                (网页服务器)

|-- astl                        ASTL (Android STL) is a slimmed-down version of the regular C++ STL.

|-- bison                        (自动生成语法分析器,将无关文法转换成CC++

|-- blktrace                blktrace is a block layer IO tracing mechanism

|-- bluetooth                (蓝牙相关、协议栈)

|-- bsdiff                        diff工具)

|-- bzip2                        (压缩工具)

|-- clearsilver                html模板系统)

|-- dbus                        (低延时、低开销、高可用性的IPC机制)

|-- dhcpcd                DHCP服务)

|-- dosfstools                DOS文件系统工具)

|-- dropbear                SSH2server

|-- e2fsprogs                EXT2文件系统工具)

|-- elfcopy                (复制ELF的工具)

|-- elfutils                        ELF工具)

|-- embunit                Embedded Unit Project

|-- emma                        java代码覆盖率统计工具)

|-- esd                        Enlightened Sound Daemon,将多种音频流混合在一个设备上播放)

|-- expat                        Expat is a stream-oriented XML parser.

|-- fdlibm                        FDLIBM (Freely Distributable LIBM)

|-- freetype                (字体)

|-- fsck_msdos                dos文件系统检查工具)

|-- gdata                        google的无线数据相关)

|-- genext2fs                genext2fs generates an ext2 filesystem as a normal (non-root) user

|-- giflib                        gif库)

|-- googleclient        google用户库)

|-- grub                        This is GNU GRUB, the GRand Unified Bootloader.

|-- gtest                        Google C++ Testing Framework

|-- icu4c                        ICU(International Component for Unicode)C/C++下的版本)

|-- ipsec-tools                This package provides a way to use the native IPsec functionality

|-- iptables                (防火墙)

|-- jdiff                        generate a report describing the difference between two public Java APIs.

|-- jhead                        jpeg头部信息工具)

|-- jpeg                        jpeg库)

|-- junit                        JUnit是一个Java语言的单元测试框架)

|-- kernel-headers        (内核的一些头文件)

|-- libffi                        libffi is a foreign function interface library.

|-- libpcap                (网络数据包捕获函数)

|-- libpng                        png库)

|-- libxml2                xml解析库)

|-- mtpd                        (一个命令)

|-- netcat                        simple Unix utility which reads and writes dataacross network connections

|-- netperf                        (网络性能测量工具)

|-- neven                        (看代码和JNI相关)

|-- opencore                (多媒体框架)

|-- openssl                SSL加密相关)

|-- openvpn                VPN开源库)

|-- oprofile                OProfileLinux内核支持的一种性能分析机制。)

|-- ping                        ping命令)

|-- ppp                        pppd拨号命令,好像还没有chat

|-- proguard                Java class file shrinker, optimizer, obfuscator, and preverifier

|-- protobuf                a flexible, efficient, automated mechanism for serializing structured data

|-- qemu                        arm模拟器)

|-- safe-iop                functions for performing safe integer operations

|-- skia                        skia图形引擎)

|-- sonivox                sole MIDI solution for Google Android Mobile Phone Platform

|-- speex                        Speex/解码API的使用(libspeex)

|-- sqlite                        (数据库)

|-- srec                        Nuance 公司提供的开源连续非特定人语音识别)

|-- strace                        trace工具)

|-- svox                        Embedded Text-to-Speech

|-- tagsoup                TagSoup是一个Java开发符合SAXHTML解析器)

|-- tcpdump                (抓TCP包的软件)

|-- tesseract                Tesseract Open Source OCR Engine.

|-- tinyxml                TinyXml is a simple, small, C++ XML parser

|-- tremor                        I stream and file decoder provides an embeddable,integer-only library

|-- webkit                        (浏览器核心)

|-- wpa_supplicant        (无线网卡管理)

|-- xmlwriter                XML 编辑工具)

|-- yaffs2                        yaffs文件系统)

`-- zlib                        a general purpose data compression library

 

frameworks 目录        (核心框架——javaC++语言)

.

|-- base                        (基本内容)

|   |-- api                (?都是xml文件,定义了javaapi?)

|   |-- awt                AWT库)

|   |-- build                (空的)

|   |-- camera                (摄像头服务程序库)

|   |-- cmds                (重要命令:amapp_proce等)

|   |-- core                (核心库)

|   |-- data                (字体和声音等数据文件)

|   |-- docs                (文档)

|   |-- graphics        (图形相关)

|   |-- include                (头文件)

|   |-- keystore        (和数据签名证书相关)

|   |-- libs                (库)

|   |-- location        (地区库)

|   |-- media                (媒体相关库)

|   |-- obex                (蓝牙传输库)

|   |-- opengl                2D-3D加速库)

|   |-- packages        (设置、TTSVPN程序)

|   |-- sax                XML解析器)

|   |-- services        (各种服务程序)

|   |-- telephony        (电话通讯管理)

|   |-- test-runner        (测试工具相关)

|   |-- tests                (各种测试)

|   |-- tools                (一些叫不上名的工具)

|   |-- vpn                VPN

|   `-- wifi                (无线网络)

|-- opt                        (可选部分)

|   |-- com.google.android                                (有个framework.jar

|   |-- com.google.android.googlelogin                (有个client.jar

|   `-- emoji                standard message elements

`-- policies                Product policies are operating system directions aimed at specific uses

    `-- base               

        |-- mid        MID设备)

        `-- phone        (手机类设备,一般用这个)

 

hardware 目录                (部分厂家开源的硬解适配层HAL代码)

|-- broadcom                        (博通公司)

|   `-- wlan                        (无线网卡)

|-- libhardware                        (硬件库)

|   |-- include                        (头文件)

|   `-- modules                Default (and possibly architecture dependents) HAL modules

|       |-- gralloc                gralloc显示相关)

|       `-- overlay                Skeleton for the "overlay" HAL module.

|-- libhardware_legacy        (旧的硬件库)

|   |-- flashlight                (背光)

|   |-- gps                        GPS

|   |-- include                        (头文件)

|   |-- mount                        (旧的挂载器)

|   |-- power                        (电源)

|   |-- qemu                        (模拟器)

|   |-- qemu_tracing        (模拟器跟踪)

|   |-- tests                        (测试)

|   |-- uevent                        uevent

|   |-- vibrator                        (震动)

|   `-- wifi                        (无线)

|-- msm7k                        (高通7k处理器开源抽象层)

|   |-- boot                        (启动)

|   |-- libaudio                (声音库)

|   |-- libaudio-qsd8k        qsd8k的声音相关库)

|   |-- libcamera                (摄像头库)

|   |-- libcopybit                copybit库)

|   |-- libgralloc                gralloc库)

|   |-- libgralloc-qsd8k        qsd8kgralloc库)

|   |-- liblights                (背光库)

|   `-- librpc                        RPC库)

|-- ril                                (无线电抽象层)

|   |-- include                        (头文件)

|   |-- libril                        (库)

|   |-- reference-cdma-sms        cdma短信参考)

|   |-- reference-ril                        ril参考)

|   `-- rild                                ril后台服务程序)

`-- ti                                                ti公司开源HAL

    |-- omap3                                omap3处理器)

    |   |-- dspbridge                DSP桥)

    |   |-- libopencorehw        opencore硬件库)

    |   |-- liboverlay                overlay硬件库)

    |   |-- libstagefrighthw        stagefright硬件库)

    |   `-- omx                        omx组件)

    `-- wlan                                (无线网卡)

 

packages 目录

.

|-- apps                                (应用程序库)

|   |-- AlarmClock                (闹钟)

|   |-- Bluetooth                (蓝牙)

|   |-- Browser                (浏览器)

|   |-- Calculator                (计算器)

|   |-- Calendar                (日历)

|   |-- Camera                 (相机)

|   |-- CertInstaller                (在Android中安装数字签名,被调用)

|   |-- Contacts                (拨号(调用)、联系人、通话记录)

|   |-- DeskClock                (桌面时钟)

|   |-- Email                        Email

|   |-- Gallery                        (相册,和Camera类似,多了列表)

|   |-- Gallery3D                (?3D相册)

|   |-- GlobalSearch        (为google搜索服务,提供底层应用)

|   |-- GoogleSearch        google搜索)

|   |-- HTMLViewer        (浏览器附属界面,被浏览器应用调用,同时提供存储记录功能)

|   |-- IM                        (即时通讯,为手机提供信号发送、接收、通信的服务)

|   |-- Launcher                (登陆启动项,显示图片框架等等图形界面)

|   |-- Launcher2                (登陆启动项,负责应用的调用)

|   |-- Mms                        (?彩信业务)

|   |-- Music                        (音乐播放器)

|   |-- PackageInstaller        (安装、卸载程序的响应)

|   |-- Phone                        (电话拨号程序)

|   |-- Provision                (预设应用的状态,使能应用)

|   |-- Settings                (开机设定,包括电量、蓝牙、设备信息、界面、wifi等)

|   |-- SoundRecorder        (录音机,可计算存储所需空间和时间)

|   |-- Stk                         (接收和发送短信)

|   |-- Sync                        (空)   -------1

|   |-- Updater                (空)

|   `-- VoiceDialer                (语音识别通话)

|-- inputmethods                (输入法)

|   |-- LatinIME                (拉丁文输入法)

|   |-- OpenWnn                OpenWnn输入法)

|   `-- PinyinIME                (拼音输入法)

|-- providers                        (提供器,提供应用程序、界面所需的数据)

|   |-- ApplicationsProvider                (应用程序提供器,提供应用程序启动项、更新等)

|   |-- CalendarProvider                        (日历提供器)

|   |-- ContactsProvider                        (联系人提供器)

|   |-- DownloadProvider                (下载管理提供器)

|   |-- DrmProvider                        (创建和更新数据库时调用)

|   |-- GoogleContactsProvider        (联系人提供器的子类,用以同步联系人)

|   |-- GoogleSubscribedFeedsProvider(设置信息提供器)

|   |-- ImProvider                                (空)

|   |-- ManagementProvider                (空)

|   |-- MediaProvider                        (媒体提供器,提供存储数据)

|   |-- TelephonyProvider                (彩信提供器)

|   |-- UserDictionaryProvider        (用户字典提供器,提供用户常用字字典)

|   `-- WebSearchProvider                (空)

|-- services                                       

|   |-- EasService                                (空)

|   `-- LockAndWipe                        (空)

`-- wallpapers                                        (墙纸)

    |-- Basic                                        (基本墙纸,系统内置墙纸)

    |-- LivePicker                                (选择动态壁纸)

    |-- MagicSmoke                        (壁纸特殊效果)

    `-- MusicVisualization                (音乐可视化,图形随音乐而变化)

 

1里面有一个隐藏的.git文件夹,内容都是一样的,没有有意义的代码,config看似乎是一个下载程序,因此认为这些文件夹下没有实质东西。

 

prebuilt 目录                        x86arm架构下预编译的一些资源)

.

|-- android-arm                arm-android相关)

|   |-- gdbserver                gdb调试器)

|   `-- kernel                        (模拟的arm内核)

|-- android-x86                x86-android相关)

|   `-- kernel                        (空的)

|-- common                        (通用编译好的代码,应该是java的)

|-- darwin-x86                        drawin x86平台)

|   `-- toolchain                (工具链)

|       |-- arm-eabi-4.2.1       

|       |-- arm-eabi-4.3.1       

|       `-- arm-eabi-4.4.0       

|-- darwin-x86_64                drawin x86 64bit平台)

|-- linux-x86                        linux x86平台)

|   `-- toolchain                (工具链,我们应该主要用这个)

|       |-- arm-eabi-4.2.1       

|       |-- arm-eabi-4.3.1       

|       |-- arm-eabi-4.4.0       

|       `-- i686-unknown-linux-gnu-4.2.1        x86版编译器)

|-- linux-x86_64                linux x86 64bit平台)

|-- windows                        windows平台)

`-- windows-x86_64        64bit windows平台)

system 目录                (底层文件系统库、应用及组件——C语言)

.

|-- Bluetooth                (蓝牙相关)

|-- core                        (系统核心工具盒接口)

|   |-- adb                adb调试工具)

|   |-- cpio                cpio工具,创建img

|   |-- debuggerd        (调试工具)

|   |-- fastboot        (快速启动相关)

|   |-- include                (系统接口头文件)

|   |-- init                init程序源代码)

|   |-- libacc                (轻量级C编译器)

|   |-- libctest                libc测试相关)

|   |-- libcutils        libc工具)

|   |-- liblog                log库)

|   |-- libmincrypt        (加密库)

|   |-- libnetutils        (网络工具库)

|   |-- libpixelflinger        (图形处理库)

|   |-- libsysutils        (系统工具库)

|   |-- libzipfile        zip库)

|   |-- logcat                (查看log工具)

|   |-- logwrapper        log封装工具)

|   |-- mkbootimg        (制作启动boot.img的工具盒脚本)

|   |-- netcfg                (网络配置netcfg源码)

|   |-- nexus                google最新手机的代码)

|   |-- rootdir                rootfs,包含一些etc下的脚本和配置)

|   |-- sh                        shell代码)

|   |-- toolbox                toolbox,类似busybox的工具集)

|   `-- vold                SD卡管理器)

|-- extras                        (额外工具)

|   |-- latencytop        a tool for software developers identifying system latency happen

|   |-- libpagemap        pagemap库)

|   |-- librank                Java Library Ranking System库)

|   |-- procmem        pagemap相关)

|   |-- procrank        Java Library Ranking System相关)

|   |-- showmap        showmap工具)

|   |-- showslab        showslab工具)

|   |-- sound                (声音相关)

|   |-- su                        su命令源码)

|   |-- tests                (一些测试工具)

|   `-- timeinfo        (时区相关)

`-- wlan                        (无线相关)

    `-- ti                        ti网卡相关工具及库)

 

 

vendor 目录                        (厂家定制内容)

 

|-- aosp                                android open source project

|   `-- products                (一些板级规则)

|-- htc                                HTC公司)

|   |-- common-open        (通用部分)

|   |   `-- akmd                (解压img用的工具)

|   |-- dream-open                G1开放部分)

|   |-- prebuilt-open        (预编译开放部分)

|   `-- sapphire-open        sapphire这款型号开放内容)

|-- pv-open                        (没东西)

|-- qcom                                (里面基本是空的)

`-- sample                        google提供的样例)

    |-- apps                        (应用)

    |   |-- client                (用户)

    |   `-- upgrade        (升级)

    |-- frameworks                (框架)

    |   `-- PlatformLibrary        (平台库)

    |-- products                (产品)

    |-- sdk_addon                sdk添加部分)

    `-- skins                        (皮肤)

        `-- WVGAMedDpi        WVGA适用的图片)

 

 

~/bin/mydroid/out/target/product/generic/ 目录下运行命令:

emulator -image system.img -data userdata.img -ramdisk ramdisk.img

 

ramdisk.img: 包含了在模拟器中启动Android所需的文件系统

system.img: 初始的Android系统映像,包含了程序和库文件

userdata.img: 初始的用户数据映像文件

 

模拟器会首先到指定的AVD所在的目录查找是否有userdata映像存在,如果没有的话就会基于初始的userdata.img来创建一个,加

载这3个映像文件后,它会把system.imguserdata.img分别挂载载到ramdisk文件系统中的systemuserdata目录下。所有的用

户数据都会被保存在AVD目录下的userdata-qemu.img中,初始的用户数据映像文件并不会被修改。

 

通过命令行参数启动模拟器,加载我们编译的系统映像的方法:

emulator @1.5_L2 -system system.img -ramdisk ramdisk.img

或者加上-kernel参数,用自己编出来的kernel来启动。

 

模拟器命令

android list target

android create avd -t * -n *

emulator -avd *

make snod //package to build system.img ....

mm GPSUI TARGET_PRODUCT=pnx6715_refd

use help command to review all of envsetup.sh

 

- croot:   Changes directory to the top of the tree.
- m:       Makes from the top of the tree.
- mm:      Builds all of the modules in the current directory.
- mmm:     Builds all of the modules in the supplied directories.
- cgrep:   Greps on all local C/C++ files.
- hgrep:   Greps on all local C/C++ header files.
- jgrep:   Greps on all local Java files.
- mkgrep:  Greps on all local make files.
- rcgrep:  Greps on all local .rc files.
- resgrep: Greps on all local res/*.xml files.
- shgrep:  Greps on all local .sh files.
- godir:   Go to the directory containing a file.

 

eg:

root@ubuntu:/home/android/src# mmm external/jpeg/

root@ubuntu:/home/android/src/external/jpeg# mm

root@ubuntu:/home/android/src# m

root@ubuntu:/home/android/src# make libjpeg  //if LOCAL_MODULE:= libjpeg

 

intro

Refer to : src/ndk/docs/OVERVIEW.html

 

Quote: The Android NDK is a set of tools that allows Android application developers

to embed native machine code compiled from C and/or C++ source files into their application packages.

 

 

Native Development Kit

refer to : http://developer.android.com/sdk/ndk/index.html

 

quote: http://blog.csdn.net/hhao137/archive/2009/06/28/4304664.aspx

 

1NDK是一系列工具的集合。

 

2NDK提供了一份稳定、功能有限的API头文件声明。

    Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。

 

3NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。

 

reference: src/ndk/doc/document.html

reference: src/ndk/docs/ANDROID-MK.html

reference: Android Building System 总结 -> http://blog.csdn.net/yili_xie/archive/2009/12/14/5004205.aspx

类似PRODUCT_COPY_FILES的变量参考文档-build/core/Makefile

 

 

一个Android.mk file用来向编译系统描述你的源代码,该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。

 

只有共享库将被安装/复制到您的应用软件包。虽然静态库能被用于生成共享库。

 

编译系统为你处理许多细节问题。例如,你不需要在你的Android.mk中列出头文件和依赖文件。NDK编译系统将会为你自动处理这些问题。这也意味着,在升级NDK后,你应该得到新的toolchain/platform支持,而且不需要改变你的Android.mk文件。

 

LOCAL_PATH := $(call my-dir)

宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)

 

  include $( CLEAR_VARS)

  指向一个编译脚本,几乎所有未定义的LOCAL_XXX变量都在"Module-description"节中列出。你必须在开始一个新模块之前包含这个脚本。CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),除了LOCAL_PATH

 

  LOCAL_MODULE := helloworld

  LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件。

 

  LOCAL_SRC_FILES := helloworld.c

  LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的CC++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

  注意,默认的 C++源码文件的扩展名是’.cpp’. 指定一个不同的扩展名也是可能的,只要定义 LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始的小圆点(也就是’.cxx’,而不是’cxx’).

  include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU Makefile脚本,负责收集自从上次调用'include $(CLEAR_VARS)'以来,定义在LOCAL_XXX变量中的所有信息,并且决定编译什么,如何正确地去做。还有 BUILD_STATIC_LIBRARY变量生成静态库。

 

  NDK编译系统保留下列变量名:

  -LOCAL_开头的名字(例如 LOCAL_MODULE)

  -PRIVATE_, NDK_ or APP_开头的名字(内部使用)

    -小写名字(内部使用,例如’my-dir’)

 

函数: 

    以下是一些GNU Make的宏函数,必须通过这样的形式调用:

       '$(call )'

         

    all-subdir-makefiles

     返回‘my-dir’子目录下的所有Android.mk。比如,代码的结构如下:

     sources/foo/Android.mk

     sources/foo/lib1/Android.mk

     sources/foo/lib2/Android.mk

     

     如果sources/foo/Android.mk里有这样一行:

     

     include $(call all-subdir-makefiles)

     

     那么,它将会自动地includesources/foo/lib1/Android.mksources/foo/lib2/Android.mk

     

     这个函数能将深层嵌套的代码文件夹提供给生成系统。注意,默认情况下,NDK仅在

     source/*/Android.mk里寻找文件。

     

    this-makefile

     返回当前Makefile(译者注:指的应该是GNU Makefile)的路径(即,这个函数是在哪里调用的)

 

    parent-makefile

     返回在列入树(inclusion tree)中的父makefile的路径。

     即,包含当前makefile的那个makefile的路径。

 

    grand-parent-makefile

     猜猜看...(译者注:原文为Guess what...)

 

 

    - - - - - - - - - -

 

    以下的变量是用来向生成系统描述你的组件的。你应该在'include $(CLEAR_VARS)'

    'include $(BUILD_XXXXX)'之间定义其中的一些变量。正如在前面所说的,$(CLEAR_VARS)

    是一个将会取消所有这些变量的脚本,除非在对变量的描述时有显式的说明。

     

    LOCAL_PATH

     这个变量用来设置当前文件的路径。你必须在Android.mk的开始处定义它,比如:

     

     LOCAL_PATH := $(call my-dir)

     

     这个变量不会被$(CLEAR_VARS)消除,所以每个Android.mk仅需一个定义(以防你在

     同一个文件里定义几个组件)。

   

     

    LOCAL_MODULE

     定义组件的名称。对于所有的组件名,它必须是唯一,且不能包含空格。

     include $(BUILD_XXX)之前你必须定义它。

   

     这个组件名决定生成的文件(译者注:即库名)。比如,lib,即这个组件的名称

     。但是在你的NDK生成文件(不管是Android.mk还是Application.mk)

     你只能通过正常的名称(如,)来引用其它的组件。

   

     

    LOCAL_SRC_FILES

     用它来定义所有用来生成组件的源文件。仅须列出传给编译器的文件,因为

     生成系统会自动地计算它们的相互依赖关系。

   

     注意,所有文件名都是相对于LOCAL_PATH的,你可以用到路径组件(path component)

     如:

     LOCAL_SRC_FILES := foo.c \ (译者注:‘\’为连接符)

     toto/bar.c

     

    LOCAL_CPP_EXTENSION

     这是一个可选的变量,可用它来指明C++源文件的扩展名。默认情况下是'.cpp',

     但你可以改变它。比如:

   

     LOCAL_CPP_EXTENSION := .cxx

   

   

    LOCAL_C_INCLUDES

//JC: 添加包含的头文件路径,

//likeLOCAL_C_INCLUDES += external/libiconv/include

     一个相对于相对于NDK**目录可选的路径名单,当编译所有的源文件(C,C++和汇编)时,

     它将被添加进include搜索路径。例如:

   

     LOCAL_C_INCLUDES := sources/foo

   

     或者甚至:

     

     LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

 

    LOCAL_CFLAGS

     一个可选的编译标记集,在生成CC++源文件时,将解析它。

     

     对指定额外的宏定义或编译选项很有用。

     

     重要:不要试图改变你Android.mk里的optimization/debuggin level,通过

     在你的Android.mk里指定合适的信息,它将被自动处理,并使NDK生成

     调试时可用的有用的数据文件。

     

     注意:在android-ndk-1.5_r1,相应的标记(flags)只适用于C源文件,对C++

      源文件并不适用。为了适用于完整的Android生成系统的特性,已作了修

      正。(现在,你可以使用LOCAL_CPPFLAGSC++文件指定标记)

    LOCAL_CXXFLAGS

     LOCAL_CPPFLAGS的别名。注意,不建议使用这个变量,因为在未来的NDK版本中,

     它可能会消失。

    LOCAL_CPPFLAGS

     一个可选的编译标记集,**在生成C++源文件时解析它。在编译器的命令行里

     它将在LOCAL_CFLAGS之后出现。

     注意:在android-ndk-1.5_r1,相应的标记(flags)适用于CC++源文件。

      为了适用于完整的Android生成系统的特性,已作了修

      正。(现在,你可以使用LOCAL_CFLAGSCC++源文件指定标记)

    LOCAL_STATIC_LIBRARIES

     一份static libraries组件的名单(以BUILD_STATIC_LIBRARY的方式生成),它将被

     连接到欲生成的组件上。这仅在生成shared library组件时有意义。(译者注:将指定

     的一个或多个static library module转化为一个shared library module)

    LOCAL_SHARED_LIBRARIES

//JC:包含的动态库

     一份该组件在运行期依赖于它的shared libraries *组件*。在连接时间(link time)

     与及为该生成的文件嵌入相应的信息都要用到它。

     注意,它并不将这份组件名单添加入生成图表(build graph)。即,在你的Android.mk

     里,你仍应该将它们加入到你的应用程序要求的组件。

    LOCAL_LDLIBS

     一份能在生成你的组件时用到的额外的连接器标记(linkerflags)的名单。在传递

     “-l”前缀的特殊系统库的名称时很有用。比如,下面的语句会告诉连接器在装载

     时间(load time)里生成连接到/system/lib/libz.so的组件。

     LOCAL_LDLIBS := -lz

     若想知道在这个NDK版本可以连接哪些暴露的系统库(exposed system libraries)

     请参见docs/STABLE-APIS

    LOCAL_ALLOW_UNDEFINED_SYMBOLS

     缺省值情况下,当尝试生成一个shared library遇到没有定义的引用时,会导致“undefined

     symbol”error。这对在你的源代码里捕捉bugs有很大的帮助。

     

     但是,因为一些原因你须要disable这个检查,将这个变量设置为'true’。注意,相应

     shared library可能在运行期装载失败。

    LOCAL_ARM_MODE

     缺省值情况下,ARM目标二进制将会以‘thumb’模式生成,这时每个指令都是16-bit宽的。

     如果你想强迫组件的object文件以‘arm’32位的指令)的模式生成,你可以将这个变量

     定义为'arm'。即:

     LOCAL_ARM_MODE := arm

     注意,你也可以通过将‘.arm’后缀添加到源文件名字的后面指示生成系统将指定的

     源文件以arm模式生成。例如:

     

     LOCAL_SRC_FILES := foo.c bar.c.arm

     告诉生成系统总是以arm模式编译‘bar.c’,但根据LOCAL_ARM_MODE的值生成foo.c

     注意:在你的Application.mk里将APP_OPTIM设置为'debug',这也会强迫生成ARM二进制

     代码。这是因为工具链的调度器有bugs,它对thumb码的处理不是很好。

 

//print string “here here!” on terminal while building

$(warning here here!)

//print variant value of BOARD_GPS_LIBRARIES on terminal while building

$(warning $(BOARD_GPS_LIBRARIES))

make -j4

make 2>&1 | tee /mnt/hgfs/UNIX_HOME/makeOutput.txt

 

Android系统框架

 

分四个层次,其中第三层包括:librariesAndroid runtime

Libraries : C/CPP实现;

Android Runtime:包括CoreLibraries(类似于java的基础类库)和DalvikVM

Framework通过JNI调用Libraries

referencelocal:”AndroidIPC机制Binder的各个部分

binder scheme graph:

 

 

 

Java Native Interface

referencehttp://android.git.kernel.org/?p=platform/dalvik.git;a=blob_plain;f=docs/jni-tips.html;hb=HEAD

它允许Java代码和其他语言编写的代码进行交互

android中实现的JNI库,需要连接动态库libnativehelper.so

JNI 是本地编程接口。它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码
能够与用其它编程语言( CC++ 和汇编语言)编写的应用程序和库进行互操作。

1JNI的实现方式

     实现JNI需要在Java源代码中声明,在C++代码中实现JNI的各种方法,并把这些方法注册到系统中。实现JNI的核心是JNINativeMethod结构体。

typedef struct {
       const char* name;
       const char* signature;
       void* fnPtr;
} JNINativeMethod;

 

第一个变量nameJavaJNI函数的名字,第二个变量signature用字符串描述函数参数和返回值,第三个变量fnPtrJNI函数C指针。  

 

2,在应用程序中使用JNI,可以通过代码中/development/samples/SimpleJNI来分析:

A,分析顶层Android.mk文件

    LOCAL_PACKAGE_NAME := SimpleJNI    //生成PACKAGE的名字,在out\target\product\smdk6410\obj\APPS

    LOCAL_JNI_SHARED_LIBRARIES := libsimplejni //生成JNI共享库的名字,在....smdk6410\obj\SHARED_LIBRARIES

    include $(BUILD_PACKAGE)                   //以生成APK的方式编译

    include $(call all-makefiles-under,$(LOCAL_PATH))   //调用下层makefile

B,分析JNI目录下Android.mk文件

    LOCAL_SRC_FILES:= \                           //JNIC++源文件
          native.cpp

    include $(BUILD_SHARED_LIBRARY)       //以共享库方式编译

 

3JNI的代码实现和调用

Anative.cpp内容

     static jint add(JNIEnv *env, jobject thiz, jint a, jint b){。。。} //定义JAVA方法add

     static const char *classPathName = "com/example/android/simplejni/Native";   //目标JAVA类路径

     static JNINativeMethod methods[] = {                   //本地实现方法列表
             {"add", "(II)I", (void*)add },
     };

    static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods){
。。。}   //为调用的某个JAVA类注册本地JNI函数

    static int registerNatives(JNIEnv* env){}                //为当前平台注册所有类及JNI函数

    jint JNI_OnLoad(JavaVM* vm, void* reserved){...}        //为当前虚拟机平台注册本地JNI

以上三个从下到上依次调用,实际上就是在JNI_Onload中调用RegisterNatives()来注册本地JNI方法

BSimpleJNI.java内容

    package com.example.android.simplejni;  //JAVA包,跟文件路径对应

    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;            //
需要包含的类,以便调用函数

public class SimpleJNI extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        int sum = Native.add(2, 3);                     //
调用Native类的函数add,该add就是JNI函数,由CPP实现
        tv.setText("2 + 3 = " + Integer.toString(sum));
        setContentView(tv);                                //
在屏幕上显示
    }
}

 class Native {
    static {
     // The runtime will add "lib" on the front and ".o" on the end of
     // the name supplied to loadLibrary.
        System.loadLibrary("simplejni");              //
载入由native.cpp生成的动态库,全名是lib+simplejni+.o
    }

    static native int add(int a, int b);                  //声明动态库中实现的JNI函数add,供JAVA调用
}

    编译生成PACKAGE后,安装到MID上,运行即是2+3=5

 

 

src\external\icebird\rootdir\root\init.ste.rc

src\system\core\rootdir\init.rc

 

Android init 启动过程分析 http://blog.csdn.net/zhenwenxian/archive/2009/11/12/4796205.aspx

 

MISC

init.rc\ ... “class_start default” means start default services.

 

中文翻译:

Actions

Actions是一系列命令的命名。Actions拥有一个触发器(trigger)用来决定action何时执行。当一个action在符合触发条件被执行时,如果它还没被加入到待执行队列中的话,则加入到队列最后。

 

队列中的action依次执行,action中的命令也依次执行。Init在执行命令的中间处理其它活动(设备创建/销毁,property设置,进程重启)

 

Actions表现形式为:

 

on

 

  

 

  

 

  

 

 

Services

Services是由init启动,在它们退出时重启(可选)Service表现形式为:

 

 

 

service [ ]*

  

  

   ...

 

 

Options

OptionsServices的修饰,它们影响init何时、如何运行service.

 

critical

     这是一个设备关键服务(device-critical service) .如果它在4分钟内退出超过4次,设备将重启并进入恢复模式。

 

 

disabled

     这个服务的级别将不会自动启动,它必须被依照服务名指定启动才可以启动。

 

 

setenv

     设置已启动的进程的环境变量的值

 

 

socket [ [ ] ]

     创建一个名为/dev/socket/unix domin socket,并传送它的fd到已启动的进程。必须为"dgram""stream".用户和组默认为0.

 

 

user

     在执行服务前改变用户名。当前默认为root.如果你的进程需要linux能力,你不能使用这个命令。你必须在还是root时请求能力,并下降到你需要的uid.

 

 

group [ ]*

     在执行服务前改变组。在第一个组后的组将设为进程附加组(通过setgroups()).当前默认为root.

 

 

oneshot

     在服务退出后不重启。

 

 

class

     service指定一个类别名。同样类名的所有的服务可以一起启动或停止。如果没有指定类别的服务默认为"default"类。

 

 

onrestart

       当服务重启时执行一个命令。

 

 

Triggers

     Triggers(触发器)是一个字符串,可以用来匹配某种类型的事件并执行一个action

 

 

boot

     这是当init开始后执行的第一个触发器(/init.conf被加载)

 

 

=

     property 被设为指定的值时触发。

 

 

device-added-

device-removed-

     当设备节点被添加或移除时触发。

 

 

service-exited-

     当指定的服务存在时触发

 

 

Commands

 

 

exec [ ]*

     Fork并执行一个程序().这将被block直到程序执行完毕。最好避免执行例如内建命令以外的程序,它可能会导致init被阻塞不动。

 

 

export

     设定全局环境变量的值,当这个命令执行后所有的进程都可以取得。

 

 

ifup

     使网络接口联机。

 

 

import

     解析一个init配置文件,扩展当前配置文件。

 

 

hostname

     设置主机名

 

 

chmod

     改变文件访问权限

 

 

chown

     改变文件所属和组

 

 

class_start

     当指定类别的服务没有运行,启动该类别所有的服务。

 

 

class_stop

     当指定类别的服务正在运行,停止该类别所有的服务。

 

 

domainname

     设置域名。

 

 

insmod

     加载该路径的模块

 

 

mkdir [mode] [owner] [group]

     创建一个目录,可选选项:mod,owner,group.如果没有指定,目录以755权限,ownerroot,grouproot创建.

 

 

mount

[ ]*

     尝试mount 到目录

. 可以用mtd@name格式以命名指定一个mtd块设备。包含"ro","rw","remount","noatime".

 

 

setkey

     暂时没有

 

 

setprop

     设置系统property 的值.

 

 

setrlimit

     设置resourcerlimit.

 

 

start

     启动一个没有运行的服务。

 

 

stop

     停止一个正在运行的服务。

 

 

symlink

     创建一个的符号链接到

 

 

sysclktz

     设置系统时区(GMT0)

trigger

     触发一个事件。用于调用其它action

 

 

write [ ]*

     打开的文件并写入一个或多个字符串。

 

 

Properties

Init会更新一些系统property以提供查看它正在干嘛。

 

 

 

init.action

     当前正在执行的action,如果没有则为""

 

 

init.command

     被执行的命令,如果没有则为""

 

 

init.svc.

     命名为的服务的状态("stopped", "running", "restarting")

 

的调试技术:

默认情况下,init执行的程序输出的信息和错误到/dev/null.为了debug,你可以通过Android程序logwrapper执行你的程序。这将复位向输出/错误输出到Android logging系统(通过logcat访问) 例如 service akmd /system/bin/logwrapper /sbin/akmd

 

reference:

图解 Android Handler 线程消息机制 http://dev.10086.cn/cmdn/supesite/?uid-49302-action-viewspace-itemid-472

Android Handler理解

http://blog.csdn.net/zhenyongyuan123/archive/2010/08/30/5850387.aspx

Handler presatation

src/frameworks/base/core/java/android/os/Handler.java

Others en:

http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/

Android线程间通信的Message机制 》再消化

http://blog.csdn.net/wukunting/archive/2010/07/22/5755961.aspx

http://blog.csdn.net/pilou5400/archive/2010/12/21/6089629.aspx

 

http://student.csdn.net/space.php?uid=46868&do=blog&id=20650

 

 

Handler : android提供的线程间通信机制——消息队列

发送消息并不会阻塞线程,而接收线程会阻塞线程,Message总是先进先出,依次被处理。

 

send message的两种方式:

1 Message msg = handler.obtainMessage();

msg.sendToTarget();

2 Message msg=new Message();

handler.sendMessage(msg);

 

向哪个Handler 发送消息,就必须在哪个handler.handlemessage 里面接收

 

当用户点击一个按钮时如果执行的是一个常耗时操作的话,处理不好会导致系统假死,用户体验很差,而Android则更进一步,如果任意一个 Acitivity没有响应5秒钟以上就会被强制关闭,因此我们需要另外起动一个线程来处理长耗时操作,而主线程则不受其影响,在耗时操作完结发送消息给 主线程,主线程再做相应处理。那么线程之间的消息传递和异步处理用的就是Handler

 

关于向modem发送CREG=0命令的问题:在wait_wakeup.sh中,当Erd屏幕睡眠时,会执行脚本中的循环部分,

wait_wakeup.sh

 

wake_unlock  进程解锁

wake_lock    进程加锁,不进入sleep

wait_for_fb_wake  开屏(cat /sys/power/wait_for_fb_wake 可以cat到字符串

wait_for_fb_sleep  关屏

 

烧写镜像后,第一次开机会调用wait_wakeup.sh会跑到循环中(因为wake_lockicebird radio-interface),以后再开机不会跑进循环中

eg:

echo " wait UI wake up "

        cp /sys/power/wait_for_fb_wake /dev/null

cp命令是阻塞式的吗???

 

内存回收

04-26 15:43:12.640: DEBUG/dalvikvm(1703): GC_FOR_MALLOC freed 13465 objects / 861176 bytes in 220ms

--》这是java虚拟机的内存回收,6715一般是>100ms级的
Nexus one
<100ms级的,CPU频率差好多,再加上还要虚拟一个cpurtk
U6715
慢的时候还是基本等比例的
这个是没法优化的,或者是很难的

 

reference: android sdk doc/Dev Guide/Developing/Tools

 

adb全称Android Debug Bridge

adb是客户端-服务器程序,由三个组件构成:

客户端:运行在开发主机上

服务器:同样运行于开发主机上,负责客户端与adb守护进程通信

adb daemon:在emulator或者android设备上

 

通过adb shell命令来运行adb客户端,如果发现adb服务器没有运行就将adb服务器启动。

 

发送adb命令:

adb [-d|-e|-s ]

refer to “Listing of adb Commands

adb bugreport 提取很多系统信息和日志,对分析问题很有帮助

adb jdwp //print a list of available JDWP processes on given device . Refer to DalvikVMDebugMonitor.html for more presentation

adb ppp [parm]... //i do not learn more.

 

adb shell commands:

Adb provides an ash shell, in device /system/bin/...

 

sqlite3 databases from a remote shell:

操作举例:关闭飞行模式

飞行模式状态的存储位置:

/data/data/com.android.providers.settings/databases/settings.db

# sqlite3 settings.db

sqlite> .table

sqlite> select * from system;

sqlite> update system set value = 0 where _id = 75;

 

UI/Application Exerciser Monkey

eg: $ adb shell monkey -v -p your.package.name 500

 

Other Shell Commands

查看adb所有的命令:adb shell ls /system/bin 或者 adb –help

dumpsys //dump each service

dumpstate //very useful in future

dmesg

start

stop

logcat //refer to “Listing of logcat Command Options”

 

android工具用来创建AVDs,同时可以创建android工程

 

 

 

 

“adb shell getprop”: we could check MCC and MNC and so on.

“adb shell setprop <> <> “ //usage: setprop

 

adb remount

adb kill $PID  //if PID is system_service , android would be reboot

adb -s emulator-5556 install helloWorld.apk

adb shell cat /sys/class/power_supply/battery/capacity   //display percent of battery left

adb shell cat /proc/camera //check camera info

adb shell cat /proc/kmsg  //check real-time trace kernel log

adb shell dmesg  //check trace kernel log from buffer or recoreded file

 

 

gdb server debug online for andorid system

 

adb shell

ash

gdbserver :777 --attach 1509

//1509 is pid of process you want to track

//777 is port to be created using gdbserver command

//this cmd is used to attach 1509 process to adbserver.

 

open another terminal:

prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb out/target/product/pnx6715_refd/symbols/system/bin/rild

 

(gdb) set solib-absolute-prefix /home1/work/60GB/android_eRD4_dv1.3/src/out/target/product/pnx6715_refd/symbols/

(gdb) set solib-search-path /home1/work/60GB/android_eRD4_dv1.3/src/out/target/product/pnx6715_refd/symbols/system/lib/

(gdb) target remote 192.168.2.1:777

Other reference

http://blog.csdn.net/gogofly_lee/archive/2008/12/31/3669483.aspx

看不到某些程序变量

work-around:

问题陈述:
GDB
跟到某个程序语句,
该语句里有变量var
使用print var命令查看var变量时,
GDB
提示:
No symbol "var" defined in current context.
而其他变量是可以查看的。

出现此问题的原因:
可能是编译时局部变量被优化到寄存器里了,
此时是无法在内存中查看变量的值的。

解决方法:
配置的时候加一个参数。
具体:
./configure --prefix=/home/target/totem --enable-debug --with-pgport=? (?>5432)
语句中加上CFLAGS=-O0       
/*
注意:上面语句中的“CFLAGS=-O0”,第一个是字母“O”,第二个是数字“0”*/
make clean
make
make install

参考:
参见“Debuging with GDB”8.2节:
Another possible efect of compiler optimizations is to optimize unused variables out of
existence, or assign variables to registers (as opposed to memory addresses). Depending
on the support for such cases o ered by the debug info format used by the compiler, gdb
might not be able to display values for such local variables. If that happens, gdb will print
a message like this:
No symbol "foo" in current context.
To solve such problems, either recompile without optimizations, or use a di erent debug
info format, if the compiler supports several such formats. For example, gcc, the gnu
C/C++ compiler usually supports the ‘-gstabs+’ option. ‘-gstabs+’ produces debug info
in a format that is superior to formats such as COFF. You may be able to use DWARF
2 (‘-gdwarf-2’), which is also an e ective form for debug info.

 

要进入开发设置页面,在模拟器中转到Dev Tools > Development Settings。在该设置页面有以下选项:

  • Debug app:选择要调试的程序。你不需要设定其关联至调试器,但是设定这个值有两个效果:
    • 在调试的时候,如果你在一个断点处暂停了过长的时间,这个设定会防止Android抛出一个错误
    • 这个设定使你可以选择等待调试器选项,使程序只有在调试器关联上之后才启动
  • Wait for Debugger:阻塞所选的程序的加载直到有调试器关联上,这样你就可以在 onCreate()中设置断点,这对于调试一个Activity的启动进程是非常重要的。当你对该选项进行了更改,任何正在运行的程序的实例都会被终 止。你只有在上面的选项中选择了一个调试程序才能够选中该选项。你也可以在代码中添加来实现同样的功能。
  • Immediately destroy activities:告诉系统一旦一个activity停止了就销毁该activity(例如当Android释放内存的时候)。这对于测试代码/是非常有用的,否则会比较困难。如果你的程序没有保存状态,那么选择这个选项很可能会引发很多问题。
  • Show screen updates:对于任何正在被重绘的screen sections都会在其上闪现一个粉红色的矩形。这对于发现不必要的screen绘制是很有必要的。
  • Show CPU usage:在屏幕上方显示CPU信息,显示有多少CPU资源正在被使用。上方红色条显示总的CPU使用率,它下方绿色的条显示CPU用在compositing the screen上的时间。注意:在没有重启模拟器之前,一旦你开启了该功能就不能关闭。
  • Show screen FPS:显示当前的帧率。这对于查看游戏达到的总的帧率是非常有用的。注意:在没有重启模拟器之前,一旦你开启了该功能就不能关闭。
  • Show background:当没有activity screens可见时,显示一个背景模式。一般是不会出现的,仅仅在Debug的时候会出现。

 

adb shell am

 

模拟打电话或者发短信

利用telnet命令,如telnet localhost 5554连接上device/emulator

然后输入gsm call 15555218135 sms send 15555218135 Hello,this is a Message.

Android cutils.Log

for example: java

1. package com.jackiez.mytest.util;

2.  

3. import android.util.Log;

4.  

5. public class LogUtil {

6. //锁,是否关闭Log日志输出

7. public static boolean LogOFF=false;

8. //5种类型

9. //调试日志类型

10. public static final int DEBUG=111;

11. //错误日志类型

12. public static final int ERROR =112;

13. //信息日志类型

14. public static final int INFO =113;

15. //详细信息日志类型

16. public static final int VERBOSE =114;

17. //警告日志类型

18. public static final int WARN =115;

19. //显示,打印日志

20. public static void LogShow(String Tag,String Message,int Style){

21. // TODO Auto-generated constructor stub

22. if(!LogOFF)

23. switch (Style) {

24. case DEBUG:{

25. Log.d(Tag, Message);

26. }

27. break;

28. case ERROR:{

29. Log.e(Tag, Message);

30. }

31. break;

32. case INFO:{

33. Log.i(Tag, Message);

34. }

35. break;

36. case VERBOSE:{

37. Log.v(Tag, Message);

38. }

39. break;

40. case WARN:{

41. Log.w(Tag, Message);

42. }

43. break;

44. default:

45. break;

46. }

47. }

48. }

java

通过堆栈内容,查看函数调用关系。

1. 查看当前堆栈

1) 功能:在程序中加入代码,使可以在logcat中看到打印出的当前函数调用关系

2) 方法:
new Exception(“print trace”).printStackTrace();

例如logcat中的堆栈信息如下:

1.    02-05 16:50:13.597 W/System.err( 2183): java.lang.Exception: print trace

2. 02-05 16:50:13.597 W/System.err( 2183): at com.android.internal.telephony.RIL.dial(RIL.java:815)

3. 02-05 16:50:13.597 W/System.err( 2183): at com.android.internal.telephony.gsm.GsmCallTracker.dial(GsmCallTracker.java:216)

4. 02-05 16:50:13.597 W/System.err( 2183): at com.android.internal.telephony.gsm.GsmCallTracker.dial(GsmCallTracker.java:228)

5. 02-05 16:50:13.597 W/System.err( 2183): at com.android.internal.telephony.gsm.GSMPhone.dial(GSMPhone.java:730)

6. 02-05 16:50:13.597 W/System.err( 2183): at com.android.internal.telephony.PhoneProxy.dial(PhoneProxy.java:423)

7. 02-05 16:50:13.607 W/System.err( 2183): at com.android.phone.PhoneUtils.placeCall(PhoneUtils.java:507)

8. 02-05 16:50:13.607 W/System.err( 2183): at com.android.phone.InCallScreen.placeCall(InCallScreen.java:2579)

9. 02-05 16:50:13.607 W/System.err( 2183): at com.android.phone.InCallScreen.internalResolveIntent(InCallScreen.java:1169)

10. 02-05 16:50:13.607 W/System.err( 2183):    at com.android.phone.InCallScreen.onCreate(InCallScreen.java:622)

11. 02-05 16:50:13.607 W/System.err( 2183):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)

12. 02-05 16:50:13.607 W/System.err( 2183):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

13. 02-05 16:50:13.607 W/System.err( 2183):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)

14. 02-05 16:50:13.607 W/System.err( 2183):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)

15. 02-05 16:50:13.607 W/System.err( 2183):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)

16. 02-05 16:50:13.607 W/System.err( 2183):    at android.os.Handler.dispatchMessage(Handler.java:99)

17. 02-05 16:50:13.617 W/System.err( 2183):    at android.os.Looper.loop(Looper.java:123)

18. 02-05 16:50:13.617 W/System.err( 2183):    at android.app.ActivityThread.main(ActivityThread.java:4627)

19. 02-05 16:50:13.617 W/System.err( 2183):    at java.lang.reflect.Method.invokeNative(Native Method)

20. 02-05 16:50:13.617 W/System.err( 2183):    at java.lang.reflect.Method.invoke(Method.java:521)

21. 02-05 16:50:13.617 W/System.err( 2183):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)

22. 02-05 16:50:13.627 W/System.err( 2183):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)

23. 02-05 16:50:13.627 W/System.err( 2183):    at dalvik.system.NativeStart.main(Native Method)

 

java

MethodTracing

1) 功能:用于热点分析和性能优化,分析每个函数占用的CPU时间,调用次数,函数调用关系等

2) 方法:

a) 在程序代码中加入追踪开关

1.    import android.os.Debug;     

2. ……     

3. android.os.Debug.startMethodTracing(“/data/tmp/test”); // 先建/data/tmp目录     

//NOTE: /data/tmp should exist

4. …… // 被追踪的程序段    

5.  android.os.Debug.stopMethodTracing();  

b) 编译,运行后,设备端生成/data/tmp/test.trace文件

c) trace文件复制到PC

1.         $ adb pull /data/tmp/test.trace ./ 

d) 使用android自带工具分析trace文件

1.         $ $ANDROID_SRC/out/host/linux-x86/bin/traceview test.trace  2.         NOTE: sometimes we should execute “export ANDROID_SWT=out/target/product/pnx6715_refd/system/framework/”

此时可看到各个函数被调用的次数CPU占用率等信息

e) 使用android自带工具分析生成调用关系类图

1.         $ apt-get install graphviz # 安装图片相关软件   2.         $ANDROID_SRC/out/host/linux-x86/bin/dmtracedump -g test.png test.trace  

此时目录下生成类图test.png

3) 注意
trace
文件生成与libdvm模块DEBUG版本相冲突,所以此方法只适用于对非DEBUG版本模拟器的调试,否则在分析trace文件时会报错

JC: have not done

1) 功能:
用于java层面的内存分析,显示详细的内存占用信息,指出可疑的内存泄漏对象

2) 方法:

a) 在代码中加入dump动作

1.         import android.os.Debug;    2.         import java.io.IOException;     3.         ……     4.          try {    5.         android.os.Debug.dumpHprofData(“/data/tmp/input.hprof”); // 先建/data/tmp目录     6.          } catch (IOException ioe) {     7.          } 

b) hprof文件复制到PC

1.         $ adb pull /data/tmp/input.hprof ./ 

c) 使用命令hprof-convhprof转成MAT识别的标准的hprof

1.         $ $ANDROID_SRC/out/host/linux-x86/bin/hprof-conv input.hprof output.hprof 

d) 使用MAT工具看hprof信息

下载MAT工具:http://www.eclipse.org/mat/downloads.php

用工具打开output.hprof

3) 注意:此工具只能显示java层面的,而不能显示C层的内存占用信息

JC: have not known what’s exactly it?

1) 功能
每隔N毫秒对当前正在运行的函数取样,并输出到log

2) 在代码中加入取样设定

1.         import dalvik.system.SamplingProfiler     2.         ……    3.         SamplingProfile sp = SamplingProfiler.getInstance();     4.         sp.start(n); // n为设定每秒采样次数   5.          sp.logSnapshot(sp.snapshot());     6.          ……     7.         sp.shutDown(); 

它会启一个线程监测,在logcat中打印信息

用发系统信号的方式取当前堆栈情况和内存信息

1) 原理
dalvik
虚拟机对SIGQUITSIGUSR1信号进行处理(dalvik/vm/SignalCatcher.c),分别完成取当前堆栈和取当前内存情况的功能

2) 用法

a) $ chmod 777 /data/anr # anr目录权限设为可写
$ rm /data/anr/traces.txt #
删除之前的trace信息
$ ps #
找到进程号
$ kill -3
进程号 # 发送SIGQUIT信号给该进程,此时生成trace信息
$ cat /data/anr/traces.txt
功能实现:遍历thread list(dalvik/vm/Thread.c:dvmDumpAllThreadEx()),并打印当前函数调用关系(dalvik/vm/interp/Stack.c:dumpFrames())

NOTEJCI failed to do it on android 2.2

b) $ chmod 777 /data/misc -R
$ ps #
找到进程号
$ kill -10
进程号 # 发送SIGUSR1信事信号给该进程,此时生成hprof信息
$ ls /data/misc/*.hprof
此时生成hprf文件,如何使用此文件,见第二部分(HProf)
注意:hprof文件都很大,注意用完马上删除,以免占满存储器

NOTEJCI failed to do it on android 2.2

及原理

1) android.util.Log利用println的标准java输出词句,并加前缀I/V/D….

2) dalvik利用管道加线程的方式,先利用dup2stdoutstderr重定向到管理中 (vm/StdioConverter.c:dvmstdioConverterStartup),然后再启动一个线程从管道另一端读出内容 (dalvik/vm/StdioConverter.c:stdioconverterThreadStart()),使用LOG公共工具 (system/core/liblog/logd_write.c: __android_log_print())输出到/dev/log/*中去

3) logcat通过加不同参数看/dev/log/下的不同输入信息

1.         # logcat -b main 显示主缓冲区中的信息   2.         # logcat -b radio 显示无线缓冲区中的信息   3.         # logcat -b events 显示事件缓冲区中的信息  及原理

1) 虚拟机(设备端)在启动时加载了Agent JDWP 从而具备了调试功能。在调试器端(PC端)通过JDWP协议与设备连接,通过发送命令来获取的状态和控制Java程序的执行。JDWP 是通过命令(command)和回复(reply)进行通信的。

2) JDK 中调试工具 jdb 就是一个调试器,DDMS也提供调试器与设备相连。

3) dalvikJDWP提供了两种连接方式:tcp方式和adb方式,tcp方式可以手工指定端口,adb方式自动设定为8700端口,通常使用DDMS调试就是通过adb方式

1) monkey是一个android自带的命令行工具。它向系统发送伪随机的用户事件流,实现对正在开发的应用程序进行压力测试。

2) 方法
在设备端打开setting界面
$ adb shell
# monkey -p com.android.settings -v 500
此时可以看到界面不断被切换

具体见android.os.Debug中提供的工具

1) 取毫微秒级的时间,用于计算时间
threadCpuTimeNanos()

2) 统计两点间的内存分配情况

1.         startAllocCounting()   2.         stopAllocCounting()   3.         getGlobalAllocCount()   4.         get….. 

3) 打印当前已loadclass
getLoadedClassCount()
printLoadedClasses()
它需要打开NDEBUG功能才能打开system/core/Log功能

结构分析

(1)dumpstate

MEMORY INFO

获取该log:读取文件/proc/meminfo

系统内存使用状态

CPU INFO

获取该log:执行/system/bin/top -n 1 -d 1 -m 30 -t

系统CPU使用状态

PROCRANK

获取该log:执行/system/bin/procrank

执行/system/xbin/procrank后输出的结果,查看一些内存使用状态

VIRTUAL MEMORY STATS

获取该log:读取文件/proc/vmstat

虚拟内存分配情况

vmalloc申请的内存则位于vmalloc_startvmalloc_end之间,与物理地址没有简单的转换关系,虽然在逻辑上它们也是连续的,但是在物理上它们不要求连续。

VMALLOC INFO

获取该log:读取文件/proc/vmallocinfo

虚拟内存分配情况

SLAB INFO

获取该log:读取文件/proc/slabinfo

SLAB是一种内存分配器.这里输出该分配器的一些信息

ZONEINFO

获取该log:读取文件/proc/zoneinfo

zone info

SYSTEM LOG(需要着重分析)

获取该log:执行/system/bin/logcat -v time -d *:v

会输出在程序中输出的Log,用于分析系统的当前状态

VM TRACES

获取该log:读取文件/data/anr/traces.txt

因为每个程序都是在各自的VM中运行的,这个Log是现实各自VM的一些traces

EVENT LOG TAGS

获取该log:读取文件/etc/event-log-tags

EVENT LOG

获取该log:执行/system/bin/logcat -b events -v time -d *:v

输出一些Eventlog

RADIO LOG

获取该log:执行/system/bin/logcat -b radio -v time -d *:v

显示一些无线设备的链接状态,GSMPHONE,STK(Satellite Tool Kit)...

NETWORK STATE

获取该log:执行/system/bin/netcfg (得到网络链接状态)

获取该log:读取文件/proc/net/route (得到路由状态)

显示网络链接和路由

SYSTEM PROPERTIES

获取该log:参考代码实现

显示一些系统属性,Version,Services,network...

KERNEL LOG

获取该log:执行/system/bin/dmesg

显示Android内核输出的Log

KERNEL WAKELOCKS

获取该log:读取文件/proc/wakelocks

内核对一些程式和服务唤醒和休眠的一些记录

KERNEL CPUFREQ

(Linux kernel CPUfreq subsystem) Clock scaling allows you to change the clock speed of the CPUs on the fly.

This is a nice method to save battery power, because the lower the clock speed is, the less power the CPU consumes.

PROCESSES

获取该log:执行ps -P

显示当前进程

PROCESSES AND THREADS

获取该log:执行ps -t -p -P

显示当前进程和线程

LIBRANK

获取该log:执行/system/xbin/librank

剔除不必要的library

BINDER FAILED TRANSACTION LOG

获取该log:读取文件/proc/binder/failed_transaction_log

BINDER TRANSACTION LOG

获取该log:读取文件/proc/binder/transaction_log

BINDER TRANSACTIONS

获取该log:读取文件/proc/binder/transactions

BINDER STATS

获取该log:读取文件/proc/binder/stats

BINDER PROCESS STATE

获取该log:读取文件/proc/binder/proc/*

bind相关的一些状态

FILESYSTEMS

获取该log:执行/system/bin/df

主要文件的一些容量使用状态(cache,sqlite,dev...)

PACKAGE SETTINGS

获取该log:读取文件/data/system/packages.xml

系统中package的一些状态(访问权限,路径...),类似Windows里面的一些lnk文件吧.

PACKAGE UID ERRORS

获取该log:读取文件/data/system/uiderrors.txt

错误信息

KERNEL LAST KMSG LOG

最新kernel message log

LAST RADIO LOG

最新radio log

KERNEL PANIC CONSOLE LOG

KERNEL PANIC THREADS LOG

控制台/线程的一些错误信息log

BACKLIGHTS

获取该log:获取LCD brightness/sys/class/leds/lcd-backlight/brightness

获取该log:获取Button brightness/sys/class/leds/button-backlight/brightness

获取该log:获取Keyboard brightness/sys/class/leds/keyboard-backlight/brightness

获取该log:获取ALS mode/sys/class/leds/lcd-backlight/als

获取该log:获取LCD driver registers/sys/class/leds/lcd-backlight/registers

获取相关亮度的一些信息

(2)build.prop

VERSION INFO输出下列信息
当前时间
当前内核版本:可以读取文件(/proc/version)获得
显示当前命令:可以读取文件夹(/proc/cmdline)获得
显示系统build的一些属性:可以读取文件(/system/build.prop)获得
输出系统一些属性
gsm.version.ril-impl
gsm.version.baseband
gsm.imei
gsm.sim.operator.numeric
gsm.operator.alpha

(3)dumpsys

执行/system/bin/dumpsys后可以获得这个log.
经常会发现该log输出不完整,因为代码里面要求该工具最多只执行60ms,可能会导致log无法完全输出来.
可以通过修改时间参数来保证log完全输出.
信息:
Currently running services
DUMP OF SERVICE services-name(running)

Log Code Analysis

Site: .\frameworks\base\cmds\dumpstate\

相关Log程序的代码可以从上面目录获取

Log Analysis Experience

分析步骤

1.查看一些版本信息
确认问题的系统环境
2.
查看CPU/MEMORY的使用状况
看是否有内存耗尽,CPU繁忙这样的背景情况出现.
3.
分析traces
因为traces是系统出错以后输出的一些线程堆栈信息,可以很快定位到问题出在哪里.
4.
分析SYSTEM LOG
系统Log详细输出各种log,可以找出相关log进行逐一分析

实例分析

下面分析我写的一个测试例子,OnCreate做一个死循环,这样主线程会被锁住,在按下硬件的Back之后会出现ANR的错误.
traces中发现该程序的堆栈信息如下:

----- pid 20597 at 2010-03-15 01:29:53 -----
Cmd line: com.android.test
DALVIK THREADS:
"main" prio=5 tid=3 TIMED_WAIT
| group="main" sCount=1 dsCount=0 s=N obj=0x2aac6240 self=0xbda8
| sysTid=20597 nice=0 sched=0/0 cgrp=default handle=1877232296
at java.lang.VMThread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:1306)
at java.lang.Thread.sleep(Thread.java:1286)
at android.os.SystemClock.sleep(SystemClock.java:114)
at com.android.test.main.onCreate(main.java:20)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$2200(ActivityThread.java:119)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
"Binder Thread #2" prio=5 tid=11 NATIVE
| group="main" sCount=1 dsCount=0 s=N obj=0x2fb7c260 self=0x143860
| sysTid=20601 nice=0 sched=0/0 cgrp=default handle=1211376
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #1" prio=5 tid=9 NATIVE
| group="main" sCount=1 dsCount=0 s=N obj=0x2fb7c1a0 self=0x14c980
| sysTid=20600 nice=0 sched=0/0 cgrp=default handle=1207920
at dalvik.system.NativeStart.run(Native Method)
"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=N obj=0x2fb7a1e8 self=0x126cc0
| sysTid=20599 nice=0 sched=0/0 cgrp=default handle=1269048
at dalvik.system.NativeStart.run(Native Method)
"HeapWorker" daemon prio=5 tid=5 VMWAIT
| group="system" sCount=1 dsCount=0 s=N obj=0x2e31daf0 self=0x135c08
| sysTid=20598 nice=0 sched=0/0 cgrp=default handle=1268528
at dalvik.system.NativeStart.run(Native Method)
----- end 20597 -----

该文件的堆栈结构从下往上进行分析
(1)
栈底at dalvik.system.NativeStart.run(Native Method)
系统为当前的task(应用程式)启动一个专用的虚拟机
(2) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
Activity Services
是在后台负责管理Activity,它此时将测试例子的Activity启动起来了
(3)at com.android.test.main.onCreate(main.java:20)
启动测试程序
(4)
栈顶at java.lang.VMThread.sleep(Native Method)
线程被sleep掉了,所以无法响应用户,出现ANR错误.

上面是对一个非常简单的问题的分析.

如果遇到比较复杂的问题还需要详细分析SYSTEM LOG.
1.
比如网络异常,要通过SYSTEM LOG里面输出的网络链接信息来判断网络状态
2.
数据传输,网络链接等耗时的操作需要分析SYSTEM LOG里面ActivityManager的响应时间
3...

 

.so库常用工具

readelf

显示目标ELF文件的信息,比如信赖库,头信息,段信息等。

addr2line

用户进程崩溃时内核会记录一些基本的调试信息,如果进程执行的ELF文件包含调试符号,就可以通过addr2line找到源文件中哪一行出问题。

nm

列出目标文件的符号清单,当没有输入文件名时,默认为a.out

size

显示一个目标文件或者链接库文件中的目标文件的各个段的大小,当没有输入文件名时,默认为a.out

objdump

它主要是查看ELF目标文件的内容信息

ranlib

对静态库的符号索引表进行更新

strip

通过除去绑定程序和符号调试程序使用的信息,减少扩展公共对象文件格式(XCOFF)的对象文件的大小

gprof

可以显示程序运行的“flat profile”,包括每个函数的调用次数,每个函数消耗的处理器时间。也可以显示调用图,包括函数的调用关系,每个函数调用花费了多少时间。

strings

列出文件中的可打印字符串

gprof使用介绍

http://hi.baidu.com/juventus/blog/item/312dd42a0faf169b033bf6ff.html

strip 命令

http://blog.csdn.net/aaronychen/archive/2008/03/18/2193735.aspx

ranlib的用法

http://blog.csdn.net/cmiaomiaozoo/archive/2009/10/28/4738910.aspx

linux 下使用 objdump 反汇编

http://blog.csdn.net/nwf5d/archive/2009/08/07/4423591.aspx

readelf命令

http://blog.csdn.net/zyp2671/archive/2010/04/02/5443770.aspx

nm命令介绍

http://blog.csdn.net/breezef/archive/2006/08/12/1054475.aspx

size 命令的用法

http://blog.csdn.net/clozxy/archive/2010/06/02/5641785.aspx

命令的使用

实例调试分析:

I/DEBUG   ( 3411): pid: 3436, tid: 3475  >>> system_server <<<
I/DEBUG   ( 3411): signal 11 (SIGSEGV), fault addr 00000000

I/DEBUG   ( 3411):          #00  pc 00000000  
I/DEBUG   ( 3411):          #01  pc 000527e8  /system/lib/libandroid_runtime.so
I/DEBUG   ( 3411):          #02  pc 0000f1f4  /system/lib/libdvm.so

I/DEBUG   ( 3411):
I/DEBUG   ( 3411): code around lr:
I/DEBUG   ( 3411): ad3527d8 69e19806 694c9000 1c191c10 9b059a04
I/DEBUG   ( 3411): ad3527e8 b00247a0 46c0bd10 00017868 00006728
I/DEBUG   ( 3411): ad3527f8 4c0fb570 447c4d0f 6b2e1965 d1112e00
I/DEBUG   ( 3411):
I/DEBUG   ( 3411): stack:
I/DEBUG   ( 3411):     490ecd28  00000013  
I/DEBUG   ( 3411):     490ecd2c  ad05f661  /system/lib/libdvm.so
I/DEBUG   ( 3411):     490ecd30  410c2aec  /dalvik-LinearAlloc

。。。。。。。

src/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-addr2line -e out/target/product/i850/symbols /system/lib/libandroid_runtime.so 000527e8

输出:frameworks/base/core/jni/android_location_GpsLocationProvider.cpp:397

Linux系统中的Bug

User Debug 日志记录

调试一个崩溃的程序的第一步是弄清哪里出了错。zSeries 上的Linux内核具有这样一个内置特性,它在用户进程崩溃时记录一些基本的调试信息。要启用这个特性,请以 root 用户身份执行如下命令:

echo 1 >> /proc/sys/kernel/userprocess_debug

当某个进程崩溃时,日志文件(/var/log/messages)中就会给出附加的信息,包括程序终止原因、故障地址,以及包含程序状态字(PSW)、通用寄存器和访问寄存器的简要寄存器转储。

Mar 31 11:34:28 l02 kernel: User process fault: interruption code 0x10

Mar 31 11:34:28 l02 kernel: failing address: 0

Mar 31 11:34:28 l02 kernel: CPU:    1

Mar 31 11:34:28 l02 kernel: Process simple (pid: 30122, stackpage=05889000)

Mar 31 11:34:28 l02 kernel:

Mar 31 11:34:28 l02 kernel: User PSW:    070dc000 c00ab738

Mar 31 11:34:28 l02 kernel: task: 05888000 ksp: 05889f08 pt_regs: 05889f68

Mar 31 11:34:28 l02 kernel: User GPRS:

Mar 31 11:34:28 l02 kernel: 00000000  004019a0  004019a0  00000000

Mar 31 11:34:28 l02 kernel: 00000003  c00ab732  004008f8  00400338

Mar 31 11:34:28 l02 kernel: 40018ffc  0040061c  40018e34  7ffff800

Mar 31 11:34:28 l02 kernel: 00400434  80400624  8040066e  7ffff800

Mar 31 11:34:28 l02 kernel: User ACRS:

Mar 31 11:34:28 l02 kernel: 00000000  00000000  00000000  00000000

Mar 31 11:34:28 l02 kernel: 00000001  00000000  00000000  00000000

Mar 31 11:34:28 l02 kernel: 00000000  00000000  00000000  00000000

Mar 31 11:34:28 l02 kernel: 00000000  00000000  00000000  00000000

Mar 31 11:34:28 l02 kernel: User Code:

Mar 31 11:34:28 l02 kernel: 44 40 50 00 07 fe a7 4a 00 01 18 54 18 43 18 35

a8 24 00 00

1

1 表明程序(名为“simple”)以一个程序中断代码 0x10 终止(操作系统原理表明这是一个段转换错误),而故障地址为 0。毫无疑问,有人使用了空指针。现在我们知道发生了什么,下面需要弄清它发生在何处。

基本的诊断

User Debug日志条目所提供的信息可用于确定程序的崩溃位置。一些可用的工具可帮助解决您可能会遇到的各种程序终止问题。我们将在本文中逐步介绍那些工具。

首 先,让我们检查一下该日志条目中的用户 PSW。该 PSW 包含指令地址、状态码以及关于机器状态的其他信息。眼下,我们仅关心指令地址(第33至第63位)。为简化起见,让我们假设用户PSW 070dc000 80400618。记住,我们是在考察一个 ESA/39031 位寻址)PSW。第32位不是指令地址的一部分,它是指示 31 位寻址模式的标志,但是在研究 PSW 值时必须处理它。为了获得实际的指令指针,可把PSW的第二个字减去 0x80000000。结果是一个指令地址 0x400618。为了定位代码,您需要可执行文件中的一些信息。首先使用readelf来打印一些程序头信息。

Elf file type is EXEC (Executable file)

Entry point 0x400474

There are 6 program headers, starting at offset 52

 

Program Headers:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align

  PHDR           0x000034 0x00400034 0x00400034 0x000c0 0x000c0 R E 0x4

  INTERP         0x0000f4 0x004000f4 0x004000f4 0x0000d 0x0000d R   0x1

      [Requesting program interpreter: /lib/ld.so.1]

  LOAD           0x000000 0x00400000 0x00400000 0x00990 0x00990 R E 0x1000

  LOAD           0x000990 0x00401990 0x00401990 0x000fc 0x00114 RW  0x1000

  DYNAMIC        0x0009ac 0x004019ac 0x004019ac 0x000a0 0x000a0 RW  0x4

  NOTE           0x000104 0x00400104 0x00400104 0x00020 0x00020 R   0x4

 

 Section to Segment mapping:

  Segment Sections...

   00   

   01     .interp

   02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version

          .gnu.version_r .rela.got .rela.plt .init .plt .text .fini .rodata

   03     .data .eh_frame .dynamic .ctors .dtors .got .bss

   04     .dynamic

   05     .note.ABI-tag

2

2 显示了readelf -l simple的结果(记住“simple”是我们的测试程序的名称)。在Program Headers部分,第一个 LOAD 行提供了关于程序从哪里加载的信息。在 Flg 列,该段被标记为 R(read)E(executable)VirtAddr是程序开始加载的地址。MemSiz是正在被加载到这个段中的代码长度。把它加到 VirtAddr上,这个程序的基本地址范围就是0x400000-0x400990。程序发生崩溃的指令地址为0x400618,在程序的加载范围之 内。现在我们知道了问题直接发生在代码中。

如果可执行文件包括调试符号,那么确定哪一行代码导致了问题是可以做到的。对该地址和可执行文件使用addr2line 程序,如下所示:

addr2line -e simple 0x400618

将返回:

/home/devuser/simple.c:34

要研究该问题,可以检查第 34 行。

对 于图1中原始的程序崩溃,PSW 070dc000 c00ab738。要获得指令地址,可减去0x80000000。结果为0x400ab738。这个地址并不准确地落在我们的小程序之内。那么,它是什么 呢?是来自共享库的代码。如果对可执行文件运行ldd 命令(ldd simple),将会返回程序运行所需的共享对象的列表,以及该库在那里可用的地址。

libc.so.6 => /lib/libc.so.6 (0x40021000)

/lib/ld.so.1 => /lib/ld.so.1 (0x40000000)

该指令地址对应于加载libc.so.6的地址。在我们的简单测试案例中,只需要两个共享对象。其他应用程序可能需要更多共享对象,这使得ldd的输出更加复杂。我们将以perl作为例子。 输入:

ldd /usr/bin/perl

将得到:

libnsl.so.1 => /lib/libnsl.so.1 (0x40021000)

libdl.so.2 => /lib/libdl.so.2 (0x40039000)

libm.so.6 => /lib/libm.so.6 (0x4003d000)

libc.so.6 => /lib/libc.so.6 (0x40064000)

libcrypt.so.1 => /lib/libcrypt.so.1 (0x4018f000)

/lib/ld.so.1 => /lib/ld.so.1 (0x40000000)

所需要的一切都在那里了,但是我发现对于这个进程,下面的内容读起来更快一点:

ldd /usr/bin/perl | awk ‘{print? $4 “ “ $3 }’ | sort

(0x40000000) /lib/ld.so.1

(0x40021000) /lib/libnsl.so.1

(0x40039000) /lib/libdl.so.2

(0x4003d000) /lib/libm.so.6

(0x40064000) /lib/libc.so.6

(0x4018f000) /lib/libcrypt.so.1

现 在我们来确定崩溃发生在libc中的何处。假设libc.so.6的加载地址是0x40021000,从指令地址 0x400ab738减去它,结果为0x8a738。这是进入libc.so.6 的偏移。使用nm命令,从libc.so.6转储符号,然后尝试确定该地址位于哪个函数中。对于libc.so.6nm将生成7,000多行输出。通过 对计算得出的偏移部分执行 grep(正则表达式查找程序)可以削减必须检查的数据量。输入:

nm /lib/libc.so.6 | sort | grep 0008a

将返回 66 行,在该输出的中间,我们会发现:

0008a6fc T memcpy

0008a754 t _wordcopy_fwd_aligned

该 偏移落在memcpy中的某个位置。在此例中,一个空指针被当作目标地址传递给了memcpy。我们在何处调用的memcpy呢?问得好。我们可以通过检 查输出在日志文件中的寄存器转储来确定目标区域。寄存器14包含执行某个函数调用时的返回地址。根据图1R140x8040066e,它在截去高位之 后产生一个地址 0x40066e。这个地址落在我们的程序范围之内,因此可以运行addr2line来确定该地址在何处。输入:

addr2line -e simple 0x40066e

将返回:

/home/devuser/simple.c:36

这是我们调用memcpy之后的那一行。关于addr2line的一点补充:如果可执行文件中没有包括调试符号,您将获得??:0 作为响应。

android java framework and app

android2.2 framework/base/telephony/java为例子:

打开eclipse,新建工程,java project

  create project from existing source

       directroy locates in framework/base/telephony/java

       press finish button.

 -> 进入ddms视图,连接设备,单击需要调试的进程

   

点击Run->Debug Configuration->Remote Java Application->New,设置如下:

sourcecode里设置断点,并在ddms视图中点击下图红框按钮开始调试:

切换到debug试图进行调试:

至于app的调试同framework类似,

例如把phone应用添加至上面建立好的framework/base/telephony/java工程中,只需要在com.android包中添加phone类的源代码即可,如下:

 

issue: read-only file system.

workaround 1: adb shell mount -o remount,rw -t yaffs2 /dev/block/mtdblock0 /system

workaround 2: adb root && adb remount

 

issue: out of memory.

workaround: emulator -avd youravdname -partition-size 128

ANRApplication Not Responding

1) 什么引发了ANR
Android里,应用程序的响应性是由Activity ManagerWindow Manager系统服务监视的。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR
1.
主线程 (“事件处理线程” / “UI线程”) 5秒内没有响应输入事件
2. BroadcastReceiver
10秒内没有执行完毕

2) 如何避免ANR

Android应用程序通常是运行在一个单独的线程(例如,main)里。这意味着你的应用程序所做的事情如果在主线程里占用了太长的时间的话,就会引发ANR对话框,因为你的应用程序并没有给自己机会来处理输入事件或者Intent广播。

因此,运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate() onResume())里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者以数据 库操作为例,通过异步请求的方式)来完成。然而,不是说你的主线程阻塞在那里等待子线程的完成——也不是调用Thread.wait()或是 Thread.sleep()。替代的方法是,主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将 能保证你的主线程保持对输入的响应性并能避免由于5秒输入事件的超时引发的ANR对话框。这种做法应该在其它显示UI的线程里效仿,因为它们都受相同的超 时影响。

IntentReceiver执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的工作如保存设定或者注册一个Notification 和在主线程里调用的其它方法一样,应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为 BroadcastReceiver的生命周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个 Service。顺便提及一句,你也应该避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。

 

other better suggestion of avoid ANR:

1. 单独开工作者线程,通过独立的Thread或使用类似AsyncTask的方式来处理耗时的内容。

2. 耗时的操作尽量分段处理,使用类似状态机的方法,类似Symbian的活动对象将一个复杂的事情,分段执行。

3. UI线程中不要处理过多的内容,比如将一个5MB的文本,让TextViewsetText,要知道这种UI操作,没有什么好方法去解决的,所以Android123提示,遇到UI中需要执行复杂的操作,可以参考上面2提到的分段处理方式。

 

 

3) 增强响应灵敏性

一般来说,在应用程序里,100200ms是用户能感知阻滞的时间阈值。因此,这里有一些额外的技巧来避免ANR,并有助于让你的应用程序看起来有响应性。

如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBarProgressDialog对这种情况来说很有用)。
特别是游戏,在子线程里做移动的计算。
如果你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个Splash Screen或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。

 

        当某个应用程序发生意外的错误,Android系统会弹出一个视窗,提示应用程序 XX 意外停止,并給出強行关闭(Force closebuttton,用以关闭出错的程序。这种情形就是crash状况的force close

Force close还有一种ANRApplication not responding)的情形,系統弹出视窗的提示內容和button都于crash不同,请注意区分。


Open Logcat as follow :

 

        Open DUT

        Press *#*#324#*#*

        Check ‘Logcat launch’

        Press ‘OK’ and exit

        打开Logcat后,SD卡中会自动生成

    ‘Log’文件夹,main log会保存在其中。

发生force close_crash 时,main log中就会先打印出‘FATAL EXCEPTION’这样的字符串

 

 

Android四个重要组件:

Activity:构造界面

Intent:应用程序之间传递数据

Service:不可见的后台运行的程序,为应用程序提供服务

ContentProvider:存放数据,为应用程序之间共享数据

 

容纳多个控件的容器

 

创建activity步骤:

1 创建类,复写oncreate方法,设置布局文件

2 创建layout布局文件

3 注册activityAndroidManifest.xml

 

实例:

//Activity02切换到OtherActivity

Intent intent = new Intent();

intent.setClass(Activity02.this, OtherActivity.class);

Activity02.this.startActivity(intent) : 启动一个activity

//启动的activity不一定在同一个应用程序中

//也就是说intent可以在不同程序中传递数据

 

Parcel的用法:

android Parcel 的使用,他是一个存储基本数据类型和引用数据类型的容器,在andorid 中通过IBinder来绑定数据在进程间传递数据。

 

Parcel parcel = Parcel.obtain();// 获取一个Parcel 对象
下面就可以对其进行方法进行操作了,createXXX(),wirteXXX(),readXXX(),
其中dataPosition(),返回当前Parcel 当前对象存储数据的偏移量,而setDataPosition(),设置当前Parcel 对象的偏移量,方便读取parcel 中的数据

 

 

 

Parcel CPP用法:

 

Android中的Parcel类实现代码包括Parcel.hParcel.cppParcel类似一个一维 的数据串,各种变量都可以往里面写,有一个位置指针指向这个一维的数据串中的某个位置,这个位置就是默认的读写的位置。也就是说,如果现在调用读写函数,就是读写当前位置指针处的数据,读写结束后,把位置指针向后移动一块空间,继续准备对下一部分空间进行读写操作。

/**********************
以下是 Parcel_test.cpp 程序 ****************************/
/*
这里的文件扩展名应该是.cpp,也就是c++文件,如果此处用c写程序,扩展名为.c的话,加入#include 这句后可能将出现错误*/
#include
#include
#include

int main()
{
    status_t status;
    size_t parcel_position;
    int intp=987654;
    char charp='g';
    float floatp=3.14159;
    double doublep=12345.6789012;
    long longp=1234567890;
    char *stringp="this is my parcel test!";

    Parcel p;
    parcel_position = p.dataPosition();/*
备份位置*/
    printf("
当前Parcel的读写位置是:%d\n",parcel_position);
    /*************
int类型***************/
    status=p.writeInt32(intp);
    if (status==NO_ERROR)
        printf("write int type success!\n");
    else
        printf("write int type fail,the errno=%d\n",errno);
    /*************
char类型***************/
    status=p.writeInt32(charp);
    if (status==NO_ERROR)
        printf("write char type success!\n");
    else
        printf("write char type fail,the errno=%d\n",errno);
    /*************
Float类型***************/
    status=p.writeFloat(floatp);
    if (status==NO_ERROR)
        printf("write Float type success!\n");
    else
        printf("write Float type fail,the errno=%d\n",errno);
    /*************
Double类型***************/
    status=p.writeDouble(doublep);
    if (status==NO_ERROR)
        printf("write Double type success!\n");
    else
        printf("write Double type fail,the errno=%d\n",errno);
    /*************
long类型***************/
    status=p.writeInt64(longp);
    if (status==NO_ERROR)
        printf("write long type success!\n");
    else
        printf("write long type fail,the errno=%d\n",errno);
    /*************
String类型***************/
    status=p.writeCString(stringp);
    if (status==NO_ERROR)
        printf("write String type success!\n");
    else
        printf("write String type fail,the errno=%d\n",errno);
    /*************
parcel读写位置置回原位***************/
    p.setDataPosition(parcel_position);
    /*************
读出变量***************/
    printf("
读出的int类型变量为:%d\n",p.readInt32());
    printf("
读出的char类型变量为:%c\n",(char)p.readInt32());
    printf("
读出的Float类型变量为:%f\n",(float)p.readFloat());
    printf("
读出的Double类型变量为:%f\n",(double)p.readDouble());
    printf("
读出的long类型变量为:%ld\n",(long)p.readInt64());
    printf("
读出的字符串为:%s\n",p.readCString());
}
/**********************
以上是 Parcel_test.cpp 程序 ****************************/


/***************
下面是对应的makefile文件******************/
/**********************
以下是Android.mk文件 ****************************/
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
    parcel_test.cpp

LOCAL_SHARED_LIBRARIES := \
    libutils \
    libcutils

LOCAL_CFLAGS :=

LOCAL_MODULE:= parcel_test

include $(BUILD_EXECUTABLE)
/**********************
以上是Android.mk文件 ****************************/

把这两个文件放在Android源码目录下的development目录下的parcel_test文件夹中(dl文件夹是新建的),然后在终端中使用 root权限进入到Android源码目录下,执行 make parcel_test。成功后将会在android源码目录/out/target/product/generic/system/bin/中生成 parcel_test可执行文件。

使用以下命令将它们放入Android模拟器,注意要先启动emulator

adb push Android
源码目录/out/target/product/generic/system/bin/parcel_test /data

进入data文件夹执行
adb shell
# cd data
# ./parcel_test
//////////////////////////
以下是程序运行结果 //////////////////////////////
当前Parcel的读写位置是:0
write int type success!
write char type success!
write Float type success!
write Double type success!
write long type success!
write String type success!
读出的int类型变量为:987654
读出的char类型变量为:g
读出的Float类型变量为:3.141590
读出的Double类型变量为:12345.678901
读出的long类型变量为:1234567890
读出的字符串为:this is my parcel test!


==============================
由此可知,Parcel中数据的存储结构的确正如之前猜测的那样,它是一个数据串,有一个位置指针标志着它当前的读写位置。写入数据的时候可以遵从某种约 定,按照某种顺序把数据依此写进去,读的时候再按照同样的顺序依此把数据读出来。估计应该也可以通过设置指针位置的函数跳过某些数据进行读取或写入,但我 这里没有做实验。

另外,如果写完之后再读,那么读之前记得要把位置指针重新置为要读的数据开始的地方,因为之前写的时候数据指针已经移动过了。

 

上一篇:DBI and DPI interface
下一篇:__attribute__ (( ))方法