为什么手机无法运行应用? Values之谜
来源:互联网 发布:淘宝卖假货被公安抓了 编辑:程序博客网 时间:2024/05/22 09:02
欢迎Follow我的GitHub, 关注我的CSDN, 精彩不断!
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: mainjava.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@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_home); // ...}
调用AppCompatActivity#setContentView
, Activity
绑定layout布局.
// DataBindingUtil.javapublic 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@Overridepublic 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)就不能启动呢? 原因很简单, 就是因为开源项目的主题资源设置有误. 默认主题在AndroidManifest
的theme
属性中设置.
<application android:theme="@style/AppTheme">
点击IDE的AppTheme
跳转至声明, 发现只有一处, 即在values-v23
中声明.
原因
对于资源属性而言, 系统默认查找与匹配低于当前API等级的属性, 保证高版本属性不会在低版本中执行. 因为高版本会添加更多的新接口, 低版本无法找到, 强制使用可能导致异常甚至崩溃, 所以禁止访问高版本的属性.
解决
理解了问题的所在, 解决方案就非常简单. 为了支持最低API以上的全部系统, 在默认的values/themes.xml
中, 添加AppTheme
属性即可.
<style name="AppTheme" parent="Base.AppTheme"/>
问题虽小, 但不可忽视, 否则就只能在某些手机可用, 在某些手机崩溃, 摸不着头脑. 在开发中, 优先在默认values
文件夹中添加属性, 如果需要额外支持, 在其他高版本values-vXX
中再添加. Do you get it?
That’s all! Enjoy it!
- 为什么手机无法运行应用? Values之谜
- adb无法运行项目到手机 无法安装应用
- 安卓手机:你的手机没有安装google play服务,因此无法运行此应用
- android 手机适配之values适配dimen值
- as运行应用小米手机运行失败
- Android Eclipse无法运行应用?
- AVD可以运行android应用无法运行
- CodeBlock安装后无法运行为什么?无法找到编译器?
- CodeBlock安装后无法运行为什么?无法找到编译器?
- 中兴NFC手机无法读应用问题
- Android Studio 手机 Wifi 运行应用
- 电容屏:为什么带手套无法进行操作手机?
- netduino无法调试运行应用情况解决
- 此应用无法在电脑上运行
- Android之手机电池电量应用
- 为什么tomcat下无法运行两个struts2项目?
- 为什么在Pool中传递Queue对象无法运行
- 为何偶的手机无法运行Hello World?
- Android例子—简单定时后台线程的实现
- virtualenv python虚拟环境
- Unity3D 使用“Shift+Tab”和“Tab”键 上下切换 UGUI下 Dropdown和inputfield等控件的控制顺序
- zookeeper 集群重启之后无法使用
- linux下用phpize给PHP动态添加扩展
- 为什么手机无法运行应用? Values之谜
- 基于直方图的图像增强算法(HE、CLAHE、Retinex)之(二)
- 段错误产生原因;和;计算机大端小端概念和判别方法
- 使用BigDecimal进行精确计算工具类
- 智能指针RefBase、sp、wp原理与简单应用
- ELK系列一:CentOS7安装elasticsearch5.x
- 使用VLC开发库,预览采集卡视频方法
- Vue2.0 子组件传值给父组件
- Java中static的和final