1 每一个应用拥有一个独立的user ID,该ID对系统可见,但对应用不可见,系统根据分配的user ID设置应用文件的权限
2 系统遵循最小特权原则,即应用仅拥有操作运行所需的组件的权限
3 应用间共享数据和进入系统服务:
① 两个应用共享同样的Linux userID,则它们可以互相操作彼此的文件,也可以跑在同样的Linux进程,并共享共同的虚拟机VM(但必须有相同的证书签名)
4 定位内存泄漏
① adb shell setprop libc.debug.malloc 1
② adb shell stop
③ adb shell start
④ 进行测试直到内存泄漏足够明显
⑤ 运行ddms,native allocation栏运行一次snapshot,可以得到内存的消耗比例
适用范围:应用+native
5 在应用启动时进行debug
① adb shell am set-debug-app -w 包名
② 启动应用,此时应用会提示等待debug
③ 打开ddms开始debug调试(或者gdb调试)
6 Android Java层打印堆栈:
① import android.util.Log;
② java.util.Map 《Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();
StackTraceElement[] ste = ts.get(Thread.currentThread());
for( StackTraceELement s : ste){
android.util.Slog.e(“DEBUG”, s.toString());
}
③ Process.sendSignal(pid, Process.SIGNAL_QUIT); //代码中杀死进程,生成trace文件
④ debuggerd -b //adb shell下,不杀进程,打印trace
⑤
try {
……
}catch(Exception e){
e.printStackTrace();
}
⑥
Log.d(TAG,Log.getStackTraceString(new Throwable())); //java中不中断代码
⑦ new Exception(“print trace”).printStackTrace();
7 Native打印堆栈
include 《utils/CallStack.h>
include 《utils/Log.h>
include 《sys/types.h>
android::CallStack stack;
stack.update(1, 100);
stack.dump(“”);
8 以下是关于Android L64位系统兼容32位应用的实现的分析
Android L的zygote进程的实现不同于之前的版本,除了有zygote进程之外还有zygote64进程。
在init.zygote32_64.rc有明确指出:
service zygote /system/bin/app_process32 -X zygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
service zygote_secondary /system/bin/app_process64 -X zygote /system/bin --zygote --socket-name=zygote_secondary
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote
其中app_process32和app_process64就是zygote进程的可执行程序,启动后会改名成zygote。
顾名思义,zygote32即app_process32是一个运行在32位的进程,它所连接的库也都是32位的。而zygote64就是运行在64位的进程,它所连接的库都是64位的。
在不考虑有32/64位兼容库的情况下,一个进程如果要正确的运行,就必须从可执行程序入口开始到所有使用到的库都保持32/64位的一致性。
因为zygote进程是所有第三方应用程序的父进程,所以可以认为,如果应用程序是32位的,那么他的父进程肯定就是32位的,换句话说,如果需要启动某个32位的应用,那么肯定是通过32位的zygote进程fork出来的。这一点可以在ActivityManagerService上得到验证:
ActivityManagerService中startProcessLocked方法实现启动应用,主要通过Process中的startViaZygote方法,这个方法最终是向相应的zygote进程发出fock的请求:
zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),argsForZygote);
其中openZygoteSocketIfNeeded(abi)会根据abi的类型,选择不同的zygote的socket监听的端口,在之前的init文件中可以看到:
zygote32位监听的端口就是–socket-name=zygote,另一个就是–socket-name=zygote_secondary
因此可以证实,之前的猜测,即32位应用是由32位zygote进程fork出来的,64位应用进程由64zygote进程fork出来的。
那么之前说的abi参数就是决定应用是32位还是64位的关键所在,跟踪这个参数,发现这个参数在ApplicationInfo的primaryCpuAbi中决定,这个值由PackageManagerService在做scanPackageLI的时候决定,具体这个值得得出由一个公式化的过程,主要就是判断这个apk有没有使用native的库,如果使用了,那就看使用了的库是32位的还是64位的,另外还要看系统支持的是32位的还是64位的。
以上就是AndroidL 64位系统兼容32位应用的基本实现过程,仅供参考。
9 android自定义背景shape的使用,以下是使用示例:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#00000000" /> <!-- 填充的颜色 -->
<stroke
android:width="@dimen/sm_4"
android:color="#FFffff00" /> <!-- 边框的颜色 -->
<corners android:radius="0dp" /> <!-- android:radius 弧形半径 -->
</shape>
shape定义完成后,即可在
layout.xml添加:android:background=”@drawable/[shape文件名]”
或者
selector.xml添加 :android:drawable=”@drawable/[shape文件名]”
10android 选择器使用:
在drawable或者color资源下新建选择器:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_s" android:state_pressed="true"/>
<item android:drawable="@drawable/bg_u" android:state_focused="false" android:state_pressed="false"/>
<item android:drawable="@drawable/bg_s" android:state_focused="true"/>
<item android:drawable="@drawable/u" android:state_focused="false"/>
</selector>
在布局文件中添加:android:background=”@drawable/[选择器文件名]”