为什么手机无法执行应用? Values之谜
CSDN: http://blog.csdn.net/caroline_wendy/article/details/68923156
在GitHub上Clone的某开源Android项目, 下载配置, 完毕构建, 在手机上能够安装, 可是无法执行. 项目的编译版本号(compileSdkVersion)是25(7.1), 最低的兼容版本号(minSdkVersion)是19(4.4), 手机的系统版本号是21(5.0), 已经满足应用的最低执行条件. 然而, 在同样系统版本号(25, 7.1)的模拟机上, 应用执行正常.
在我的手机执行应用时, 报错例如以下:
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.saulmm.cui/com.saulmm.cui.HomeActivity}:
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at android.support.v7.app.AppCompatDelegateImplV9.createSubDecor(AppCompatDelegateImplV9.java:359)
at android.support.v7.app.AppCompatDelegateImplV9.ensureSubDecor(AppCompatDelegateImplV9.java:328)
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:289)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:276)
at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:261)
at com.saulmm.cui.HomeActivity.onCreate(HomeActivity.java:42)
定位
问题起源于DataBindingUtil#setContentView, DataBindingUtil绑定layout布局.
// HomeActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
// ...
}
调用AppCompatActivity#setContentView, Activity绑定layout布局.
// DataBindingUtil.java
public static <T extends ViewDataBinding> T setContentView(Activity activity, int layoutId,
DataBindingComponent bindingComponent) {
activity.setContentView(layoutId);
// ...
}
终于是Activity代理实现类AppCompatDelegateImplV9实现setContentView的详细逻辑. 通过ensureSubDecor方法创建DecorView, 填充Activity的自己定义布局resId, ensureSubDecor再调用createSubDecor方法创建DecorView.
// AppCompatDelegateImplV9.java
@Override
public void setContentView(int resId) {
ensureSubDecor(); // 创建并初始化DecorView
ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);
mOriginalWindowCallback.onContentChanged();
}
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
mSubDecor = createSubDecor();
// ...
}
}
createSubDecor方法, 依据应用的样式主题(Theme)设置根布局DecorView的样式, 并执行初始化. 当未含有AppCompatTheme_windowActionBar属性时, 则觉得主题未设置, 并抛出异常IllegalStateException.
// AppCompatDelegateImplV9.java
// 依据布局样式Style设置根布局DecorView的样式
private ViewGroup createSubDecor() {
TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
// 没有布局属性
if (!a.hasValue(R.styleable.AppCompatTheme_windowActionBar)) {
a.recycle();
// 问题所在!
throw new IllegalStateException(
"You need to use a Theme.AppCompat theme (or descendant) with this activity.");
}
// ...
}
为什么API 25的模拟器能够启动, 我的手机(API 21)就不能启动呢? 原因非常easy, 就是由于开源项目的主题资源设置有误. 默认主题在AndroidManifest的theme属性中设置.
<application android:theme="@style/AppTheme">
点击IDE的AppTheme跳转至声明, 发现仅仅有一处, 即在values-v23中声明.
原因
对于资源属性而言, 系统默认查找与匹配低于当前API等级的属性, 保证高版本号属性不会在低版本号中执行. 由于高版本号会加入很多其它的新接口, 低版本号无法找到, 强制使用可能导致异常甚至崩溃, 所以禁止訪问高版本号的属性.
解决
理解了问题的所在, 解决方式就非常easy. 为了支持最低API以上的所有系统, 在默认的values/themes.xml中, 加入AppTheme属性就可以.
<style name="AppTheme" parent="Base.AppTheme"/>
问题虽小, 但不可忽视, 否则就仅仅能在某些手机可用, 在某些手机崩溃, 摸不着头脑. 在开发中, 优先在默认values目录中加入属性, 假设须要额外支持, 在其它高版本号values-vXX中再加入. Do you get it?
That’s all! Enjoy it!
为什么手机无法执行应用? Values之谜的更多相关文章
- Linux下的Jenkins作为hub,Windows作为node节点,在Android手机上执行自动化脚本
1.在Linux上放selenium-server-standalone-2.53.0.jar,在jar包目录下执行命令java -jar selenium-server-standalone-2.5 ...
- 【初体验】macos下android ndk交叉编译hello world,并拷贝到android手机上执行
1.机器上以前安装了java 1.8(貌似android ndk不需要java) 2. 下载android ndk,版本是android-ndk-r14b (比较奇怪,我下载了最新的android-n ...
- 使用Java让android手机自动执行重复重启
public static void main(String[] args)throws IOException,Exception { for(int j=0;j<10;j++) { Thre ...
- C#跨平台手机应用开发工具Xamarin尝试 与Eclipse简单对比
Xamarin 支持使用C#开发基于Android.IOS.WindowsPhone应用开发,最大特点C#+跨平台,详细说明问度娘. 安装 研究 想体验研究的点击查看页面 Xamarin For Vi ...
- x86架构手机跑安卓好吗?(脑补)
华硕低价位手机ZenFone一推出就掀起市场话题,许多人也对ZenFone所采用的Intel Atom处理器有所意见,深怕其相容性问题无法正确执行应用程式App,这究竟是怎么回事呢? Intel近几年 ...
- 技术解析:锁屏绕过,三星Galaxy系列手机也能“被”呼出电话
近期,由两位安全研究人员,Roberto Paleari及Aristide Fattori,发布了关于三星Galaxy手机设备安全漏洞的技术细节.据称,Galaxy手机可在锁屏状态下被未授权的第三方人 ...
- Android手机一键Root原理分析
图/文 非虫 一直以来,刷机与Root是Android手机爱好者最热衷的事情.即使国行手机的用户也不惜冒着失去保修的风险对Root手机乐此不疲.就在前天晚上,一年一度的Google I/O大会拉开了帷 ...
- 泛泰A900 刷4.4专用中文TWRP2.7.1.1版 支持自己主动识别手机版本号(全球首创)
因本人手上的A900S已砖, 所以临时弄不了ROM了, 先上传之前已经弄好的刷4.4专用的新版TWRP recovery 2.7.1.1 这个版本号是我自己定义的,为差别之前公布的2.7.0.0版( ...
- 让Qt for Windows Phone 8.1在真机上执行
让Qt for Windows Phone 8.1在真机上执行 前面几篇博文是为这篇文章做铺垫的,终于目的为的是使用Qt框架制作出可以在Windows Phone 8.1真机上执行的程序.因为Qt f ...
随机推荐
- windows安装tensorflow GPU
一.安装Anaconda Anaconda是Python发行包,包含了很多Python科学计算库.它是比直接安装Python更好的选择. 二.安装Tensorflow 如果安装了tensorflow, ...
- Android快速开发不可或缺的11个工具类(下载)
功能分类:工具 支持平台:Android 运行环境:Eclipse 开发语言:Java 开发工具:Eclipse 源码大小:11.45KB 下载地址:ht ...
- 关于JavaScript中Get/Set访问器
有时候大家可能会纳闷,在使用JavaScript的时候,只需要给一个系统变量赋值就可以触发一系列操作去相应. 但是我们在写Js的时候,修改了一个自定义变量,却连个P都没有.是不是很郁闷呢? 其实,我们 ...
- How to develop and deploy ActiveX control in C#
Link:https://blogs.msdn.microsoft.com/asiatech/2011/12/05/how-to-develop-and-deploy-activex-control- ...
- js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象
我最近在做一个vue + element-UI + vue-resource + vuex项目的时候,遇到了一个对象的问题. 当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后 ...
- SQL Server数据库命名规范
良好的命名习惯是一种美德,下面是个人整理的数据库命名规范: 数据库命名规范: 1. 数据库名: 1.1)用产品或项目的名字命名: 1.2)Pascal Case,如 ...
- Android 自定义属性动画&Camera动画
摘要: Android 自定义属性动画&Camera动画 1.相关知识点 对于Androi的帧动画,可以制作gif图片,有时为了能够动态的生成帧动画,就得需要使用代码构建了 Animati ...
- Java将数据库数据导入EXCEL
一般的数据库数据怎么导入excel中呢??这让人非常疑惑,今天我找到了一个方法能够实现 须要导入一个第三方包下载地址 详细内容例如以下: 里面含有指导文档,index.html里面含有怎样读取数据库文 ...
- MVC 之Action
下面我要重新温习一下,MVC控制器中的Action方法相关概念: 1.Action方法必须是public,不能是private或者是protected; 2.Action方法不能够被重载: 3.Act ...
- Linux数据库:MYSQL启用和查看二进制日志
在/etc/my.cnf文件中[mysqld]下加上: server-id = 1 (在整个Mysql集群中保证唯一) log-bin = binlog log-bin-index = binlog ...