Android Framework知识点

1 重点知识

1.1 Alarm

当手机重启或者应用被杀死的时候,Alarm会被删除,因此,如果想通过Alarm来完成长久定时任务是不可靠的,如果非要完成长久定时任务,可以这样:将应用的所有Alarm信息存到数据库中,每次应用启动的时候都重新注册Alarm并更新Alarm的触发时间,通过这种方式就不存在Alarm丢失的情况了。

1.2 Android-N app seinfo设置流程

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

startProcessLocked() {

...

Process.ProcessStartResult startResult =

Process.start(entryPoint,

app.processName,

uid, uid, gids,

debugFlags, mountExternal,

app.info.targetSdkVersion,

app.info.seinfo,

requiredAbi, instructionSet,

app.info.dataDir, entryPointArgs);

...

}

frameworks/base/core/java/android/os/Process.java

start() {

try {

return startViaZygote(processClass,

niceName,

uid, gid, gids,

debugFlags, mountExternal,

targetSdkVersion, seInfo,

abi, instructionSet,

appDataDir, zygoteArgs);

} catch (ZygoteStartFailedEx ex) {

...

}

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

ForkAndSpecializeCommon() {

...

rc = selinux_android_setcontext(

uid, is_system_server,

se_info_c_str, se_name_c_str);

...

}

external/libselinux/src/android.c

int selinux_android_setcontext(

uid_t uid,

bool isSystemServer,

const char *seinfo,

const char *pkgname)

{

...

}

1.3 Launcher的启动

/* ActivityThread.java */

SystemServer.java

private void startOtherServices() {

...

mActivityManagerService.systemReady(

new Runnable() {

});

}

1.4 屏幕永不超时

frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java

frameworks/base/packages/SettingsProvider/res/values/defaults.xml

将def_screen_off_timeout的值改成2147483647(0x7fffffff)。

/data/system/users/0/settings_system.xml

adb shell settings put system screen_off_timeout 3600000 #一小时超时

1.5 禁止锁屏

frameworks/policies/base/phone/com/android/internal/policy/impl/KeyguardViewMediator.java

将mExternallyEnabled的值改成false。

1.6 tmpfs文件系统

mkdir /data/tmp

mount -t tmpfs -o size=100M tmpfs /data/tmp

1.7 apk signer

apk: private key signer

keystore: 密钥库

2 Android异常分析汇总

2.1 Android卡在开机动画

1)AudioFlinger反复重启

2)systemui ANR

2.2 framework反复重启

1)boot_progress|low-level shutdown|am_crash|checkScreenEnabled|ILL_ILLOPN

2.3 no window focus

ViewRootImpl.java

mAttachInfo.mHasWindowFocus = true

Activity中在dispatchKeyEvent()或者dispatchTouchEvent()方法里面,通过反射把mAttachInfo.mHasWindowFocus重置为true,可以解决no window focus。

@Override

public boolean dispatchTouchEvent(@NonNull KeyEvent event) {

try {

ViewParent viewRootImpl =

getWindow().getDecorView().getParent();

Class viewRootImplClass =

viewRootImpl.getClass();

Field mAttachInfoField =

viewRootImplClass.getDeclaredField(

"mAttachInfo");

mAttachInfoField.setAccessible(true);

Object mAttachInfo =

mAttachInfoField.get(viewRootImpl);

Class mAttachInfoClass =

mAttachInfo.getClass();

Field mHasWindowFocusField =

mAttachInfoClass.getDeclaredField(

"mHasWindowFocus");

mHasWindowFocusField.setAccessible(true);

mHasWindowFocusField.set(mAttachInfo,

true);

boolean mHasWindowFocus =

(boolean) mHasWindowFocusField.get(

mAttachInfo);

} catch (Exception e) {

e.printStackTrace();

}

return super.dispatchKeyEvent(event);

}

2.4 dumpsys gfxinfo

使用dumpsys gfxinfo命令可获取128帧的绘制信息,详细包括每一帧绘制的Draw、Process、Execute三个过程的耗时,如果这三个时间总和超过16.6ms即认为发生了卡顿。

2.5 Linux disk usage

查看当前目录下面所有文件夹所占的空间。

du -h -d 1

显示目录和目录下子目录和文件占用磁盘空间的大小。

du -h /data/data

2.6 提取log

import io

import re

import sys,os

import shutil

arg0_proc_name = ''

def print_usage():

print('\nUsage: python ' + arg0_proc_name +

' <DIR> <file_prefix> <match_string>')

print('refer to the below showcases '

'regarding match_string\n')

list = [

'boot_progress|shutdown',

'boot_progress|low-level shutdown|'

'am_crash',

'boot_progress|shutdown|am_crash|'

'bootinfo',

'checkScreenEnabled|ILL_ILLOPN',

'UIWDT',

]

for item in list:

print(' \"' + item + '\"')

print('')

def remove_dir(dir_path):

if os.path.isdir(dir_path):

for file in os.listdir(dir_path):

if (os.path.isdir(dir_path +

os.path.sep + file)):

remove_dir(dir_path +

os.path.sep + file)

else:

os.remove(dir_path +

os.path.sep + file)

os.removedirs(dir_path)

def write_file_string(file, line_string):

h = open(file, 'a+')

h.writelines(line_string)

h.close()

def write_line_string_to_log(src_file,

dst_file, match_string):

line_cnt = 1

fp = io.open(src_file, 'r', encoding='utf-8',

errors='ignore')

for line_string in fp:

if re.findall(match_string, line_string.lower()):

#if re.findall(match_string, line_string.lower(),

#re.I):

write_file_string(

dst_file, str(line_cnt) + ' ' + line_string)

line_cnt += 1

def find_string(dir_path, file_prefix, match_string):

remove_dir(dir_path + os.path.sep + 'my_out')

os.makedirs(dir_path + os.path.sep + 'my_out')

try:

for file in os.listdir(dir_path):

if (os.path.isfile(dir_path + os.path.sep +

file) and \

file.startswith(file_prefix)):

write_line_string_to_log(dir_path +

os.path.sep + file,

dir_path + os.path.sep +

'my_out' + os.path.sep + file,

match_string)

except KeyboardInterrupt:

print('Got ^C exit signal')

def main():

global arg0_proc_name

arg0_proc_name = sys.argv[0]

if sys.argv[0].rfind(os.path.sep) > 0 :

index = sys.argv[0].rfind(os.path.sep)

arg0_proc_name = sys.argv[0][index+1:]

if len(sys.argv) < 4:

print_usage()

sys.exit(0)

print('to be found: ' + sys.argv[2])

find_string(sys.argv[1], sys.argv[2],

sys.argv[3])

if name == 'main':

main()

3 USB异步API

development/samples/USB/AdbTest

import static java.lang.Integer.toHexString;

Integer.toHexString(USB_VID)

USB gadget state is not attached

MTP/mass_storage

Maybe the USB cable|idVendor=1d6b|idVendor=12d1|usb disconnect|over-current|nearby|wwan0, isUp is:

  1. Choose xxx-Domain, then click Create to create a new page BBB under xxx-Domain.

  2. Add Link to xxx-Domain, Edit - copy other line to get prefix format - Insert Link - Search BBB.

4 ART

adb shell oatdump --oat-file=/data/dalvik-cache/xxx/xxx.dex

Linux:

readelf -a xxx.dex

5 Abbreviations

Android PMS LI、LIF、LPw、LPr:要想弄明白方法名中的LI、LIF、LPw、LPr的含义,需要先了解PackageManagerService内部使用的两个锁。因为LI、LIF、LPw、LPr中的L,指的是Lock,而后面跟的I和P指的是两个锁,I表示mInstallLock同步锁;P表示mPackages同步锁。LPw、LPr中的w表示writing,r表示reading。LIF中的F表示Freeze。

ILL_ILLOPN:illegal operand

scanDirLI():scanDir Lock mInstallLock