空指针:NullPointException
1.方法需要对传入的参数判空后再使用
2.对外部接口的调用,需要确保返回值中不为空
3.在App中过多使用全局变量,一旦发生内存回收,全局变量会被置为空,可以将全局变量序列化到本地,为空时从本地反序列化回来
角标越界:IndexOutOfBoundsException,StringIndexOutOfBoundsException,ArrayIndexOutOfBoundsException
1.在遍历一个数组/集合时,要预判数组/集合是否为空,长度是否大于0
2.在使用数组/集合中的元素时,要预判数组/集合长度是否有这么长
3.先判断字符串长度再使用,subString(start,end)这样的函数
试图调用一个空对象的方法:Attempt to invoke virtual method on a null object reference
类型转换异常:ClassCastException:classA cannot be cast to classB
1.强制类型转换导致,可以使用安全类型转换函数,如convertToInt(obj, 0)
public final static int convertToInt(Object value, int defaultValue) {
if (value == null || "".equals(value.toString().trim())) {
return defaultValue;
}
try {
return Integer.valueOf(value.toString());
} catch (Exception e) {
try {
return Double.valueOf(value.toString()).intValue();
} catch (Exception e1) {
return defaultValue;
}
}
}
数字转换错误:NumberFormatException
如:
String abc = "1122xx";
int result = Integer.parseInt(abc);
声明数组时长度为-1:NegativeArraySizeException
如:
String[] arg1 = new String[args.length - 1];//args.length为0
遍历集合同时删除其中元素:ConcurrentModificationException
比较器使用不当:Comparison method violates its general contract!
如:
Comparator comparator = new Comparator(){
public int compare(Double d1,Double d2){
return p1 > p2 ? 1 : -1;
}
};//没有考虑到p1==p2的情况
当除数为0:java.lang.ArithmeticException:divide by zero
不能随便使用的asList:
java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:144)
at java.util.AbstractList$Itr.remove(AbstractList.java:360) at
java.util.AbstractCollection.remove(AbstractCollection.java:252) at
如:
String str = "1,2,3";
List test = Arrays.asList(str.split(","));//asList()返的是Arrays$ArrayList,其没有实现add和remove方法
test.remove("1");
解决方法:将Arrays$ArrayList转换为ArrayList
String str = "1,2,3";
List test = Arrays.asList(str.split(","));//asList()返的是Arrays$ArrayList,其没有实现add和remove方法
List arrayList = new ArrayList(test);
arrayList.remove("1");
类找不到:ClassNotFoundException
动态加载一个类时,如果这个类在运行时找不到,就会抛出这个异常
类找不到:NoClassDefFoundError
当在一个B来中声明A类的实例
ClassA obj = new ClassA();
但是打包时B和A在不同的dex中,如果在A所在的dex中把A类删除了,就会抛出此异常
找不到Activity:android.content.ActivityNotFoundException:No Activity found to handle Intent {…}
错误原因:URL不是以http开头,代码就会抛出异常
Uri uri = Uri.parse("www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent);
不能实例化Activity:java.lang.RuntimeException:Unable to instantiate activity ComponentInfo
没有在清单文件中注册
找不到Service:java.lang.RuntimeException:Unable to instantiate receiver
注意检查代码中是否有Class.forName("class1")这样的语句,ProGuard会将class1混淆,从而就找不到class1这个类
不能启动BroadcastReceiver:Unable to start receiver
使用Activity以外的content来startActivity,必须指定为Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult不能回传:Failure delivering result ResultInfo{who=null,request=0,result=-1}
传回来的key是A,但是却按照B这个key来取值
Fragment not attached to Activity
Fragment还没有Attach到Activity时就调用了诸如getResourse()这样的方法
解决方案:先使用isAdded方法进行判断
if(isAdded()){//isAdded方法是Android系统提供的,只有在Fragment被添加到所属的Activity后才返回true
getResourses().getString(...);
}
实体对象不支持序列化:Parcelable encountered IOException writing serializable object(name=xxx)…
序列化时未指定ClassLoader:BadParcelableException:ClassNotFoundException when unmarshalling…
public class MyParcelable implements Parcelable {
private String mStr;
private ClassA a;
...
private MyParcelable(Parcel in) {
mStr = in.readString();
a = in.readParcelable(null);
}
}
崩溃处在最后一句,对a的反序列化上,改成
a = in.readParcelable(ClassA.class.getClassLoader());
反序列化时发现类找不到(被ProGuard混淆导致的崩溃):Parcelable encountered ClassNotFoundException reading a Serializable object …
-keep class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient ;
!private ;
!private ;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
反序列化时发现类找不到(传入畸形数据):parcelable encountered ClassNotFoundException reading a Serializable object(name=某个类的名称)
反序列化时出错:Could not read input channel file descriptors from parcel…
可能是intent传递的数据太大导致的
Adapter数据源变化但是没通知ListView:The content of the adapter has changed but ListView did not receive a notification…
ListView滚动时点击刷新按钮后崩溃:
java.lang.IndexOutOfBoundsException:Invalid index 30,size is 1 at
java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)…
解决方案:ListView滚动的时候将刷新按钮设置为不可点击
AbsListView的obtainView返回空指针:java.lang.NullPointerException at android.widget.AbsListView.obtain View(AbsListView.java:1521)at android.widget.ListView.makeAndAddView
导致的原因是getView方法在某些时候返回null,返回的时候需判空,如果为null就返回convertView
Adapter数据源变化但是没调用notifyDataSetChanged:The application’s PagerAdapter changed the adapter’s contents without calling PagerAdapter#notifyDataSetChanged
PagerAdapter对于notifyDataSetChanged()和getCount()的执行顺序是非常严格的,系统跟踪count的值,如果这个值和getCount返回的值不一致,就会抛出此异常
窗体句柄泄露:
android.view.WindowLeaded:Activity xxx has leaked window
com.android.internal.policy.impl.Phone.Window$DecorView{xxxx} that was originally added here.
可能是在非主线程中的某些操作不当而产生了一个严重的异常,从而强制关闭当前Activity,而在关闭的同时,没能及时调用dismiss来解除ProgressDialog等的引用,从而系统抛出上述崩溃信息
解决方法:重写Activity的onDestroy方法,在方法中调用dismiss来解除对ProgressDialog等的引用
View not attached to window manager:
java.lang.IllegalArgumentException:View not attached to window manager at
android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:356) at
android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:201) at…
发生这类Exception的场景是,有一个耗时的线程任务,在任务开始的时候显示一个对话框,然后当任务完成后再销毁,在此期间Activity因为某种原因被杀掉且又重新启动了,那么当Dialog调用dismiss方法的时候就会抛此异常
token null is not for an application:android.view.WindowManager$BadTokenException:Unable to add window – token null is not for an application
new AlertDialog.Builder(getApplicationContext())
.setIcon(...)
...
.show();
只有Activity才能添加一个窗体
permission denied for this window type:Android.view.WindowManager$BadTokenException:Unable to add window android.view.ViewRootImpl$W@411da608 – permission denied for this window type
多发生在使用WindowManager自定义弹出框时,没有设置权限,需添加
is your activity running:
android.view.WindowManager$BadTokenException:Unable to add window – token
android.app.LocalActivityManager$LocalActivityRecord@45a58ee0 is not valid;is your activity running?
由于Activity A依附于ActivityB,当Activity B产生错误的时候,Activity A因为调用了一个已经被finish()/或者还没有执行完onCreate()的Activity抛出此异常
添加窗体失败
java.lang.RuntimeException:Adding window failed at
android.view.ViewRootImpl.setView(ViewRootImpl.java:511) at
android.view.WindowManagerImpl.addView(WindowManagerImpl.java:301) at
android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215) at…
AlertDialog.resolveDialogTheme
java.lang.NullPointerException at
android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:142) at
android.app.AlertDialog$Builder.(AlertDialog.java:359) at
com.radzik.devadmin.MainActivity$5.onClick(MainActivity.java:140) at
android.view.View.performClick(View.java:4084)…
1.在B页面写了一个show方法,控制AlertDialog.Builder的弹出和隐藏,在A页面调用B页面的show方法
2.在TabActivity中切换Tab时,也容易产生这个Crash,因为在new对话框的时候参数content指定成了this,即指向当前子Activity的content,但子Activity是动态创建的,不能保证一直存在,所以将this替换为getParent()即可
The specified child already has a parent.You must call removeView() on the child’s parent first
先将child从它的父布局中移除:parent.removeView(child);
再设置
子线程不能修改UI:android.view.ViewRootImpl$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views…
不能在子线程操作AlertDialog和Toast:Can’t create handler inside thread that has not called Looper.prepare()
Resources$NotFoundException:android.content.res.Resources$NotFoundException:String resource ID #0x1
StackOverfiowError
主要是因为Layout布局文件结构嵌套层次太深,尽量控制在5层以下
还有可能是App中有多个线程,在退出App的时候可能不能完全关闭App,必须使用System.exit(0)
UnsatisfiedLinkError:
java.lang.UnsatisfiedLinkError:dalvik.system.PathClassLoader [DexPathList[[zip file “/data/app/appname-1.apk”]…
造成这个Crash肯定是so格式的文件没有加载到
InfiateException之FileNotFoundException
Caused by:android.view.InfiateException:Binary XML file line #18:Error infiating class at
android.view.LayoutInfiater.createView(LayoutInfiater.java:518)
Caused by:java.io.FileNotFoundException:res/drawable-hdpi/add.png at
android.content.res.AssetManager.openNonAssetNative(Native Method)
可能是GC导致的,Activity销毁了,但是里面涉及的资源并没有被回收,于是便产生内存泄露,但是表现为FileNotFoundException
解决方案是在Activity的onStop方法中,手动释放每一张图片资源:
Drawable d = imageView.getDrawable();
if (d != null)
d.setCallback(null);
imageView.setImageDrawable(null);
imageView.setBackgroundDrawable(null);
InfiateException之缺少构造器:
android.view.InfiateException:Binary XML file line #:Error infiating class com.example.activity1.TestButton
自定义控件若需在xml文件中使用,就必须重写带有两个参数的构造方法
InfiateException之style与android:textStyle的区别:android.view.InfiateException:Binary XML file line #14:Error infiating class
引用定义好的样式
style = "@style/NormalText"
TransactionTooLargeException:android.view.InfiateException:Binary XML file line #14:Error infiating class
Binder最大通常限制为1MB,大于1MB就会抛出此异常
NoSuchMethodError:java.lang.NoSuchMethodError
可能是Android不同版本的API不同导致,可以在不同版本的SDK上编译,发现错误,或者对版本进行判断
RemoteViews:android.widget.RemoteViews$RefiectionAction.writeToParcel(RemoteViews.java:763)
当Android版本是4.1以下时,Bitmap为null会抛出此异常
pointerIndex out of range:
java.lang.IllegalArgumentException:pointerIndex out of range at
android.view.MotionEvent.nativeGetAxisValue(Native Method)
在做多点触控放大缩小,操作自己绘制的图形时发生此异常,可以在绘图的时候捕获这个异常
SecurityException之一:Intent中图片太大
Unable to find app for caller android.app.ApplicationThreadProxy@41868f10(pid=24370) when stopping service Intent {cmp=xxx}
SecurityException之二:动态加载其他apk的activity
java.lang.SecurityException:Given caller package com.jianqiang.abc is not running in process ProcessRecord {41e74e50 28637:com.zhao3546.launcher/u0a10142}
如果在apk中使用了动态注册BroadcastReceiver,那么Launcher动态加载该apk时,就有可能出现java.lang.SecurityException异常
解决方法参照:http://blog.csdn.net/zhao_3546/article/details/11195881
SecurityException之三:No permission to modify thread
java.lang.SecurityException:No permission to modify given thread at
android.os.Process.setThreadPriority(Native Method) at
android.webkit.WebViewCore$WebCoreThread$1.handleMessage(WebViewCore.java:764)
在执行某些需要权限的操作时,要么加上if语句跳过这个操作,要么使用try...catch...捕获这类异常
view的getDrawingCache()返回null
java.lang.NullPointerException at
android.view.View.buildDrawingCache(View.java:6578) at
android.view.View.getDrawingCache(View.java:6428) at…
当背景图太大,超过了屏幕大小,就会导致getDrawingCache()返回的结果是null
DeadObjectException
某个对象已经被系统回收了,可我们还在使用它
ViewFlipper引发的血案
java.lang.IllegalArgumentException:Receiver not registered:
android.widget.ViewFlipper$1@4083a4d0 at
android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:634)
在Activity中使用ViewFlipper控件,进行横竖屏切换操作时就会发生这种异常,这是由于onDetachedFromWindow()在onAttachedToWindow()之前被调用所致,需重写onDetachedFromWindow()方法
@Override
protected void onDetachedFromWindow(){
try{
super.onDetachedFromWindow();
}catch(IllegalArgumentException e){
stopFlipping();
}
}
ActivityNotFoundException:
android.content.ActivityNotFoundException:Unable to find explicit activity class
{com.android.settings/com.android.settings.WirelessSettings};
have you declared this activity in your AndroidManifest.xml?
Android4.0以上把原先的打开网络设置方式舍弃了
if(Build.VERSION.SDK_INT > 13){
startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
}else {
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
Package manager has died:
Packeage manager has died at
android.app.ApplicationPackageManager.getApplicationInfo(ApplicationPackageManager.java:213)
try{
String channelId = getPackageManager()
.getApplicationInfo(
getPackageName(),PackageManager.GET_META_DATA)
.metaData.getString("UMENG_CHANNEL");
PackageInfo info = this.getPackageManager()
.getPackageInfo(getPackageName(),0);
}catch(PackageManager.NameNotFoundException e){
}
PackageManager如果已经died,说明该进程不存在了,此时任何向它进行的请求都将失效,解决方案就是每次获取PackageManager的时候用try...catch...捕获异常
SpannableString与富文本字符串:java.lang.IndexOutOfBoundsException:setSpan(-1…-1) starts before 0 at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:951) at …
可能是在长按一段文本时,有些Android系统对于EditText的getSelectionStart方法,会返回-1
Can not perform this action after onSaveInstanceState
java.lang.IllegalStateException:
Can not perform this action after onSaveInstanceState at
android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)…
android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:595)
commit()方法在Activity的onSavaInstanceState()之后调用就会出错,因为onSaveInstanceState方法是在Activity即将被销毁前调用,以保存Activity数据的,如果在保存完状态后再添加Fragment就会出错
解决方法是把commit()方法替换成commitAllowingStateLoss()
Service Intent must be explicit
Android在升级到5.0系统后会产生这样的崩溃,直接通过action启动Service就会导致这个问题,必须指定component或package
Intent intent= new Intent();
intent.setAction("your action name");
intent.setPackage(getPackageName());
context.startService(intent);
No transaction is active:android.database.sqlite.SQLiteException:cannot commit - no transaction is active
在事务中,逐条循环插入大量数据时会导致此崩溃,解决方法是一次性地把这些数据都插入到数据库中
public void insertOrUpdateDataBatch(){
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try{
for(String sql : sqls){
db.execSQL(sql);
}
//设置事务标志为成功,当结束事务时就会提交事务
db.setTransactionSuccessful();
}catch(Exception e){
e.printStackTrace();
}finally{
db.endTransaction();
db.close();
}
}
忘记关闭Cursor:android.database.CursorWindowAllocationException:Cursor window allocation of 2048kb failed
数据库被锁定:android.database.sqlite.SQLiteDatabaseLockedException:database is locked
在不同的线程中创建多个连接时,就会抛出此异常,解决方案是将数据库做成一个单例
试图再打开已经关闭的对象:java.lang.IllegalStateException:attempt to re-open an already-closed object
多线程操作数据,A读完数据库将其关闭,B此时正在写数据,就会发生此Crash
在聊天室中,保持数据库一直处于Open状态,等退出聊天室再执行close方法
文件加密了或无数据库:SQLiteDatabaseCorruptException:file is encrypted or is not a database
如果有两个不同版本的DB就会出现此异常,如果DB破损(多次插拔SD卡,导致部分文件破损),也有可能出现此异常
WebView中SQLite缓存导致的崩溃:
SQLiteDiskIOException:disk I/O error…at android.webkit.WebViewDatabase$1.run(WebViewDatabase.java:1000)
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源)和Html5缓存(appcache)
WebView自带的缓存机制里,会将url保存在webviewCashe.db中,将url内容保存在webviewCashe文件夹下,而对于database目录下的webview.db和webviewCashe.db都会自动生成1个名为android_metadata的表,只要创建SQLite数据库中的表,就会自动创建这个表
建议缓存策略为:判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK
磁盘读写错误:android.database.sqlite.SQLiteDiskIOException:disk I/O error(code 1802)
dbHelper只有在创建数据库、进行事务处理时才会锁住数据库,默认情况下,dbHelper会缓存DB实例,执行类似于getWritableDatabase的操作是立即返回的,并不会上锁
disk I/O error这类异常的抛出是因为多线程修改DB
android_metadata表不存在:
android.database.sqlite.SQLiteException:no such table:android_metadata SQLiteOpenHelper.getReadableDatabase
开发中需要连接SQLite数据库,当使用如下方法打开数据库时就会抛出上述错误:
SQLiteDatabase database = SQLiteDatabase.openDatabase(PATH,null,SQLiteDatabase.OPEN_READONLY);
解决方法是将openDatabase方法中的最后一个参数改为SQLiteDatabase.NO_LOCALIZED_COLLATORS
android_metadata表中的locale字段:android.database.sqlite.SQLiteException:Failed to change locale for db ‘/data/data/appname/databases/webview.db’ to ‘zh_CN’
数据库或磁盘满了:android.database.sqlite.SQLiteFullException:database or disk is full
内存溢出:OutOfMemoryException
在AndroidManifest.xml中有个参数可以设置:
Verify Failed:java.lang.VerifyError:Rejecting class xxx.package.activityA that attempts to sub-class erroneous class xxx.package.Activity 基类
TimeoutException:com.android.internal.BinderInternal$GcWatcher.finalize() timed out after 10 seconds
GC回收超时会抛出此异常,注意重写finalize方法时不要有超时的操作
JSON解析异常:org.json.JSONException:No value for UserName at org.json.JSONObject.get(JSONObject.java:354) at…
在解析JSON的时候,使用了getString("UserName"),如果不存在此key就会抛出上述异常,可以使用optString("UserName")、optJsonArray方法
JSONArray在初始化时为空
java.lang.NullPointerException at
org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116) at
org.json.JSONTokener.nextValue(JSONTokener.java:94)t…
两个不同类型的View有相同的id
java.lang.IllegalArgumentException:Wrong state class,expecting View State but received class android.widget.ScrollView$SavedState instead.This usually happens when two views of different type have the same id in the same hierarchy.This view’s id is id/0xff0000.Make sure other views do not use the same id.
建议最好保证每个View的id都是唯一的,至少在一个布局文件中是唯一的
LayoutInfiater.from().infiate()使用不当导致的崩溃:No package identifier when getting value for resource number 0x00000001
在程序中使用LayoutInfiater.from().infiate()语句时,必须写在具体的子类中,一定不能工作在父类或虚类里
可以参考:http://blog.csdn.net/yanzi1225627/article/details/37338565
ViewGroup中的玄机:java.lang.IllegalArgumentException:parameter must be a descendant of this view
这个崩溃是ViewGroup的offsetRectBetweenParentAndChild方法抛出来的
可以参考:http://blog.sina.com.cn/s/blog_5704bfaf0102v3bn.html
图片缩放很多倍:java.lang.IllegalArgumentException:bitmap size exceeds 32bits
当图片缩放了很多倍时,导致内存溢出,就会抛出此异常,多发生在全屏显示一张图片的时候
图片宽高为0:
java.lang.IllegalArgumentException:width and height must be>0 at android.graphics.Bitmap.nativeCreate(Native Method)
通常是因为没有取到图片的宽和高(缓存数据被清空或提前调用了获取图片宽高的方法),返回默认值0抛出此异常
不能重复添加组件:View xxx has already been added to the window manager
解决方法:
try{
windowmanager.removeView(view);
}catch(IllegalStateException e){
e.printStackTrace();
}
try{
windowmanager.addView(view);
}catch(IllegalStateException e){
e.printStackTrace();
}