今天看到这样一个面试题,遂看了下Android系统源码
发现在ActivityThread.java中的performLaunchActivity函数中有这么一段代码
可见,如果在onStart之前如果Activity执行了finish函数,就不会再执行onStart函数了。
示例代码如下:
今天看到这样一个面试题,遂看了下Android系统源码
发现在ActivityThread.java中的performLaunchActivity函数中有这么一段代码
可见,如果在onStart之前如果Activity执行了finish函数,就不会再执行onStart函数了。
示例代码如下:
本文基于Android8.1系统
因为安卓系统默认测试网络的连接是用的google相关的域名,在国内网络无法访问,所以造成即手机连上网络也会出现“已连接,但无法访问互联网”的问题。
可以使用下面两个方法其中之一修改,换成国内可访问的链接
1. 修改文件frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
将文件中常量DEFAULT_HTTPS_URL和DEFAULT_HTTP_URL对应的URL换成可访问的(注意:链接是需要返回http 204返回码的)
2. 修改Android的settings库中Global域中captive_portal_http_url和captive_portal_https_url的值
笔者用的第一种方法,第二种方法没做测试,修改默认设置值请参考下面的链接
http://clients1.google.com/generate_204
http:// clients3.google.com/generate_204
http://www.google-analytics.com/generate_204
http://httpbin.coding.io/status/204
http://www.google.cn/generate_204
http://gen204.sinaapp.com/generate_204
http://g.cn/generate_204
https://mine260309.me/generate_204
http://ping.mine260309.me/generate_204
http://noisyfox.cn/generate_204
https://204.io/generate_204
https://mine260309.me/archives/1587
基本Android8.1系统
一、healthd裁剪
1. system/core/rootdir/init.rc
屏蔽healthd服务
#service healthd /system/bin/healthd
# class core
# critical
# group root system wakelock
删除后系统没办法启动了
二、app删除
2. 启动模拟器看是否有Contacts和Email应用: 有
3. 去掉build/make/target/product/core.mk中PRODUCT_PACKAGES下的Emailt和Contacts并编译看系统中是否还这两个应用: 还有
4. 删除out下对应设备目录下的system/app/Email和system/priv-app/Contacts目录,并编译看系统中是否还这两个应用: 还有
5. 把out目录里的system.img删除掉,再试: 不行
6. 把out/target/common/obj/Apps目录下Email和Contacts相关目录删除再试: 还是有
7. 重启一下系统试试: 不行
8. 把修改core.mk中,把mmsservice也删除掉试试:不行
9. 把源码中packages/apps中的Contacts和Email目录删除,Email目录保留emailcommon目录:好了,这次没了
此阶段结论:其实第3步后make clean一下也可以,但是不想make clean
10. 把Calendar、ExactCalculator(calculator2)、Music、Gallery、Gallery2、SoundRecorder、TvSettings全删掉
三、mediaserver裁剪
在frameworks/av/media/mediaserver/mediaserver.rc中,将mediaserver启动项屏蔽掉
编译后系统可以启动,但是没有壁纸了,设置壁纸也没作用
四、framework服务删减
1、VibratorService删除
屏蔽掉SystemServer.java中启动这个服务的代码
//traceBeginAndSlog(“StartVibratorService”);
//vibrator = new VibratorService(context);
//ServiceManager.addService(“vibrator”, vibrator);
//traceEnd();
删除后,应用调用Vibrator时不会崩溃,log会提示no vibrator service
下面这一段也屏蔽掉:
/* by liuderu
traceBeginAndSlog(“MakeVibratorServiceReady”);
try {
vibrator.systemReady();
} catch (Throwable e) {
reportWtf(“making Vibrator Service ready”, e);
}
traceEnd(); */
2. ConsumerIrService删除
在system/core/rootdir/init.rc中on boot节点中增加如下代码:
setprop config.disable_consumerir true
3. LockSettingsService
在SystemServer.java中屏蔽LOCK_SETTINGS_SERVICE_CLASS的启动
/* by liuderu
traceBeginAndSlog(“StartLockSettingsService”);
try {
mSystemServiceManager.startService(LOCK_SETTINGS_SERVICE_CLASS);
lockSettings = ILockSettings.Stub.asInterface(
ServiceManager.getService(“lock_settings”));
} catch (Throwable e) {
reportWtf(“starting LockSettingsService service”, e);
}
traceEnd(); */
屏蔽bootPhase对lockSetting的检查:
/* by liuderu
traceBeginAndSlog(“StartBootPhaseLockSettingsReady”);
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
traceEnd();
*/
4. MmsServiceBroker
删除SystemServer中
/* by liuderu
traceBeginAndSlog(“StartMmsService”);
mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
traceEnd();
*/
第二个地方
/*by liuderu
traceBeginAndSlog(“MakeMmsServiceReady”);
try {
if (mmsServiceF != null) mmsServiceF.systemRunning();
} catch (Throwable e) {
reportWtf(“Notifying MmsService running”, e);
}
traceEnd();
*/
5. TextServicesManagerService
禁止拼写检查服务
public boolean isSpellCheckerEnabled() {
//default from true to false, by liuderu
return getBoolean(Settings.Secure.SPELL_CHECKER_ENABLED, false);
}
6. AccountManagerService裁剪
SystemServer.java去掉相关代码
/* by liuderu traceBeginAndSlog(“StartAccountManagerService”);
mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
traceEnd();*/
ContentService.java
private SyncManager getSyncManager() {
if (SystemProperties.getBoolean(“config.disable_network”, false)) {
return null;
}
return null;
/*by liuderu
synchronized(mSyncManagerLock) {
try {
// Try to create the SyncManager, return null if it fails (e.g. the disk is full).
if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest);
} catch (SQLiteException e) {
Log.e(TAG, “Can’t create SyncManager”, e);
}
return mSyncManager;
} */
}
DefaultPermissionGrantPolicy.java
第一部分:
/*by liuderu
// Calendar provider
PackageParser.Package calendarProviderPackage = getDefaultProviderAuthorityPackageLPr(
CalendarContract.AUTHORITY, userId);
if (calendarProviderPackage != null) {
grantRuntimePermissionsLPw(calendarProviderPackage, CONTACTS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(calendarProviderPackage, CALENDAR_PERMISSIONS,
true, userId);
grantRuntimePermissionsLPw(calendarProviderPackage, STORAGE_PERMISSIONS, userId);
}
// Calendar provider sync adapters
List<PackageParser.Package> calendarSyncAdapters = getHeadlessSyncAdapterPackagesLPr(
calendarSyncAdapterPackages, userId);
final int calendarSyncAdapterCount = calendarSyncAdapters.size();
for (int i = 0; i < calendarSyncAdapterCount; i++) {
PackageParser.Package calendarSyncAdapter = calendarSyncAdapters.get(i);
if (doesPackageSupportRuntimePermissions(calendarSyncAdapter)) {
grantRuntimePermissionsLPw(calendarSyncAdapter, CALENDAR_PERMISSIONS, userId);
}
}
// Contacts
Intent contactsIntent = new Intent(Intent.ACTION_MAIN);
contactsIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
PackageParser.Package contactsPackage = getDefaultSystemHandlerActivityPackageLPr(
contactsIntent, userId);
if (contactsPackage != null
&& doesPackageSupportRuntimePermissions(contactsPackage)) {
grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId);
grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId);
}
// Contacts provider sync adapters
List<PackageParser.Package> contactsSyncAdapters = getHeadlessSyncAdapterPackagesLPr(
contactsSyncAdapterPackages, userId);
final int contactsSyncAdapterCount = contactsSyncAdapters.size();
for (int i = 0; i < contactsSyncAdapterCount; i++) {
PackageParser.Package contactsSyncAdapter = contactsSyncAdapters.get(i);
if (doesPackageSupportRuntimePermissions(contactsSyncAdapter)) {
grantRuntimePermissionsLPw(contactsSyncAdapter, CONTACTS_PERMISSIONS, userId);
}
}
// Contacts provider
PackageParser.Package contactsProviderPackage = getDefaultProviderAuthorityPackageLPr(
ContactsContract.AUTHORITY, userId);
if (contactsProviderPackage != null) {
grantRuntimePermissionsLPw(contactsProviderPackage, CONTACTS_PERMISSIONS,
true, userId);
grantRuntimePermissionsLPw(contactsProviderPackage, PHONE_PERMISSIONS,
true, userId);
grantRuntimePermissionsLPw(contactsProviderPackage, STORAGE_PERMISSIONS, userId);
}*/
第二部分:
/* by liuderu
String[] contactsSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
syncAdapterPackagesProvider.getPackages(ContactsContract.AUTHORITY, userId) : null;
String[] calendarSyncAdapterPackages = (syncAdapterPackagesProvider != null) ?
syncAdapterPackagesProvider.getPackages(CalendarContract.AUTHORITY, userId) : null;*/
UsageStatsService.java
void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
/*by liuderu
// Get sync adapters for the authority
String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser(
authority, userId);
for (String packageName: packages) {
// Only force the sync adapters to active if the provider is not in the same package and
// the sync adapter is a system package.
try {
PackageInfo pi = mPackageManager.getPackageInfoAsUser(
packageName, PackageManager.MATCH_SYSTEM_ONLY, userId);
if (pi == null || pi.applicationInfo == null) {
continue;
}
if (!packageName.equals(providerPkgName)) {
setAppIdleAsync(packageName, false, userId);
}
} catch (NameNotFoundException e) {
// Shouldn’t happen
}
}
*/
}
ContactsProvider2.java
case BACKGROUND_TASK_UPDATE_ACCOUNTS: {
/*by liuderu
Context context = getContext();
if (!mAccountUpdateListenerRegistered) {
AccountManager.get(context).addOnAccountsUpdatedListener(this, null, false);
mAccountUpdateListenerRegistered = true;
}
// Update the accounts for both the contacts and profile DBs.
Account[] accounts = AccountManager.get(context).getAccounts();
switchToContactMode();
boolean accountsChanged = updateAccountsInBackground(accounts);
switchToProfileMode();
accountsChanged |= updateAccountsInBackground(accounts);
switchToContactMode();
updateContactsAccountCount(accounts);
updateDirectoriesInBackground(accountsChanged);*/
break;
}
7. PrintManagerService
在SystemServer中删除相关代码
/*
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
traceBeginAndSlog(“StartPrintManager”);
mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
traceEnd();
}
*/
8. CoverageService
在SystemServer中删除相关代码
/*by liuderu
if (!disableNonCoreServices && CoverageService.ENABLED) {
traceBeginAndSlog(“AddCoverageService”);
ServiceManager.addService(CoverageService.COVERAGE_SERVICE, new CoverageService());
traceEnd();
}
*/
9. DiskStatsService
在SystemServer中删除相关代码
/*by liuderu
traceBeginAndSlog(“StartDiskStatsService”);
try {
ServiceManager.addService(“diskstats”, new DiskStatsService(context));
} catch (Throwable e) {
reportWtf(“starting DiskStats Service”, e);
}
traceEnd();
*/
对于有序广播,并且发送广播的进程和接收处理的进程不是一个进程时,超过60秒才会有anr?
本文基本Android8.1系统源码
stack.log的第一个参数是LOG_TAG,第二个是固定的ANDROID_LOG_DEBUG
笔者本来以为zygote是通过127.0.0.1这种方式创建的server,所以会有此疑问。经过研究发现,zygote是通过文件建立的socket server(具体文件名/dev/socket/zygote),并且zygote是以root权限运行的,所以它生成的socket文件普通应用是无法进行通讯的。
删除目录frameworks/base/core/res/res/下面的除了简体中文zh-rCN、繁体中文zh-rTW、zh-rHK和英文en-rXX之外的相关语言资源文件
删除前system.img文件为1.2G左右
删除后system.img文件为1.1G左右
在frameworks/base/core/res/res/values/locale_config.xml中删除不使用的语言即可
有多个功能类似的脚本,用到同一个变量,但是这个变量有可能会根据需要改变,如果每个脚本文件定义一个这个变量,修改的时候每个脚本都要修改,很麻烦,所以想将这个变量定义在一个common.sh脚本里面,然后在功能脚本里面引用这个脚本,代码如下:
Ubuntu18.04.4,不能使用Ubuntu16会有很多依赖软件版本太低
硬盘200G,内存4G+,交换分区(swap)4G+(可装完系统后添加,见后面错误处理部分)
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
sudo apt install uuid uuid-dev zlib1g-dev liblz-dev liblzo2-2 liblzo2-dev lzop git-core curl u-boot-tools mtd-utils android-tools-fsutils device-tree-compiler gdisk liblz4-tool m4 libz-dev
安装open-jdk-8
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
安装gcc-arm-none-eabi
sudo apt-get install gcc-arm-none-eabi
安装完这一项后,在~/.bashrc中最后一行添加脚本export ARMGCC_DIR=/usr/
然后执行source ~/.bashrc
安装cmake,需要3.13.0版本以上,安装步骤如下,其中./bootstrap那一步可以不用加后面的–qt-gui参数
https://blog.csdn.net/huigougou/article/details/84326907
然后进入到Android源码目录,假设源码在用户根目录的aosp目录中:
cd ~/aosp
然后初始化编译环境,使用下面的命令:
source build/envsetup.sh
然后选择要编译的目标版本,先输入lunch命令
lunch
然后在显示的列表中选择你的目标版本,输入相应的数字,按回车即可
然后使用make开始编译,可以使用-j参数增加编译的线程以提高速度,线程数量为cpu核心数的2倍比较合适,比如你的cpu是4核的使用
make -j8
就可以了
解决办法:
This will do the trick:
export LC_ALL=C
Add it to your bashrc file or equivalent.
参考链接:https://stackoverflow.com/questions/49955137/error-when-build-lineageos-make-ninja-wrapper-error-1
https://www.jianshu.com/p/2beae17c9b12
解决方案:
修改jack server内存
步骤:
打开./prebuilts/sdk/tools/jack-admin
找到下面这一行
JACK_SERVER_VM_ARGUMENTS=”${JACK_SERVER_VM_ARGUMENTS:=-Dfile.encoding=UTF-8}”
修改为
JACK_SERVER_VM_ARGUMENTS=”${JACK_SERVER_VM_ARGUMENTS:=-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096M}”
保存jack-admin文件
在命令行执行
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server
重启jack server
然后重新编译