关闭

皇家豆瓣酱

19
原创
12
转载
3
译文
8
评论
39178
访问

2015十二月
23

android异常笔记

1.  Activity ca.ct.activity.OBaccaratActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@42db0500 that was originally added here  
  
       ~~~ 出现错误的情景是:当我点击返回键,退出一个activity进入另一个activity的时候,有一个dialog,或者是其他的组件在提示,但是这个时候我着急又很快的按了一下返回键就报这样的错误
       ~~~ 解决方法:在dialog中添加一下代码
public void onDestroy(){
	super.onDestroy();
	if(dialog !=null){
		dialog.dismiss();
		dialog =null;
	}
}

2.Fatal signal 11 (SIGSEGV) at 0x00000040 (code=1), thread 20476 (.example.new)
        ~~~出现错误的情景:同样的,某个页面有视频播放器,调用surface,和jni,当我点击返回键,然后在很快的点击一下以后,会报上面的东西,但是并没有java的异常或者其他提示信息出现
        ~~~解决方法:目前并没有找到解决的办法。也不知道什么原因。但是有一篇博客写的和我的qi类似,但是照着他的方法并没有解决我的问题。http://blog.csdn.net/sonikk/article/details/9217181

3.android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    ~~~在非主线程中直接设置组件会抛出这样的异常。比如我为了简单在线程中为TextView.setText().这个在低版本中是可以运行。高版本中操作页面的必须在主线程中。这里只能用handler

4,ava.lang.IllegalStateException: Could not execute method of the activity
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException

说白了就是无法执行和activity相关的方法,为什么无法执行呢,因为你给系统的是空引用,出现空指针错误
造成这种因素的原因很多,我目前已知的,就是代码的顺序问题,在onCreate方法中。

5.has leaked window com.android.internal.policy.impl.PhoneWindow$ that was originally added here

~~~出现错误的情景

经常在应用中需要处理一些耗时的工作,诸如读取大文件、访问网络资源等。为了避免因程序假死而带来的糟糕用户体验,通常我们可以通过线程+Handler或者Android提供的AsyncTask来解决该问题,并一般以ProgressDialog等提示性控件来告知用户当前的程序进度。而标题中描述的异常则会常常出现在这样的场景中,并且往往掩盖了导致异常的真正的罪魁祸首。

  ~~~问题原因

从异常描述中,大致的意思是存在窗口句柄泄露,即未能及时销毁某个PhoneWindow。而这往往误导了我们,把过多的精力放在查找所谓的内存泄露上了。其实存在这么一种情况,即因我们在非主线程中的某些操作不当而产生了一个严重的异常,从而强制当前Activity被关闭。而在关闭的同时,却没能及时的调用dismiss来解除对ProgressDialog等的引用,从而系统抛出了标题中的错误,而掩盖了真正导致这个错误的异常信息。

  ~~~解决方法之一

本解决方法并不能真正的解决问题,但是在一定程度上可以将真正导致错误的异常信息显露出来。即重写Activity的onDestroy方法,在方法中调用dismiss来解除对ProgressDialog等的引用。


6.遇到过两次,在RelativeLayout中当我将两个组件调换位置一个在上一个在下时,在activity中实例化这个组件就会报类型转换异常,目前没找到问题原因。

7.Unable to start activity ComponentInfo{com.example.new855/ca.ct.activity.FanTanActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class
    Caused by: java.lang.OutOfMemoryError:
            理由以及原因:At runtime, Android resize's images based on need (based on the screen size and resolution). It uses Bitmap's for doing the resizing internally. Which, obviously, is very memory intensive (kinda allocates memory like crazy). One quick way to fix such issues can be, that you copy all drawable files to drawable-ldpi, mdpi, hdpi folders. This way android will just pick up the files from these folders and not resize them.
		简单点内存泄漏,这个是一大篇幅的内容,需要慢慢去研究。

8.IllegalArgumentException: View not attached to window manager
引起的原因:A应用在使用Intent显示启动其他应用,当关闭其他应用显A应用界面时报错。

解决方法1:

A应用使用startActivityForResult(intent)启动其他应用

解决方法2:

关闭其他应用时每次都使用Intent重新拉起一遍A应用

在A中启动B,B中有线程操作,结束时涉及到对话框的dismiss。如果在操作尚未结束时,按下HOME键,线程后台操作。此时重新进去A,等到线程操作完成就会出现这个异常。此时应该做一个判断,如下:

// Dismiss the Dialog only when the parent Activity is still alive.
if (SelectContactsActivity!=null&&!SelectContactsActivity.this.isFinishing()) {
      mProgressDialog.dismiss();
}



9.IllegalArgumentException: connection is null
  有时候同样的代码,在一个机子上可以正常执行,在另一个机子上就会报这也的异常。这是因为绑定服务的时候bindService(intent, null, BIND_AUTO_CREATE);这也写的,但是高版本中ServiceConnection不能为空。所以要new一个出来。应该这也写
bindService(intent, new ServiceConnection() {
	@Override
	public void onServiceDisconnected(ComponentName name) {
		// TODO Auto-generated method stub
	}
	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		// TODO Auto-generated method stub
	}
}, BIND_AUTO_CREATE);  

10、 你后台的Activity被系统回收怎么办:onSaveInstanceState

  当你的程序中某一个Activity A 在运行时中,主动或被动地运行另一个新的Activity B  这个时候A会执行

  Java代码

    public void onSaveInstanceState(Bundle outState) {
 		super.onSaveInstanceState(outState);
 		outState.putLong("id", 1234567890);
    }
  public void onSaveInstanceState(Bundle outState) {
  		super.onSaveInstanceState(outState);
  		outState.putLong("id", 1234567890);
  }

  B 完成以后又会来找A, 这个时候就有两种情况,一种是A被回收,一种是没有被回收,被回 收的A就要重新调用onCreate()方法,不同于直接启动的是这回onCreate()里是带上参数savedInstanceState,没被收回的就还是onResume就好了。

  savedInstanceState是一个Bundle对象,你基本上可以把他理解为系统帮你维护的一个Map对象。在onCreate()里你可能会用到它,如果正常启动onCreate就不会有它,所以用的时候要判断一下是否为空。


11. 如何将SQLite数据库(dictionary.db文件)与apk文件一起发布?

 

  解答:可以将dictionary.db文件复制到Eclipse Android工程中的resaw目录中。所有在resaw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到resaw目录中

12.Gradle DSL method not found: 'runProguard()'

要让sync成功,改下gradle的版本就可以了,如下:

dependencies {         classpath 'com.android.tools.build:gradle:0.14.1'         // NOTE: Do not place your application dependencies here; they belong         // in the individual module build.gradle files     }

但是真正的解决办法是将一下内容更换就可以

buildTypes {
    release {
        runProguard false // 已经被废弃并且停止使用了
        ......
    }
}

new:

buildTypes {
    release {
        minifyEnabled false // 替代的方式
        ......
    }
}


13:Gradle version 2.10 is required. Current version is 2.8 Error

https://services.gradle.org/distributions/gradle-2.10-all.zip  从该链接下载文件
Settings > Builds,Execution,Deployment > Build Tools > Gradle >Gradle home path。 修改2.8的目录改为2.10



14:cannot perform this action after onsaveinstancestate。

百度了一下,都说将commit替换成commitAllowingStateLoss就可以了。(我的问题在于在onResume()方法内使用fragment的commit)这样替换的确解决了问题,但是后来仔细研究了下才发现事情没这么简单。

抛出异常的原因
众所周知,Android系统可以为了释放资源在任意时刻终止进程,有些后台运行的进程可能都不会有任何提示的被杀。而onSaveInstanceState()就是给activity一个最后机会去保存它需要保存的东西,bundle对象就是所要保存信息的载体被传到系统服务进程,如果有朝一日该activity被重新创建时,该对象就会被传回帮助activity重现先前的状态。那么抛出异常的原因在哪儿呢?事实上bundle对象仅仅是activity在调用onSaveInstanceState()时的快照,也就意味着在onSaveInstanceState()后使用FragmentTransaction#commit()时,bundle并没有对该transaction作保存而在activity还未恢复到最初状态时调用,这样便会出现UI的丢失,为了保护用户体验IllegalStateException就被抛出了。
版本差异

如何避免
1 在activity生命周期方法内使用FragmentTransaction#commit()应谨慎
   多数的应用会在onCreate()中使用该方法,所以不会遇到这样的问题,但如果在onActivityResult(), onStart()或onResume()中使用时就有可能遇到了。那么如果因为一些原因一定要在这些方法中使用FragmentTransaction#commit()该怎么办呢(比如说从下一个页面回来时需要刷新界面的时候)。这时最好在FragmentActivity#onResumeFragments()或者Activity#onPostResume()中使用。这两个方法会保证在activity恢复到最初状态后被调用。
commitAllowingStateLoss()只能当做最后的手段
    commit和commitAllowingStateLoss()之间的唯一区别是如果状态丢失后者仅仅是不抛出异常而已。一般情况下你不会想用这个方法因为它仍然会有状态丢失的可能。
由于在百度上看到多数的解决办法是使用commitAllowingStateLoss(),并非说这个办法不行,而是尽量精益求精,找到问题的本质所在。翻译有出入 ,请尽量看原文。
详细的信息请参考原作者文章:http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html


15:Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.MainActivity}: java.lang.IllegalStateException: This app has been built with an incorrect configuration. Please configure your build for VectorDrawableCompat.

产生的原因是:com.android.support:appcompat-v7与rasterized vectors不兼容,gradle2.0及其之上,library的资源没有栅格化,所以不会发生这个问题

2. 解决方案:

1.在projectgradle中将gradle版本改为2.0或者之上


2. 再次运行,此时控制台输出异常:

Warning:Gradle version 2.10 is required. Current version is 2.8. If using the gradle wrapper, try editing the distributionUrl in xxx\bbb\gradle-wrapper.properties to gradle-2.10-all.zip

按照路径所指出的地址,找到文件gradle-wrapper.properties,编辑最后一句版本号为日志中所输出的版本

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

3. 再次运行,还是错误,原因是你还没有下载gradle-2.10

这时可以从网上下载一个gradle-2.10.zip并解压,然后放到AndroidStudiodd的默认gradle配置目录

然后再在AndroidStudio中做一下设置,如下图





img

wr751811032

等级:

排名:千里之外

博客专栏
文章分类
文章存档
阅读排行
评论排行
推荐文章
最新评论
img