异常分析 (空间太小)

  1. 出现 异常的原因:
  2. 碎片化 。
  3. MobileAPI脏数据
  4. 混淆时没有Keep 要使用的类或者方法  。 
 
  本地开发要与线上分开  
 异常信息中提示  “方法名”unknown source 内容 ,会加大我们准确定位的crash的难度 。
 导致 unknown source 的原因
    1.执行javac时丢失文件名和行号 
       我们要在javac编译时保留debug信息  <javac  debug="true" debuglevel="source ,line" ....>
   2. 执行了代码混淆丢失文件名个行号
       在proguard文件中增加  -keeparttributes  SourceFile,LineNumberTable
 
 
 
 
名称  关键字  发生频率 发生原因 解决方式
名称 关键字发生频率发生场景解决方式
 空指针NullPointException 1.调用接口时,过于信息返回数据 ,一旦为空的Json,引发崩溃
2.在使用asyncTask调用接口返回数据,在asyncTask的doInBackGround中,会因为有空而崩溃
3.页面跳转前后,跳转前的数据没有准备好 ,
4.APP过多的使用全局变量 ,一旦发生内存回收,这些全局变量会被设置为空,而又没有考虑这种情况 。
1.方法需要对传入的参数判空或者try...catch后再继续使用
2.
3.调用外部接口确保返回值不为空,甚至确保执行该接口不会抛异常,导致程序的退出。
4.避免使用全局变量,不到万不得已不要使用全局变量,也要使全局支持序列号本地机制,一旦为空就通过fang
角标越界IndexOutOfBoundsException(基类)
StringIndexOutOfBoundsException(字符串截取越界)
ArrayIndexOutOfBoundsException(数组越界)
 1.由于程序不严谨导致
2.在使用字符串时,经常使用subString(start ,end) 。start ,end超过字符串长度,就会崩溃 。

1.在遍历一个数组/集合时要预判数组集合是否为空 ,长度是否大于0;
2.在使用数组、集合中的元素时,要预判数组集合长度是否有那么长 。
试图调用一个空对象的方法Attempt  to invoke virtual method on a null object reference
试图在一个空对象引用调用虚方法
 1.在一个activity中,调用另一个activity的方法 ,为此在B中建立一个static 变量 ,当这个static 变量被回收时 ,便会有异常。
2.推送 ,点击推送消息根据事先定好的协议,跳过首页直接进入二级甚至三级 。这时二级界面要是有首页的某个对象是,该对象势必为空。
没实例化
类型转换异常ClassCastException:classA cannot be cast  to classB Object x =new Integer(0)  ;
String str  =(String)x;
将安全类型转换函数 
把字符串转换为整数 小数或布尔类型时,我们要为指定转换失败时的默认值。否则,就会得到一个空值。
数字转换错误NumberFormatException 在数据类型转换过程中 ,如果转换不成功,一般会抛出ClassCastException的异常 。有一个例外 ,字符型转换为数字失败时 ,时Android系统会抛出NumberFormatException异常 ( 
如String abc ="123****45"
    int result  =Integer.parseInt(abc) ;
这种情况发生在服务器返回数据没有按照约定返回整数而是字符串 ,客户端必须考虑到这种情况,如果转换失败,必须有默认值否则直接崩溃
声明数组长度为-1NegativeArraySizeException 数组大小为负值异常 ,单前使用负数大小创建数组时抛出该异常。场景
String[] arg1 =new String[args.length -1] ; args没有元素时 。
如果数组长度是由另一个变量动态得到时 ,要保证中括号[] 中的值必须大于0
遍历集合的同时删除其中的元素ConcurrModificationException 1.遍历一个集合不能删除该集合中的元素
2.多线程中删除同一个集合的元素(线程安全)
解决方案:需要再定义一个列表结合delList ,来保存需要删除的对象
比较器使用不当comparsion method violates its general contrac 因为Comparator 的compare的方法使用的姿势不对(他是基于插入排序与归并排序算法相结合的产物 ,要比日常所用的冒泡排序算法快很多)(单元测试)
当除数为0Java.lang.ArithmeticException:divide by zero 当程序中执行一个除法时 ,如果除数为0 ,就会发生该情况
.
 
不能随便使用aslist AbstractList  (add    remove)
 子类    ArrayList  (add    remove)
            Arrays$Arraylist  (没有实现 (add  he remove)
 
找不到类(一)classNotFoundException 当我们动态加载一个类时候 ,如果该类运行时找不到,就会抛异常 如 
class.forName("com.company.package.class") ;
 由于类的全名称是字符串形式 ,这个很有可能是不正确 。
还有 findSystemClass("classname")
loadClass("classname") ;
 
找不到类(二)NoClassDefFoundError ClassA obj= new ClassA() ; 打包B和A分别位于不同的dex中 ,这时在A所在的dex中把A类删除了
通常插件化编程会扯出这个异常因为要使用DexClassLOder。
 
activity 相关异常

   
找不到ActivityAndroid content,activityNotFoundException:NO activty found to handle Intent{....} 1.错误原因  URL 不是以http开头 
Uri uti =Uri.parse("www.baidu.com"); 
Intent intent   =new Intent ........ 
2.打开SD卡上的一个html页面时 ,没有为Intent指定打开Html页面所需要的浏览器 
3.调用百度地图时openBaiduMapNavi 手机没有安装百度地图客户端 。(要判读是否安装)
 
不能实例化activityjava.lang.RuntimeException:Unable to instantiate to activity ComponentInfo 1.通常没有AndroidManifext.xml  清单中注册activity  。
2.系统处于异常状态(内存不足)导致部件初始化 。

 
找到serviceJava.lang.RuntimeException:Unable to instance receiver 1.检查代码中是否有Class.forName("Class1")
2.ProGuard 会将class1 混淆 ,从而找不到这个类 。
 
不能启动BroadcastReceunable to start  reciver 1.在推送时,会和APP事先定义好协议,点击推送消息就跳过首页直接进入二级页面。
2.Content中有一个startActivity方法 ,Activity继承自Content ,重载startActivity方法,如果activity使用startActivity方法,不会有任何限制,如果使用Context的startActivity方法的话,就需要开启一个新的task,就需要开启一个新的task ,就会出现异常需要添加一个fiag
使用activity以外的content来startActivity ,比如BroadCastReceiver,就必须为Intent.FLAG_ACTIVITY_NEW_TASK,否则就会抛异常 。 
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult不能回传failure delivering result ResultInfo{who=null  ,request =0 ;result=-1} startActivityForResult,传回来的可key是A ,但按照B这个Key来取值 
猴急的fragmentFragment not attacher to Activity  因为fragment在还没有Attach到activity时,调用诸如getResource这样的方法 。
如getResource.getString(R.string.app_name) ;
解决方案 
if(isAdded){
getResources().getString(R.string.app_name)}
isAdd方法是Android系统提供的,它只有在fragment被添加到所属activity后才会返回ture。

序列号相关异常
   
实体对象不支持序列号Parcelable encountered IOEXception writing serializable  object(name=xx) 如 :该类里面存在自定义实体 ,而该自定义实体未序列化。。。。 
序列化时未指定ClassLoaderBadParcelableException:ClassNotFoundException when unmarshalling 在使用Parcelable 机制时 。
a =in.readParcelable(null) ;
private MyParcelable(Parcel in){ 
mStr =in.readString() ;
a=in.readParcelable(ClassA.class.getClassLoader())
}
ClassLoaderclassNotFoundException 。 当ClassLoader为空时系统采取默认的ClassLoader。
Android有两种ClassLoader:framework  classLoader和apk ClassLoader ,其中framework ClassLoader知道怎么加载Android的系统的内部的类 ;apk ClassLoader知道怎么加载我们自己写的类 ,也知道怎么加载Android系统的内部的类 。在APP刚启动时,默认的ClassLoader是apk ClassLoader ,但在系统内存不足应用会被系统回收再次启动的,这个默认的ClassLoader会变成framework ClassLoader  ,所以对于我们自己的类会报classNotFoundException 。
 
反序列化时发现类找不到:被ProGuard混淆导致的崩溃parcelable  encountered ClassNotFoundException reading a  Serializable object .. ProGuard 对于Class.forName(className)中的class无能为力,他会将这个class混淆的面目全非,于是在反序列化时找不到这个类。在ProGuard中keep这个类
反序列化时发现类找不到:传入畸形数据
(安全漏洞)
Parcelable encountered  ClassNotFoundException reading a Serializable  object(name  =某个类名称) 1.由于正APP中使用getSeriaizableExtra() 的 api, 
APP开发人员没有对传入的数据做异常判断,别的有企图的人可以通过传入畸形数据,导致本地拒绝服务
2.传入简单数据,比如Integer  ,就会抛出类型转换异常classCastException
2.当传入自定义的可序列化对象时,就会抛出上述带有ClassNotException 的异常信息

 
反序列化时出错Could  not read input  channel  file  description from parcel 一般是因为Intent 传递的数据太大 ,貌似大于1MB  就会崩溃。也有可能是fileDescripter太多而且没有关闭 ,或者looper太多没有退出导致的 
列表相关异常

   
adpter数据变化但是没有通知listview  adapter的内容变化了 ,但是相应的listview并不知情 1.保证adapter的数据在在主线程中修改
2.及时的调用notifyDataSetChange方法
     
listview滚动时点击刷新按钮后崩溃  滚动时调用getCount ,回调用getView,这时将数据clear了  。会报IndexOutOfBoundsException:Invalid  index  30 ,size  is  1 ;在listview滚动时将刷新按钮设置为不可点击
Abslilstview 的obtainView  返回空指针 。 Abslilstview 的obtainView 方法获取不到view ,其原因在于getview方法在某些时候返回nullgetView的第二个常数convertView是不会为null ;
在getView返回值得时候,判断一下是否为null  ,如果为null ,则放回convertView 。
Adapter数据源发生变化但是没有notifyDataSetChanged pageAdapter对于notifyDataSetChanged()和getCount()的执行顺序是非常严格的才,系统跟踪count的值 ,如果这个值和getCount返回值不一致,就会抛出这个异常 。为了保证getCount总是返回一个正确的值 ,那么在初始化viewpage时应该先给adapter初始化内容后再将该adapter传递给viewpage ,如果不这样处理 ,在更新adapter的内容后 ,应该调用一下adapter的 notifyDataSetChanged 。

窗体相关的异常:基本上都是dissmiss方法销毁对话框的时候 ,activty已经不存在。
   
窗口句柄泄露 非主线程中的某些操作不当而引起的异常,从而导致强制关闭当前activity。而还未及时的调用dismss来解除Dialog等引用 。在onDestroy()方法中调用dismiss来解除对dialog的引用 。
dialog.dismiss() ;
view not attached to widow manager 在一个费时的线程,在任务开始时显示对话框,任务结束时再销毁对话框,在期间如果activity因为某种原因有重新启动,那么Dialog调度dismiss方法的时候windowManager检查发现Dialog所属Activity已经不存在,所以会报
view not attached to widow manager

要正确使用对话框 ,
(1)不要在非UI线程中使用对话框创建显示和取消对话框 。,那么对于异步操作显示对话框怎么办?
Activty都要有相应的操作对话框回调 ,比如: 
.onCreateDialog .showDialog .dimissDialog  .removeDialog .
(2)一定要让对话框对象在activty的可控制范围内核生命周期之内。如对话框一定要是Activty的成员变量,并且再让对话框变量活跃在activty的Oncreat和OnDestory的方法之间 。
窗体在不恰当的时候获取了焦点。 在popoupWindow显示之前,就把焦点赋予它。
一般发生在Android2.3时出现
进行兼容。。。

token null  is not  for an application 在实现Android浮窗时 ,Context不正确 
AlertDialog.Builder(mcontext)所接的getAPPAction——Context()获取的Context,而应该是activty的实例,因为只有一个activty才能添加一个窗体。
 
permission  denied  for  this windown  type 在使用WindowMagnager.Layout.TYPE_SYSTEM_ALERT涉及window type 权限问题 。解救办法的在配置文件中添加权限 
<!---显示系统窗口权限--> _ALERT_WINDOW
<!---在屏幕最顶部显示addview--> _OVERLAY_WINDOW

is your  activty running 1.当我回来,你已不在 。这种Crash 与弹窗密切相关 ,由于

2.在 onCreate 方法中 ,想要弹出PopupWindow,当参数parent为空时 ,就会报上述的错误,因为PopupWindow依赖于activty ,而activty的OnCreate还没执行完 ,那么肯定会报错。
2.可以通过延迟(handle)来实现这个效果。。。
添加窗体失败   
AlertDialog.resolveDialogTheme
 1.在B页写了一个show方法 ,控制AlertDialog的弹出和隐藏 。在A页面却要调用页面B页面的show方法,于是就崩溃了。
2.在TabActivty中切换Tab ,容易产生这个Crash ,因为在new对话框时,参数content指定成了this
,即指向当前子activty的content,但是子activty是动态创建的 ,不能保证一直存在,其父activity的content则是隐藏的,所以将this替换为getParent()即可,
1.
this specifiied childed already has a parent  在使用儿子时要先要调用其父的remove -view 方法,解除父子关系 。 
子线程不能修改UI    
不能再子线程操作AlterDialog和Toast   
资源相关的异常()

   
Resources$NotFoundException  因为参数int resID 错误 。我们把String 赋值给int的ResId ,所以编译器找不到正确的resource而报错误 。 
StackOverefiowError  Layout布局文件结构嵌套太深 ,我们应该尽量控制在5层以上 。要经常使用Hierarchy View对其进行优化,移除不必要的试图。 
在APP退出的时候APP有多个线程,那么在退出APP的时候可能不能完全关闭APP,及时使用finish方法也无法做到 ,必须使用System.exit(0)这样的语句才可以。这是因为finish方法只能退出当前的activity ,但是还有其他activty未关闭,这些activty中没有结束的线程,从而还有一些资源没有释放。而exit(int code)方法可以使进程退出能保证把所有的线程的栈空间释放,否则会有线程残留空间无法释放从而无法回收。将会导致该进程新建时栈空间不足,从而发生StackOverefiowError异常。
无论哪种StackOverefiowError异常都是由于无线递归引起的,在JVM中有一个栈,预设了一个深度,当超出这个深度时就会抛出StackOverefiowError。
unstatisfiedLinkError .so格式的文件没有加载到 ,检查libs的aremeabi目录下的.so文件是否存在 。不能只看aremeabi 还要看x86下.so文件是否存在,如果没有,在x86的设备上依然是加载不到的。cpu指令集在Android aremeabi aremeabi-v7a mips 和   x86 ,所以处理so文件要格外小心  。
aremeabi 与 aremeabi-v7a 的so数量不一致,是典型的会导致UnsatisfiedLinkError的场景
infiateException之FileNotFoundException GC导致 ,activty被销毁但涉及的资源没有被回收,便产生内存泄露,但是表现为FileNotFoundException在activty的onStop方法中手动释放每一张图片的资源
infiateException之缺少构造器 在创建自定义View的时候,会可能产生。
是其中第二个参数用来将xml文件中的属性初始化。
在自定义控件若需要xml文件中使用,就必须重写带上两个参数的构造方法 。
infiateException之style与android:textstyle的区别 style中定义 要用 style=“@style/NomalText” 
TransactionTooLargeException Binder最大通常为1MB ,如果大于1MB就会抛出TransactionTooLargeException 异常 。 
这个异常经常出现在图片的分享功能中。
在采集打点数据时也会看到这类异常 ,(数据积累到一定量后才发生的)
不要将大量的数据传入Binder 不如说图片

系统碎片化化异常(一是版本差异 二是不同的ROM)
   
NosuchMethodErrorjava.lang.NoSuchMethErroor 方法被放弃,谨慎使用 。在开发阶段Android Lint,里面又被废弃方法的警告。
如果使用要进行Android  系统版本的判断。 
int sysVersion =Integer.paresInt(android.os.Build.VERDION.SDK) ;
if.....
RemoteViewsandroid.widget.RemoteView$Refiection.writeToParcel(Remote.java:763) RemoteViews使用的地方有两个 ,
APPWidget ,Notification。对于APP类而言有机会用到的是后者。
Notification 有一个contentView属性,就是RemoteView类型 。给imageview设置图片  textVie
绑定资源ID 。

异常:当Bitmap为null时
     当你的string 为""或者为null 
   Android版本是4.1时 不会出现以上情况。只会表现出异常并不会大致程序崩溃
pointerIndex out of  rangejava.lang.IllegalArgumentException:pointerIndex out of rangeat android view .motionEvent.nationGetAxiValue(Native Method) 在做多点触控放大缩小,操作自己所绘制的图形时发生这个异常,如果是操作图片的方法缩小,多点触控不会出现这个错误 。这个bug是Android系统原因导致的,所以简单有效的办法是在绘制时捕获这个异常 。

在用viewpage的话 ,onInterceptTouchEvent返回false 会导致viewpage翻页出现bug 。  
方法一:
public  fioat spacing (MotionEvent event){
try{ 
x =event.getX(0) -event.getX(i) ;
y=event.get(0)-event.getY(i);
}catch(IllegalArgumentException){
e.printStackTrance() ;
}
}


方法二:1.让view创建一个子view继承自它们中的某一个。
2.重写这个 view的onInterceptTouchEvent和onTouchEvent
3.为上述这个两个方法增加try。。catch语句,捕获已知的异常 。
try{ 
 super.onIntercepttouchEvent(MotionEvent ev)
}catch(IllegalArgumentException){
e.printStackTrance() ;
}
try{ 
 super.onTouchEvent(MotionEvent ev)
}catch(IllegalArgumentException){
e.printStackTrance() ;
}
至少在4.1 上是好用的。
securityException 之一 Intent中的图片太大 在跳转的extra中有bitmap应该减少要传输的图片的体积大小,或者通过保存图片的SD卡中或者通过URI方式传递图片参数,否则,图片太大,就会有上述错误。1MB是一个临界点 。 
SecurityException 之二 动态加载其他的apk的activity 。 如果在apk中动态的注册Broadcast ,那么Launcher动态加载该apk时 ,就有可能出现java.lang.secuityException异常 修改之前注册的BroadcastReceiver的地方 ,通过ContextHOder()来=注册BroadcastReceiver ,把apk重新部署验证即可 。
SecurityException 之三 No permission to modify thread  App经常会申请一些权限 ,而有些手机的ROM处于安全考虑,会禁止这些权限 ,那么当APP使用这些权限时 ,就会发生崩溃 。在执行某些安全相关的操作时 ,要么加if语句跳过要么使用try...catch..  捕获这类异常 ,宁肯点击无效也不能崩溃 。如电话拨打 有些手机会禁止 。即使在功能清单文件中配置了页不行 ,我们要先判断是否有打电话的权限,以确保不发生崩溃 。
view的getDrawingCache()返回null 当背景图太大,超过屏幕的大小 ,就导致getDrawingCache()返回的结果是null ,从而抛出NullPointEXception 异常控制图片的大小 ,剪裁或者等比缩放 。
DeadObjectException    
anderoid  2.1 不支持SSL  版本判断 
viewFlipper 横竖屏切换引发的异常是由于onDetachedFromWindow()在onAttachedToWindow()  ;重写viewFlipper的OnDetachedFromWindow()方法
ActivtyNotFoundException 发生在4.0 以上出现  。原因 ,是4.0
以上用来的网络设置方式舍弃了 。
 
Android2.2 不支持xlargeScreensNO resource identifier found  for  attribute ‘xlargeScreens’in package  ‘Android’ 在功能清单文件中supports-scress标记中 ,原因xlargeScreens  属性在API9(2.3)中才支持 。 
package manager  has diedPackage  manager  has died  at android.app.applicationPackageManager.getApplication(ApplicationPackageManager.java..)  
spannableString 与富文本字符串   
can not perfform  this action  after onSaveInstanceState commit方法在activity的OnSaveInstanceState()之后调用 ,因为。。。 
service Intent  must  be  explicitservice Intent  must  be  explicit 在5.0系统后会产生这样的崩溃 ,直接通过action启动service ,就会导致这个问题  ,必须指定component 或者package 才能避免这类问题 。
SqLite相关异常

   
No transaction is active    
忘记关闭Cursor    
数据库被锁定    
试图再打开已经关闭的对象    
文件加密了或无数据库    
webview中的Sqlite 缓存导致的崩溃    
webview中的cache数据    
磁盘读写错误    
android_metadata表不存在    
android_metadate表中的locale字段    
数据库或者磁盘满了    

不明错误
   
内存溢出    
verify Failed    
TimeOutException    
json  解析异常    
jsonArray在初始化时为空    
第三方SDK 抛出的crash    
两个不同类型的view有相同的id    
LayoutInfiater.from().infitate()使用不当导致的崩溃    
viewgroup    
monkey点击过快导致的崩溃    
图片缩放很多倍    
图片宽度为0    
不能重复添加组件    
     





转载于:https://www.cnblogs.com/yanghuaji/p/5849987.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值