本文将为您提供关于AndroidCTS中neverallow规则生成过程的详细介绍,同时,我们还将为您提供关于activity的属性android:taskAffinity和android:allow
本文将为您提供关于Android CTS中neverallow规则生成过程的详细介绍,同时,我们还将为您提供关于activity 的属性 android:taskAffinity 和 android:allowTask、android 4.0中的java.lang.StackOverflowError,而不是android 3.0中的、android 6 中 init.rc 的生成过程【转】、android @android:Theme.Dialog 和 @android:Widget.Button找不到的实用信息。
本文目录一览:- Android CTS中neverallow规则生成过程
- activity 的属性 android:taskAffinity 和 android:allowTask
- android 4.0中的java.lang.StackOverflowError,而不是android 3.0中的
- android 6 中 init.rc 的生成过程【转】
- android @android:Theme.Dialog 和 @android:Widget.Button找不到
Android CTS中neverallow规则生成过程
CTS里面SELinux相关测试中neverallow测试项占绝大多数,Android系统开发者都应该知道,在修改sepolicy时,需要确保不能违反这些neverallow规则,不然会过不了CTS。CTS中nerverallow测试都是在SELinuxNeverallowRulesTest.java文件中,并且从AOSP代码中发现该文件不是人工提交的,而是通过python脚本生成的,为了以后更好的修改sepolicy,就需要了解下SELinuxNeverallowRulesTest.java是如何生成的。
Makefile
首先看下SELinuxNeverallowRulesTest.java的生成的Makefile.
selinux_general_policy := $(call intermediates-dir-for,ETC,general_sepolicy.conf)/general_sepolicy.conf
selinux_neverallow_gen := cts/tools/selinux/SELinuxNeverallowTestGen.py
selinux_neverallow_gen_data := cts/tools/selinux/SELinuxNeverallowTestFrame.py
LOCAL_ADDITIONAL_DEPENDENCIES := $(COMPATIBILITY_TESTCASES_OUT_cts)/sepolicy-analyze
LOCAL_GENERATED_SOURCES := $(call local-generated-sources-dir)/android/cts/security/SELinuxNeverallowRulesTest.java # 目标文件
$(LOCAL_GENERATED_SOURCES) : PRIVATE_SELINUX_GENERAL_POLICY := $(selinux_general_policy)
$(LOCAL_GENERATED_SOURCES) : $(selinux_neverallow_gen) $(selinux_general_policy) $(selinux_neverallow_gen_data)
mkdir -p $(dir $@)
$< $(PRIVATE_SELINUX_GENERAL_POLICY) $@
# $< 为:右边依赖的第一个元素, 即 $(selinux_neverallow_gen) = cts/tools/selinux/SELinuxNeverallowTestGen.py
# $@ 为:左边目标,即要生成的目标文件SELinuxNeverallowRulesTest.java
# 这条命令相当于 cts/tools/selinux/SELinuxNeverallowTestGen.py $(call intermediates-dirfor,ETC,general_sepolicy.conf)/general_sepolicy.conf SELinuxNeverallowRulesTest.java
include $(BUILD_CTS_HOST_JAVA_LIBRARY)
从上面可以看到,执行SELinuxNeverallowTestGen.py general_sepolicy.conf SELinuxNeverallowRulesTest.java会生成SELinuxNeverallowRulesTest.java文件。
general_sepolicy.conf 生成
该文件的生成Makfile
# SELinux policy embedded into CTS.
# CTS checks neverallow rules of this policy against the policy of the device under test.
##################################
include $(CLEAR_VARS)
LOCAL_MODULE := general_sepolicy.conf # 目标文件
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := tests
include $(BUILD_SYstem)/base_rules.mk
$(LOCAL_BUILT_MODULE): PRIVATE_MLS_SENS := $(MLS_SENS)
$(LOCAL_BUILT_MODULE): PRIVATE_MLS_CATS := $(MLS_CATS)
$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_BUILD_VARIANT := user
$(LOCAL_BUILT_MODULE): PRIVATE_TGT_ARCH := $(my_target_arch)
$(LOCAL_BUILT_MODULE): PRIVATE_WITH_ASAN := false
$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY_SPLIT := cts
$(LOCAL_BUILT_MODULE): PRIVATE_COMPATIBLE_PROPERTY := cts
$(LOCAL_BUILT_MODULE): $(call build_policy, $(sepolicy_build_files), \
$(PLAT_PUBLIC_POLICY) $(PLAT_PRIVATE_POLICY)) # PLAT_PUBLIC_POLICY = syetem/sepolicy/public PLAT_PRIVATE_POLICY = system/sepolicy/private
$(transform-policy-to-conf) # 这里是使用m4将te规则文件都处理合成为目标文件$@,即general_sepolicy.conf
$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
##################################
可以看到,general_sepolicy.conf 文件是将system/sepolicy/public和system/sepolicy/private规则文件整合在一起,而这些目录包含的是AOSP sepolicy大多数配置信息。
SELinuxNeverallowTestGen.py 脚本逻辑
生成的逻辑都是在该脚本中,下面脚本我调整了顺序,方便说明执行的逻辑,脚本代码
#!/usr/bin/env python
import re
import sys
import SELinuxNeverallowTestFrame
usage = "Usage: ./SELinuxNeverallowTestGen.py <input policy file> <output cts java source>"
if __name__ == "__main__":
# check usage
if len(sys.argv) != 3:
print usage
exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
# 这三个变量是同目录下SELinuxNeverallowTestFrame.py文件中的内容,是生成java文件的模版
src_header = SELinuxNeverallowTestFrame.src_header
src_body = SELinuxNeverallowTestFrame.src_body
src_footer = SELinuxNeverallowTestFrame.src_footer
# grab the neverallow rules from the policy file and transform into tests
neverallow_rules = extract_neverallow_rules(input_file) # 提取neverallow规则从general_sepolicy.conf中
i = 0
for rule in neverallow_rules:
src_body += neverallow_rule_to_test(rule, i)
i += 1
# 然后将neverallow规则写入到SELinuxNeverallowRulesTest.java文件中
with open(output_file, 'w') as out_file:
out_file.write(src_header)
out_file.write(src_body)
out_file.write(src_footer)
# extract_neverallow_rules - takes an intermediate policy file and pulls out the
# neverallow rules by taking all of the non-commented text between the 'neverallow'
# keyword and a terminating ';'
# returns: a list of rules
def extract_neverallow_rules(policy_file):
with open(policy_file, 'r') as in_file:
policy_str = in_file.read()
# full-Treble only tests are inside sections delimited by BEGIN_TREBLE_ONLY
# and END_TREBLE_ONLY comments.
# uncomment TREBLE_ONLY section delimiter lines
remaining = re.sub(
r'^\s*#\s*(BEGIN_TREBLE_ONLY|END_TREBLE_ONLY|BEGIN_COMPATIBLE_PROPERTY_ONLY|END_COMPATIBLE_PROPERTY_ONLY)',
r'\1', # group 引用
policy_str,
flags = re.M) # 该方法是将 #开头的注释行任意空格后跟着BEGIN_TREBLE_ONLY、END_TREBLE_ONLY、BEGIN_COMPATIBLE_PROPERTY_ONLY和END_COMPATIBLE_PROPERTY_ONLY时,替换为这些关键字,即去掉注释
# remove comments
remaining = re.sub(r'#.+?$', r'', remaining, flags = re.M) # 将文件中的 # 开头注释行去掉
# match neverallow rules
lines = re.findall(
r'^\s*(neverallow\s.+?;|BEGIN_TREBLE_ONLY|END_TREBLE_ONLY|BEGIN_COMPATIBLE_PROPERTY_ONLY|END_COMPATIBLE_PROPERTY_ONLY)',
remaining,
flags = re.M |re.S) # 将neverallow和以这几个关键字开头的行取出来
# extract neverallow rules from the remaining lines
# 这些关键字会修饰里面的neverallowrules,若treble_only_depth > 1 说明是适用于treble系统, 若compatible_property_only_depth > 1,说明适用于 compatible_property 系统
rules = list()
treble_only_depth = 0
compatible_property_only_depth = 0
for line in lines:
if line.startswith("BEGIN_TREBLE_ONLY"):
treble_only_depth += 1
continue
elif line.startswith("END_TREBLE_ONLY"):
if treble_only_depth < 1:
exit("ERROR: END_TREBLE_ONLY outside of TREBLE_ONLY section")
treble_only_depth -= 1
continue
elif line.startswith("BEGIN_COMPATIBLE_PROPERTY_ONLY"):
compatible_property_only_depth += 1
continue
elif line.startswith("END_COMPATIBLE_PROPERTY_ONLY"):
if compatible_property_only_depth < 1:
exit("ERROR: END_COMPATIBLE_PROPERTY_ONLY outside of COMPATIBLE_PROPERTY_ONLY section")
compatible_property_only_depth -= 1
continue
rule = NeverallowRule(line)
rule.treble_only = (treble_only_depth > 0)
rule.compatible_property_only = (compatible_property_only_depth > 0)
rules.append(rule)
if treble_only_depth != 0:
exit("ERROR: end of input while inside TREBLE_ONLY section")
if compatible_property_only_depth != 0:
exit("ERROR: end of input while inside COMPATIBLE_PROPERTY_ONLY section")
return rules
# neverallow_rule_to_test - takes a neverallow statement and transforms it into
# the output necessary to form a cts unit test in a java source file.
# returns: a string representing a generic test method based on this rule.
# 将neverallowrules 替换到java模版中
def neverallow_rule_to_test(rule, test_num):
squashed_neverallow = rule.statement.replace("\n", " ")
method = SELinuxNeverallowTestFrame.src_method
method = method.replace("testNeverallowRules()",
"testNeverallowRules" + str(test_num) + "()")
method = method.replace("$NEVERALLOW_RULE_HERE$", squashed_neverallow)
method = method.replace(
"$FULL_TREBLE_ONLY_BOOL_HERE$",
"true" if rule.treble_only else "false")
method = method.replace(
"$COMPATIBLE_PROPERTY_ONLY_BOOL_HERE$",
"true" if rule.compatible_property_only else "false")
return method
总结下脚本功能
- 将BEGIN_TREBLE_ONLY|END_TREBLE_ONLY|BEGIN_COMPATIBLE_PROPERTY_ONLY|
END_COMPATIBLE_PROPERTY_ONLY这几个关键字前面的注释去掉,以便后面解析时使用; - 删除冗余的注释行;
取neverallow和上面四个关键字的部分进行解析,并根据下面情况对treble_only和compatible_property_only进行设置;
- neverallow 包含在BEGIN_TREBLE_ONLY和END_TREBLE_ONLY之间,treble_only被设置为true;
- neverallow 包含在BEGIN_COMPATIBLE_PROPERTY_ONLY和END_COMPATIBLE_PROPERTY_ONLY之间,compatible_property_only被设置为true;
- neverallow 不在任何BEGIN_TREBLE_ONLY/END_TREBLE_ONLY和BEGIN_COMPATIBLE_PROPERTY_ONLY/END_COMPATIBLE_PROPERTY_ONLY之间,则treble_only和compatible_property_only都被设置为false。
- 然后用neverallow部分、treble_only和compatible_property_only值对下面方法模板中的$NEVERALLOW_RULE_HERE$、$FULL_TREBLE_ONLY_BOOL_HERE$和$COMPATIBLE_PROPERTY_ONLY_BOOL_HERE$分别替换。
src_method = """
@RestrictedBuildTest
public void testNeverallowRules() throws Exception {
String neverallowRule = "$NEVERALLOW_RULE_HERE$";
boolean fullTrebleOnly = $FULL_TREBLE_ONLY_BOOL_HERE$;
boolean compatiblePropertyOnly = $COMPATIBLE_PROPERTY_ONLY_BOOL_HERE$;
if ((fullTrebleOnly) && (!isFullTrebleDevice())) {
// This test applies only to Treble devices but this device isn't one
return;
}
if ((compatiblePropertyOnly) && (!isCompatiblePropertyEnforcedDevice())) {
// This test applies only to devices on which compatible property is enforced but this
// device isn't one
return;
}
// If sepolicy is split and vendor sepolicy version is behind platform's,
// only test against platform policy.
File policyFile =
(isSepolicySplit() && mvendorSepolicyVersion < P_SEPOLICY_VERSION) ?
deviceSystemPolicyFile :
devicePolicyFile;
/* run sepolicy-analyze neverallow check on policy file using given neverallow rules */
ProcessBuilder pb = new ProcessBuilder(sepolicyAnalyze.getAbsolutePath(),
policyFile.getAbsolutePath(), "neverallow", "-w", "-n",
neverallowRule);
pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
BufferedReader result = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
StringBuilder errorString = new StringBuilder();
while ((line = result.readLine()) != null) {
errorString.append(line);
errorString.append("\\n");
}
assertTrue("The following errors were encountered when validating the SELinux"
+ "neverallow rule:\\n" + neverallowRule + "\\n" + errorString,
errorString.length() == 0);
}
本地生成 SELinuxNeverallowRulesTest.java 文件
在修改SELinux后,想确定下是否满足neverallow规则,虽然编译过程中会进行neverallow检查,但由于打包时间比较耗时,如果在本地生成的话,那速度会更快。
本地生成 SELinuxNeverallowRulesTest.java 命令
默认是在源码的根目录
make general_sepolicy.conf
cts/tools/selinux/SELinuxNeverallowTestGen.py out/target/product/cepheus/obj/ETC/general_sepolicy.conf_intermediates/general_sepolicy.conf SELinuxNeverallowRulesTest.java
由于某些规则是使用attribute,可能不是很明显,还需要结合其他方法来确定。
总结
从生成代码中可以看到,neverallow规则都属于AOSP system/sepolicy/private和system/sepolicy/public中的neverallow,所以在添加规则时不能修改neverallow,也不能违背。
附件
cts_neverallow.zip,中包含有:
SELinuxNeverallowTestGen.py 脚本
general_sepolicy.conf
SELinuxNeverallowTestFrame.py Java测试代码模板
first 为SELinuxNeverallowTestGen.py第一步执行的结果
second 为SELinuxNeverallowTestGen.py第二步执行的结果
SELinuxNeverallowRulesTest.java 为生成的文件
后面三个文件是前三个文件所生成,执行命令为:
SELinuxNeverallowTestGen.py general_sepolicy.conf SELinuxNeverallowRulesTest.java
链接
https://liwugang.github.io/2019/12/29/CTS-neverallow.html
activity 的属性 android:taskAffinity 和 android:allowTask
1. 清单文件中,activity 的属性
android:allowTaskReparenting
这个属性用于设定 Activity 能够从启动它的任务中转移到另一个与启动它的任务有亲缘关系的任务中,转移时机是在这个有亲缘关系的任务被带到前台的时候。如果设置了 true,则能够转移,如果设置了 false,则这个 Activity 必须要保留在启动它的那个任务中。
如果这个属性没有设置,那么其对应的 <application> 元素的 allowTaskReparenting 属性值就会应用到这个 Activity 上。它的默认值是 false。
通常,当 Activity 被启动时,它会跟启动它的任务关联,并它的整个生命周期都会保持在那个任务中。但是当 Activity 的当前任务不在显示时,可以使用这个属性来强制 Activity 转移到与当前任务有亲缘关系的任务中。这种情况的典型应用是把应用程序的 Activity 转移到与这个应用程序相关联的主任务中。
例如,如果一个电子邮件消息中包含了一个网页的链接,点击这个链接会启动一个显示这个网页的 Activity。但是,由 e-mail 任务部分启动的这个 Activity 是由浏览器应用程序定义的。如果把它放到浏览器的任务中,那么在浏览器下次启动到前台时,这个网页会被显示,并且在 e-mail 任务再次显示时,这个 Activity 有会消失。
Activity 的亲缘关系是由 taskAffinity 属性定义的。通过读取任务的根 Activity 的亲缘关系来判断任务的亲缘关系。因此,通过定义,任务中的根 Activity 与任务有着相同的亲缘关系。因此带有 singleTask 或 singleInstance 启动模式的 Activity 只能是任务的根节点,Activity 的任务归属受限于 standard 和 singleTop 模式。
经典理解:
就是说,一个 activity1 原来属于 task1,但是如果 task2 启动起来的话,activity1 可能不再属于 task1 了,转而投奔 task2 去了。
当然前提条件是 allowTaskReparenting,还有 affinity 设置
有点像,你捡到一条狗,在家里喂养几天觉得不错,当自己家的了;但是突然有一天他的主人找上门来了,小狗还是乖乖和主人走了。。。
或者:
用法
是否允许 activity 更换从属的任务,比如从短信息任务 切换到浏览器任务。
用来标记 Activity 能否从启动的 Task 移动到有着 affinity 的 Task(当这个 Task 进入到前台时)——“true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个 Task 里。
如果这个特性没有被设定,设定到元素上的 allowTaskReparenting 特性的值会应用到 Activity 上。默认值为 “false”。
一般来说,当 Activity 启动后,它就与启动它的 Task 关联,并且在那里耗尽它的整个生命周期。当当前的 Task 不再显示时,你可以使用这个特性来强制 Activity 移动到有着 affinity 的 Task 中。典型用法是:把一个应用程序的 Activity 移到另一个应用程序的主 Task 中。
例如,如果 e-mail 中包含一个 web 页的链接,点击它就会启动一个 Activity 来显示这个页面。这个 Activity 是由 Browser 应用程序定义的,但是,现在它作为 e-mail Task 的一部分。如果它重新宿主到 Browser Task 里,当 Browser 下一次进入到前台时,它就能被看见,并且,当 e-mail Task 再次进入前台时,就看不到它了。
Actvity 的 affinity 是由 taskAffinity 特性定义的。Task 的 affinity 是通过读取根 Activity 的 affinity 决定。因此,根据定义,根 Activity 总是位于相同 affinity 的 Task 里。由于启动模式为 “singleTask” 和 “singleInstance” 的 Activity 只能位于 Task 的底部,因此,重新宿主只能限于 “standard” 和 “singleTop” 模式。
android:alwaysRetainTaskState
这个属性用于设置 Activity 所属的任务状态是否始终由系统来维护。如果设置为 true,则由系统来维护状态,设置为 false,那么在某些情况下,系统会允许重设任务的初始状态。默认值是 false。这个属性只对任务根节点的 Activity 有意义,其他所有的 Activity 都会被忽略。
通常,在某些情况中,当用户从主屏中重新启动一个任务时,系统会先清除任务(从堆栈中删除根节点 Activity 之上的所有 Activity)。
但是,当这个属性被设置为 true 时,用户会始终返回到这个任务的最后状态,而不管中间经历了哪些操作。这样做是有好处的,例如,Web 浏览器的应用就会保留很多用户不想丢失的状态,如多个被打开的标签页。
经典理解:
这个属性用来标记应用的 task 是否保持原来的状态,“true” 表示总是保持,“false” 表示不能够保证,默认为 “false”。此属性只对 task 的根 Activity 起作用,其他的 Activity 都会被忽略。 默认情况下,如果一个应用在后台呆的太久例如 30 分钟,用户从主选单再次选择该应用时,系统就会对该应用的 task 进行清理,除了根 Activity,其他 Activity 都会被清除出栈,但是如果在根 Activity 中设置了此属性之后,用户再次启动应用时,仍然可以看到上一次操作的界面。 这个属性对于一些应用非常有用,例如 Browser 应用程序,有很多状态,比如打开很多的 tab,用户不想丢失这些状态,使用这个属性就极为恰当。
android:clearTaskOnLaunch
这个属性用于设定在从主屏中重启任务时,处理根节点的 Activity 以外,任务中的其他所有的 Activity 是否要被删除。如果设置为 true,那么任务根节点的 Activity 之上的所有 Activity 都要被清除,如果设置了 false,就不会被清除。默认设置时 false。这个属性只对启动新任务(或根 Activity)的那些 Activity 有意义,任务中其他所有的 Activity 都会被忽略。
当这个属性值被设置为 true,用户再次启动任务时,任务根节点的 Activity 就会被显示,而不管在任务的最后做了什么,也不管任务使用 Back 按钮,还是使用 Home 离开的。当这个属性被设置为 false 时,在某些情况中这个任务的 Activity 可以被清除,但不总是这样的。
例如,假设某人从主屏中启动了 Activity P,并且又从 P 中启动了 Activity Q。接下来用户按下了 Home 按钮,然后由返回到 Activity P。通常用户会看到 Activity Q,因为这是在 P 的任务中所做的最后的事情。但是,如果 P 把这个属性设置为 true,那么在用户按下 Home 按钮,任务被挂起时,Activity P 之上的所有 Activity(本例中是 Activity Q)都会被删除。因此当用户再次返回到本任务时,用户只能看到 Activity P。
如果这个属性和 allowTaskReparenting 属性都被设置为 true,那些被设置了亲缘关系的 Activity 会被转移到它们共享的亲缘任务中,然后把剩下的 Activity 都给删除。
经典理解:
这个属性用来标记是否从 task 清除除根 Activity 之外的所有的 Activity,“true” 表示清除,“false” 表示不清除,默认为 “false”。同样,这个属性也只对根 Activity 起作用,其他的 Activity 都会被忽略。 如果设置了这个属性为 “true”,每次用户重新启动这个应用时,都只会看到根 Activity,task 中的其他 Activity 都会被清除出栈。如果我们的应用中引用到了其他应用的 Activity,这些 Activity 设置了 allowTaskReparenting 属性为 “true”,则它们会被重新宿主到有共同 affinity 的 task 中。
android:finishOnTaskLaunch
这个属性和 android:allowReparenting 属性相似,不同之处在于 allowReparenting 属性是重新宿主到有共同 affinity 的 task 中,而 finishOnTaskLaunch 属性是销毁实例。如果这个属性和 android:allowReparenting 都设定为 “true”,则这个属性好些。
android:configChanges
在 Activity 中添加了 android:configChanges 属性,目的是当所指定属性 (Configuration Changes) 发生改变时,通知程序调用 onConfigurationChanged () 函数。
android 4.0中的java.lang.StackOverflowError,而不是android 3.0中的
01-31 12:52:53.020: E/AndroidRuntime(10957): FATAL EXCEPTION: main
01-31 12:52:53.020: E/AndroidRuntime(10957): java.lang.StackOverflowError
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.graphics.Paint.getTextRunAdvances(Paint.java:1711)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.TextLine.handleText(TextLine.java:749)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.TextLine.handleRun(TextLine.java:972)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.TextLine.measureRun(TextLine.java:416)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.TextLine.measure(TextLine.java:295)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.TextLine.metrics(TextLine.java:269)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.Layout.getLineExtent(Layout.java:942)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.Layout.draw(Layout.java:405)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.text.BoringLayout.draw(BoringLayout.java:400)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.TextView.onDraw(TextView.java:5038)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:10978)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.AbsListView.dispatchDraw(AbsListView.java:2092)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:11083)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.AbsListView.draw(AbsListView.java:3398)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:11083)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.FrameLayout.draw(FrameLayout.java:450)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.ScrollView.draw(ScrollView.java:1524)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:10981)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:10981)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.widget.FrameLayout.draw(FrameLayout.java:450)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.View.draw(View.java:10981)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
01-31 12:52:53.020: E/AndroidRuntime(10957): at android.view.ViewGroup.drawChild(Vi
解决方法:
此堆栈与您拥有太多嵌套布局时获得的堆栈非常相似.我会运行layoutopt,看看你是否可以减少你的布局层次结构,看它是否修复它,对于Framework差异,我不能说它们是否减少了这个限制,或者是否更新的控件增加了它们的内部层次结构布局,这些都超出了限制.很难说…
https://developer.android.com/studio/tools/help/layoutopt.html
android 6 中 init.rc 的生成过程【转】
本文转载自:https://blog.csdn.net/quhj/article/details/51819638
android 系统开机是会有一个初始化过程 init ,整个初始化过程是根据配置脚本 init.rc 进行的。init.rc 文件位于 android 设备的根目录,在设备出厂是就确定了,一般用户无法修改,厂家也不希望用户修改,如果是资深人士,那就另当别论了。
不管在 android 的原生代码根目录,还是 soc 提供的目录下,在执行完 source build/envsetup.sh 之后,可以在代码根目录下使用
mgrep init.rc 命令,命令的输出大概揭示了 init.rc 的生成过程。
以下是我在 freescale 平台的输出结果:
./device/fsl/imx6/evk_6sl.mk:24: device/fsl/evk_6sl/init.rc:root/init.freescale.rc \
./device/fsl/imx6/sabreauto_6q.mk:20: device/fsl/sabreauto_6q/init.rc:root/init.freescale.rc \
./device/fsl/imx6/imx6.mk:370: system/core/rootdir/init.rc:root/init.rc \
./device/fsl/imx6/evk_6ul.mk:24: device/fsl/evk_6ul/init.rc:root/init.freescale.rc \
./device/fsl/imx6/sabresd_6dq.mk:20: device/fsl/sabresd_6dq/init.rc:root/init.freescale.rc \
./device/fsl/imx6/sabresd_6sx.mk:20: device/fsl/sabresd_6sx/init.rc:root/init.freescale.rc \
./device/fsl/imx6/sabreauto_6sx.mk:20: device/fsl/sabreauto_6sx/init.rc:root/init.freescale.rc \
./device/fsl/imx7/imx7.mk:359: system/core/rootdir/init.rc:root/init.rc \
./device/fsl/imx7/sabresd_7d.mk:24: device/fsl/sabresd_7d/init.rc:root/init.freescale.rc \
./device/generic/qemu/ranchu_arm64.mk:33: system/core/rootdir/init.rc:root/init.rc \
./device/generic/qemu/qemu_base.mk:42: init.rc \
./system/core/CleanSpec.mk:51:$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
./system/core/CleanSpec.mk:52:$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
./system/core/rootdir/Android.mk:4:# init.rc
./system/core/rootdir/Android.mk:5:# Only copy init.rc if the target doesn''t have its own.
./system/core/rootdir/Android.mk:9:LOCAL_MODULE := init.rc
./system/core/rootdir/Android.mk:24:# Put it here instead of in init.rc module definition,
./system/core/rootdir/Android.mk:25:# because init.rc is conditionally included.
./build/target/product/full_x86.mk:23:# that isn''t a wifi connection. This will instruct init.rc to enable the
./build/target/product/full_x86_64.mk:23:# that isn''t a wifi connection. This will instruct init.rc to enable the
./build/target/product/embedded.mk:35: init.rc \
./build/core/Makefile:801:recovery_initrc := $(call include-path-for, recovery)/etc/init.rc
行:
./system/core/rootdir/Android.mk:9:LOCAL_MODULE := init.rc
揭示了 android 原始的 init.rc 的位置以及生成动作
行:
./device/fsl/imx6/imx6.mk:370: system/core/rootdir/init.rc:root/init.rc \
揭示了 soc 厂家定制后还使用原始的 init.rc
行:
./device/fsl/imx6/imx6.mk:370: system/core/rootdir/init.rc:root/init.rc \
揭示了 soc 如何把自己定制的文件按照系统定义的名称,让 init.rc 包含到。
这个大概就是 init.rc 的生成过程了把,freescale 是直接使用了 android 原始的 init.rc 也可以直接使用自己的。
---------------------
作者:FisherQu
来源:CSDN
原文:https://blog.csdn.net/quhj/article/details/51819638
版权声明:本文为博主原创文章,转载请附上博文链接!
android @android:Theme.Dialog 和 @android:Widget.Button找不到
android @android :Theme.Dialog 和 @android :Widget.Button找不到是什么回事?
我们今天的关于Android CTS中neverallow规则生成过程的分享已经告一段落,感谢您的关注,如果您想了解更多关于activity 的属性 android:taskAffinity 和 android:allowTask、android 4.0中的java.lang.StackOverflowError,而不是android 3.0中的、android 6 中 init.rc 的生成过程【转】、android @android:Theme.Dialog 和 @android:Widget.Button找不到的相关信息,请在本站查询。
本文标签: