为什么手机无法执行应用? 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 ...
随机推荐
- imageNamed 、imageWithContentsOfFile、 initWithContentsFile区别
[UIImage imageNamed:]只适合与UI界面中的贴图的读取,较大的资源文件应该尽量避免使用 用UIImage加载本地图像最常用的是下面三种: 1.用imageNamed方法 [UIIma ...
- Windows远程连接局域网内或同一个网段或同一个路由器的某台机器
http://bbs.shendu.com/thread-1443245-1-1.html 亲自试验,具体操作如下: 我现在有三台机器和对应的ip地址(ip地址自己手动填写,不会网上搜) ...
- GoogleMapsV3-----基础地图(自定义消息提示OverlayView) (转)
<html> <head> <title> </title> <title></title> <style type ...
- JMeter ----请求数据参数设置-自动增长变量
使用Jmeter性能测试的时候, 需要录入一些测试数据, 当这些数据要插入数据库的时候, 数据库通常会要求数据不能重复, 所以无法使用同一个数据反复进行测试, 这时候就需要在每次请求的时候使用不同的请 ...
- Remote 'attachhome' failed on nodes:XXX
RAC安装过程中,在安装GI的时候报如下错误: 解决方法: 根据提示执行以下脚本 $ /u01/app//grid/oui/bin/runInstaller -attachHome -noCluste ...
- ASP.NET Helper
- php log类
个人抽离出来一个超级简易但是实用的代码段 public static function WriteLog($msg,$module = null,$logLevel = "DEBUG&quo ...
- django打印字典
- jenkins 发送邮件模板
jenkins 发送邮件模板 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 安装ubuntu和windows双系统后,如何修改默认启动项
在安装了Ubuntu16.04系统之后,系统会默认自启动Ubuntu16.04,而我们大多数情况下可能都在使用windows系统,不修改默认设置,不经意间便会启动了Ubuntu16.04,通过我的经历 ...