A.详细崩溃日志信息
# main(1) java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.paidian.hwmc-1/base.apk", dex file "/data/app/com.paidian.hwmc-1/base.apk"],nativeLibraryDirectories=[/data/app/com.paidian.hwmc-1/lib/arm64, /data/app/com.paidian.hwmc-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libijkffmpeg.so"
B.查看崩溃类信息
本机
的方法的适当本机语言定义,则引发。 public class UnsatisfiedLinkError extends LinkageError { private static final long serialVersionUID = -4019343241616879428L; public UnsatisfiedLinkError() { super(); } public UnsatisfiedLinkError(String s) { super(s); } }
C.项目中异常分析
F.解决办法
报这个错误通常是so库加载失败,或者找不到准备执行的JNI方法:
ndk { //根据需要 自行选择添加的对应cpu类型的.so库。 //abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'mips' abiFilters 'armeabi-v7a' } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) //这两个是必须要加的,其它的可供选择 compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4' compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4' //其他库文件 //compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8' //compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8' }
G.知识延申
A.详细崩溃日志信息
再给它添加Fragment就会出错。
IllegalStateException: Can not perform this action after onSaveInstanceState:
B.查看崩溃类信息
public class IllegalStateException extends RuntimeException { public IllegalStateException() { super(); } public IllegalStateException(String s) { super(s); } public IllegalStateException(String message, Throwable cause) { super(message, cause); } public IllegalStateException(Throwable cause) { super(cause); } static final long serialVersionUID = -1848914673093119416L; }
C.项目中异常分析
F.解决办法
G.其他延申
java.lang.IllegalStateException:Can't change tag of fragment d{e183845 #0 d{e183845}}: was d{e183845} now d{e183845 #0 d{e183845}} java.lang.IllegalStateException:Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 37 path $.data
A.详细崩溃日志信息
Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f040151 a=2} android.view.LayoutInflater.createView(LayoutInflater.java:620)
B.查看崩溃类信息
public static class NotFoundException extends RuntimeException { public NotFoundException() { } public NotFoundException(String name) { super(name); } public NotFoundException(String name, Exception cause) { super(name, cause); } }
C.项目中异常分析
F.解决办法
B.查看崩溃类信息
public class IllegalArgumentException extends RuntimeException { public IllegalArgumentException() { super(); } public IllegalArgumentException(String s) { super(s); } public IllegalArgumentException(String message, Throwable cause) { super(message, cause); } public IllegalArgumentException(Throwable cause) { super(cause); } private static final long serialVersionUID = -5365630128856068164L; }
G.常见的出现场景
A.详细崩溃日志信息
Can't compress a recycled bitmap com.paidian.hwmc.utils.i.a(FileUtils.java:75)
B.查看崩溃类信息
public boolean compress(CompressFormat format, int quality, OutputStream stream) { checkRecycled("Can't compress a recycled bitmap"); //省略代码 return result; } //如果位图已被回收,则希望抛出异常的方法将调用此值。 private void checkRecycled(String errorMessage) { if (mRecycled) { throw new IllegalStateException(errorMessage); } }
C.项目中异常分析
D.引发崩溃日志的流程分析
Free the native object associated with this bitmap, and clear the reference to the pixel data
F.解决办法
A.详细崩溃日志信息
Please call the AutoSizeConfig#init() first com.paidian.hwmc.base.BaseApplication.initAutoSizeConfig(BaseApplication.java:386)
B.查看崩溃类信息
public class NullPointerException extends RuntimeException { private static final long serialVersionUID = 5162710183389028792L; public NullPointerException() { super(); } public NullPointerException(String s) { super(s); } }
C.项目中异常分析
D.引发崩溃日志的流程分析
空指针问题解决思路:
F.解决办法
空指针最为常见,也最容易规避,使用的时候一定要进行null check,采取不信任原则:
A.详细崩溃日志信息
android.view.WindowManager$BadTokenException Unable to add window -- token android.os.BinderProxy@7f652b2 is not valid; is your activity running?
B.查看崩溃类信息
D.引发崩溃日志的流程分析
Toast.makeText(this,"潇湘剑雨-yc",Toast.LENGTH_SHORT).show(); try { Thread.sleep(20000); } catch (InterruptedException e) { e.printStackTrace(); }
F.解决办法
第二种,抛出异常增加try-catch,代码如下所示,最后仍然无法解决问题
G.哪些情况会发生该问题?
A.详细崩溃日志信息
android.widget.FrameLayout cannot be cast to android.widget.RelativeLayout com.paidian.hwmc.goods.activity.GoodsDetailsActivity.initView(GoodsDetailsActivity.java:712)
B.查看崩溃类信息
public class ClassCastException extends RuntimeException { private static final long serialVersionUID = -9223365651070458532L; public ClassCastException() { super(); } public ClassCastException(String s) { super(s); } }
C.项目中异常分析
F.解决办法
A.详细崩溃日志信息
new Thread(new Runnable() { @Override public void run() { ToastUtils.showRoundRectToast("潇湘剑雨-杨充"); } }).start();
然后找找报错日志从哪里来的
子线程中吐司的正确做法,代码如下所示
new Thread(new Runnable() { @Override public void run() { Looper.prepare(); ToastUtils.showRoundRectToast("潇湘剑雨-杨充"); Looper.loop(); } }).start();
得出的结论
A.详细崩溃日志信息
Didn't find class "om.scwang.smartrefresh.layout.SmartRefreshLayout" on path: DexPathList[[zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/base.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_dependencies_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_0_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_slice_1_apk.apk", zip file "/data/app/com.paidian.hwmc-EsIbVq6e0mFwE0-rPanqdg==/split_lib_s com.paidian.hwmc.goods.activity.GoodsDetailsActivity.onCreate(GoodsDetailsActivity.java:209)
B.查看崩溃类信息
public class ClassNotFoundException extends ReflectiveOperationException { private static final long serialVersionUID = 9176873029745254542L; private Throwable ex; public ClassNotFoundException() { super((Throwable)null); // Disallow initCause } public ClassNotFoundException(String s) { super(s, null); // Disallow initCause } public ClassNotFoundException(String s, Throwable ex) { super(s, null); // Disallow initCause this.ex = ex; } public Throwable getException() { return ex; } public Throwable getCause() { return ex; } }
C.项目中异常分析
F.解决办法
如果找不到的Class是应用自由Class(含第三方SDK的Class),可以通过反编译工具查看对应apk中是否真的缺少该Class,再进行定位,这种往往发生在:
A.详细崩溃日志信息
java.util.concurrent.TimeoutException: android.view.ThreadedRenderer.finalize() timed out after 10 seconds at android.view.ThreadedRenderer.nDeleteProxy(Native Method) at android.view.ThreadedRenderer.finalize(ThreadedRenderer.java:423)
B.查看崩溃类信息
public class TimeoutException extends Exception { private static final long serialVersionUID = 1900926677490660714L; public TimeoutException() {} public TimeoutException(String message) { super(message); } }
F.解决办法
A.详细崩溃日志信息
Exception in thread "main" java.lang.NumberFormatException: For input string: "100 " at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:458) at java.lang.Integer.parseInt(Integer.java:499)
B.查看崩溃类信息
public class NumberFormatException extends IllegalArgumentException { static final long serialVersionUID = -2848938806368998894L; public NumberFormatException () { super(); } public NumberFormatException (String s) { super (s); } static NumberFormatException forInputString(String s) { return new NumberFormatException("For input string: /"" + s + "/""); } }
C.项目中异常分析
F.解决办法
A.详细崩溃日志信息
java.lang.IllegalStateException: Fragment not attached to Activity
C.项目中异常分析
F.解决办法
if(isAdded()){//isAdded方法是Android系统提供的,只有在Fragment被添加到所属的Activity后才返回true activity.getResourses().getString(...); }
@Override public void onAttach(Context context) { super.onAttach(context); activity = (MainActivity) context; } @Override public void onDetach() { super.onDetach(); if (activity != null) { activity = null; } }
G.其他延申
A.详细崩溃日志信息
java.lang.ArrayIndexOutOfBoundsException: 0 at com.example.mytest.CityAdapter.setDataNotify(CityAdapter.java:183) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
B.查看崩溃类信息
public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException { private static final long serialVersionUID = -5116101128118950844L; public ArrayIndexOutOfBoundsException() { super(); } public ArrayIndexOutOfBoundsException(int index) { super("Array index out of range: " + index); } public ArrayIndexOutOfBoundsException(String s) { super(s); } public ArrayIndexOutOfBoundsException(int sourceLength, int index) { super("length=" + sourceLength + "; index=" + index); } public ArrayIndexOutOfBoundsException(int sourceLength, int offset, int count) { super("length=" + sourceLength + "; regionStart=" + offset + "; regionLength=" + count); } }
F.解决办法
A.详细崩溃日志信息
Unable to instantiate application com.pedaily.yc.meblurry.App: java.lang.IllegalAccessException
B.查看崩溃类信息
public class IllegalAccessException extends ReflectiveOperationException { private static final long serialVersionUID = 6616958222490762034L; public IllegalAccessException() { super(); } public IllegalAccessException(String s) { super(s); } }
C.项目中异常分析
F.解决办法
G.其他延申
A.详细崩溃日志信息
Unable to add window -- token android.os.BinderProxy@9a57804 is not valid; is your activity running? android.view.ViewRootImpl.setView(ViewRootImpl.java:907)
B.查看崩溃类信息
public static class BadTokenException extends RuntimeException { public BadTokenException() { } public BadTokenException(String name) { super(name); } }
C.项目中异常分析
F.解决办法
/** * 展示加载窗 * @param context 上下文 * @param isCancel 是否可以取消 */ public static void show(Context context, boolean isCancel) { if(context == null){ return; } if (context instanceof Activity) { if (((Activity) context).isFinishing()) { return; } } if (loadDialog != null && loadDialog.isShowing()) { return; } loadDialog = new LoadLayoutDialog(context, isCancel); loadDialog.show(); } /** * 销毁加载窗 * @param context 上下文 */ public static void dismiss(Context context) { if(context == null){ return; } try { if (context instanceof Activity) { if (((Activity) context).isFinishing()) { loadDialog = null; return; } } if (loadDialog != null && loadDialog.isShowing()) { Context loadContext = loadDialog.getContext(); if (loadContext instanceof Activity) { if (((Activity) loadContext).isFinishing()) { loadDialog = null; return; } } loadDialog.dismiss(); loadDialog = null; } } catch (Exception e) { e.printStackTrace(); loadDialog = null; } }
G.其他延申
Dialog&AlertDialog,Toast,WindowManager不能正确使用时,经常会报出该异常,原因比较多,几个常见的场景如下:
H.其他建议
B.查看崩溃类信息
ClassLoader
实例试图加载类的定义(作为普通方法调用的一部分或使用 新的
表达式创建新实例的一部分),则抛出该类的定义。编译当前执行的类时存在搜索类定义,但无法再找到该定义。 public class NoClassDefFoundError extends LinkageError { private static final long serialVersionUID = 9095859863287012458L; public NoClassDefFoundError() { super(); } public NoClassDefFoundError(String s) { super(s); } private NoClassDefFoundError(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } }
C.项目中异常分析
D.引发崩溃日志的流程分析
F.解决办法
G.其他延申
[解决方案]:NoClassDefFoundError异常一般出现在编译环境和运行环境不一致的情况下,就是说有可能在编译过后更改了Classpath或者jar包所以导致在运行的过程中JVM或者ClassLoader无法找到这个类的定义。
F.解决办法
3.1 OnErrorNotImplementedException【 Can't create handler inside thread that has not called Looper.prepare()】
A.详细崩溃日志信息
Can't create handler inside thread that has not called Looper.prepare()
D.引发崩溃日志的流程分析
F.解决办法
final Runnable runnable = new Runnable() { @Override public void run() { //执行耗时操作 try { Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName()); Thread.sleep(2000); Log.e("bm", "执行完耗时操作了~"); } catch (InterruptedException e) { e.printStackTrace(); } } }; new Thread() { public void run() { Looper.prepare(); new Handler().post(runnable);//在子线程中直接去new 一个handler Looper.loop(); //这种情况下,Runnable对象是运行在子线程中的,可以进行联网操作,但是不能更新UI } }.start();
final Runnable runnable = new Runnable() { @Override public void run() { //执行耗时操作 try { Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName()); Thread.sleep(2000); Log.e("bm", "执行完耗时操作了~"); } catch (InterruptedException e) { e.printStackTrace(); } } }; new Thread() { public void run() { //在子线程中直接去new 一个handler new Handler(Looper.getMainLooper()).post(runnable); //这种情况下,Runnable对象是运行在主线程中的,不可以进行联网操作,但是可以更新UI } }.start();
C.项目中异常分析
F.解决办法
百度google大家多说的是任务管理器 kill掉adb 或者重启adb server,但我任务管理器就没有adb ,猜测是某个程序占用了adb端口。于是按此思路查找。 5037为adb默认端口 查看该端口情况如下: netstat -aon|findstr "5037" TCP 127.0.0.1:5037 0.0.0.0:0 LISTENING 6540 发现6540占用了 5037端口,继续查看6540的task,发现是wandoujia .如下所示 tasklist|findstr "6540" wandoujia_daemon.exe 6540 Console 1 4,276 K 接下来问题就好解决了,在任务管理器kill掉wandoujia_daemon.exe ,运行android程序,ok . 1.关闭xx荚进程 2.adb kill-server 3.adb start-server
3.3 java.lang.IllegalStateException: ExpectedBEGIN_OBJECT but was STRING at line 1 column 1 path $
A.详细崩溃日志信息
java.lang.IllegalStateException: ExpectedBEGIN_OBJECT but was STRING at line 1 column 1 path $
C.项目中异常分析
D.引发崩溃日志的流程分析
F.解决办法
/**
*/ public static boolean isJson(String value) { try { new JSONObject(value); } catch (JSONException e) { return false; } return true; } /** * 判断是否是json结构 */ public static boolean isGoodJson(String json) { try { new JsonParser().parse(json); return true; } catch (JsonParseException e) { System.out.println("bad json: " + json); return false; } } ```
G.其他延申,补充说明
A.详细崩溃日志信息
android.content.ActivityNotFoundException: No Activity found to handle Intent
B.查看崩溃类信息
public class ActivityNotFoundException extends RuntimeException { public ActivityNotFoundException() { } public ActivityNotFoundException(String name) { super(name); } };
F.解决办法
Intent intent = new Intent(Intent.ACTION_SENDTO,url); try { context.startActivity(intent); } catch(ActivityNotFoundException exception) { Toast.makeText(this, "no activity", Toast.LENGTH_SHORT).show(); }
//避免安装了应用宝的用户点击其他外部链接走此方法导致崩溃 //判断是否用应用宝客户端 if(AppUtils.isPkgInstalled(AdDetailActivity.this,"com.tencent.android.qqdownloader")){ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity( intent); }
A.详细崩溃日志信息
出错代码位置 public static String softVersionName(Context context) { PackageInfo info = null; try { info = context.getPackageManager().getPackageInfo( context.getPackageName(), 0); //在这里 } catch (NameNotFoundException e) { e.printStackTrace(); } return info.versionName; }
D.引发崩溃日志的流程分析
F.解决办法
public static String softVersionName(Context context) { PackageInfo info = null; try {//增加同步块 synchronized (context) { info =context.getPackageManager().getPackageInfo(context.getPackageName(), 0); } return info.versionName; } catch (Exception e) { e.printStackTrace(); return ""; } }
G.其他延申
private void test() { //这个Demo就是同时创建两个线程来进行Binder调用. for (int i = 0; i < 2; i++) { new Thread() { @Override public void run() { int count = 0; List<PackageInfo> list = getPackageManager().getInstalledPackages(0); for (PackageInfo info : list) { if(count >=1000){ break; } try { PackageInfo pi = getPackageManager().getPackageInfo(info.packageName, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException e) { } } } }.start(); } } }
synchronized(MainActivity.class){ PackageInfo pi = getPackageManager() .getPackageInfo(info.packageName, PackageManager.GET_ACTIVITIES); }
A.详细崩溃日志信息
View=com.android.internal.policy.impl.PhoneWindow$DecorView{22a4fb16 V.E..... R.....ID 0,0-1080,1020} not attached to window manager com.flyco.dialog.widget.base.BaseDialog.superDismiss(BaseDialog.java)
C.项目中异常分析
D.引发崩溃日志的流程分析
F.解决办法
G.其他延申,建议
A.详细崩溃日志信息
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { act=initApplication cmp=com.paidian.hwmc/.service.InitializeService }: app is in background uid UidRecord{a37d28d u0a386 TRNB bg:+5m30s482ms idle procs:3 seq(0,0,0)}
A.详细崩溃日志信息
C.项目中异常分析
D.引发崩溃日志的流程分析
@Override public void onBackPressed() { if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) { super.onBackPressed(); } }
public void onBackPressed() { if (mActionBar != null && mActionBar.collapseActionView()) { return; } if (!mFragments.getFragmentManager().popBackStackImmediate()) { finishAfterTransition(); } } public void finishAfterTransition() { if (!mActivityTransitionState.startExitBackTransition(this)) { finish(); } }
@Override public boolean popBackStackImmediate() { checkStateLoss(); executePendingTransactions(); return popBackStackState(mHost.getHandler(), null, -1, 0); }
private void checkStateLoss() { if (mStateSaved) { throw new IllegalStateException( "Can not perform this action after onSaveInstanceState"); } if (mNoTransactionsBecause != null) { throw new IllegalStateException( "Can not perform this action inside of " + mNoTransactionsBecause); } }
F.解决办法
if (!isFinishing()) { super.onBackPressed(); }
C.项目中异常分析
遇过出现getActivity()出现null的时候导致程序报出空指针异常。其实原因可以归结于因为我们在
D.引发崩溃日志的流程分析
当遇到getActivity()为null,或getContext()时,先冷静想想以下3点:
F.解决办法
在Fragment中直接调用 private MActivity mActivity; @Override public void onAttach(Activity activity) { super.onAttach(activity); mActivity = (MActivity) activity; } @Override public void onDetach() { super.onDetach(); mActivity = null; }
G.其他延申
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Parcelable p = mFragments.saveAllState(); if (p != null) { outState.putParcelable(FRAGMENTS_TAG, p); } …… }
@SuppressWarnings("deprecation") @Override protected void onCreate(@Nullable Bundle savedInstanceState) { mFragments.attachHost(null /*parent*/); super.onCreate(savedInstanceState); NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { mFragments.restoreLoaderNonConfig(nc.loaders); } if (savedInstanceState != null) { Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG); mFragments.restoreAllState(p, nc != null ? nc.fragments : null); …… } if (mPendingFragmentActivityResults == null) { mPendingFragmentActivityResults = new SparseArrayCompat<>(); mNextCandidateRequestIndex = 0; } mFragments.dispatchCreate(); }
假设我们的页面叫MyActivity(继承自FragmentActivity),其中用到的Fragment叫MyFragment。出现上面这种情况时,app发生的变化如下:
对于上面的问题,可以考虑下面这两种解决办法:
if(savedInstanceState!= null){ String FRAGMENTS_TAG = "Android:support:fragments"; savedInstanceState.remove(FRAGMENTS_TAG); }
A.详细崩溃日志信息
C.项目中异常分析
F.解决办法
public static String replacer(String data) { try { //使用%25替换字符串中的%号 data = data.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); data = URLDecoder.decode(data, "utf-8"); } catch (Exception e) { e.printStackTrace(); } return data; }
A.详细崩溃日志信息
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{*****Activity}: java.lang.ClassNotFoundException: Didn't find class "*****Activity" on path: /data/app/*******.apk
B.查看崩溃类信息
public class ClassNotFoundException extends ReflectiveOperationException { private static final long serialVersionUID = 9176873029745254542L; private Throwable ex; public ClassNotFoundException() { super((Throwable)null); // Disallow initCause } public ClassNotFoundException(String s) { super(s, null); // Disallow initCause } public ClassNotFoundException(String s, Throwable ex) { super(s, null); // Disallow initCause this.ex = ex; } public Throwable getException() { return ex; } public Throwable getCause() { return ex; } }
F.解决办法
A.详细崩溃日志信息
C.项目中异常分析
D.引发崩溃日志的流程分析
F.解决办法
G.其他延申,常见场景
H.NoClassDefFoundError和ClassNotFoundException区别
报错信息:
Could not open database, (OS error - 36:File name too long) {"code":"4444","message":"未知错误","exception":"Data too long for column 'sdk_token' at row 1"}
日志错误截图
解决办法
A.详细崩溃日志信息
Caused by: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details Caused by: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
B.查看崩溃类信息
public class ExecutionException extends Exception { protected ExecutionException() { throw new RuntimeException("Stub!"); } protected ExecutionException(String message) { throw new RuntimeException("Stub!"); } public ExecutionException(String message, Throwable cause) { throw new RuntimeException("Stub!"); } public ExecutionException(Throwable cause) { throw new RuntimeException("Stub!"); } }
F.解决办法
android.enableAapt2=false
G.其他延申
# 应用版本名称 VERSION_NAME=1.0.0 # 应用版本号 VERSION_CODE=100 # 支持库版本 SUPPORT_LIBRARY=24.2.1 # MIN_SDK_VERSION ANDROID_BUILD_MIN_SDK_VERSION=14 # TARGET_SDK_VERSION ANDROID_BUILD_TARGET_SDK_VERSION=24 # BUILD_SDK_VERSION ANDROID_BUILD_SDK_VERSION=24 # BUILD_TOOLS_VERSION ANDROID_BUILD_TOOLS_VERSION=24.0.3
android { compileSdkVersion project.ANDROID_BUILD_SDK_VERSION as int buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION defaultConfig { applicationId project.APPLICATION_ID // lib项目不需要配置这一项 versionCode project.VERSION_CODE as int versionName project.VERSION_NAME minSdkVersion project.ANDROID_BUILD_MIN_SDK_VERSION as int targetSdkVersion project.ANDROID_BUILD_TARGET_SDK_VERSION as int } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') //这里注意是双引号 compile "com.android.support:appcompat-v7:${SUPPORT_LIBRARY}" compile "com.android.support:design:${SUPPORT_LIBRARY}" compile "com.android.support:recyclerview-v7:${SUPPORT_LIBRARY}" compile "com.android.support:support-annotations:${SUPPORT_LIBRARY}" compile "com.android.support:cardview-v7:${SUPPORT_LIBRARY}" compile "com.android.support:support-v4:${SUPPORT_LIBRARY}" }
4.6 java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException
A.详细崩溃日志信息
Caused by: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: Error while executing process /Users/duanzheng/WorkSpace/AndroidSdk/build-tools/27.0.3/aapt with arguments {package -f --no-crunch -I /Users/duanzheng/WorkSpace/AndroidSdk/platforms/android-27/android.jar -M /Users/duanzheng/.jenkins/workspace/android_hwmc_project/UdeskSDKUI/build/intermediates/manifests/aapt/release/AndroidManifest.xml -S /Users/duanzheng/.jenkins/workspace/android_hwmc_project/UdeskSDKUI/build/intermediates/res/merged/release --non-constant-id -0 apk --no-version-vectors} Caused by: org.gradle.process.internal.ExecException: Process 'command '/Users/duanzheng/WorkSpace/AndroidSdk/build-tools/27.0.3/aapt'' finished with non-zero exit value 1 //注意这里看重点:aapt'' finished with non-zero exit value 1
F.解决办法
H.aapt是啥
A.详细崩溃日志信息
1 #00 pc 00768556 /vendor/lib/libllvm-glnext.so [armeabi-v8] 2 #01 pc 000011e0 <unknown> 3 java: 4 [Failed to get java stack]
A.详细崩溃日志信息
UncaughtException detected: io.reactivex.exceptions.OnErrorNotImplementedException: Only the original thread that created a view hierarchy can touch its views. Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
B.查看崩溃类信息
C.项目中异常分析
D.引发崩溃日志的流程分析
详细日志错误
vity.baojia.ChoiceResultPsActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.cheoo.app.fragment.choiceresultps.QuotationDaQuanFragment: could not find Fragment constructor
可能导致的出现该bug的原因分析
问题代码如下所示,解决办法就是添加一个无参构造方法即可。
public static BusinessHotCarFragment newInstance(Map<String,String> map) { BusinessHotCarFragment fragment = new BusinessHotCarFragment(map); return fragment; } public BusinessHotCarFragment(Map<String,String> map) { this.pMap =map; } //解决问题办法,添加一个无参构造方法 public BusinessHotCarFragment(){}
深入分析为何Fragment需要无参构造函数才可以实例化
既然报的找不到构造方法的错误,先来看一下Fragment的构造函数:
/** * Default constructor. <strong>Every</strong> fragment must have an * empty constructor, so it can be instantiated when restoring its * activity's state. It is strongly recommended that subclasses do not * have other constructors with parameters, since these constructors * will not be called when the fragment is re-instantiated; instead, * arguments can be supplied by the caller with {@link #setArguments} * and later retrieved by the Fragment with {@link #getArguments}. * * <p>Applications should generally not implement a constructor. Prefer * {@link #onAttach(Context)} instead. It is the first place application code can run where * the fragment is ready to be used - the point where the fragment is actually associated with * its context. Some applications may also want to implement {@link #onInflate} to retrieve * attributes from a layout resource, although note this happens when the fragment is attached. */ public Fragment() { }
这个异常是从哪里来的?
public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) { try { Class<?> clazz = sClassMap.get(fname); if (clazz == null) { // Class not found in the cache, see if it's real, and try to add it clazz = context.getClassLoader().loadClass(fname); sClassMap.put(fname, clazz); } Fragment f = (Fragment) clazz.getConstructor().newInstance(); if (args != null) { args.setClassLoader(f.getClass().getClassLoader()); f.setArguments(args); } return f; } catch (ClassNotFoundException e) { throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (java.lang.InstantiationException e) { throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (IllegalAccessException e) { throw new InstantiationException("Unable to instantiate fragment " + fname + ": make sure class name exists, is public, and has an" + " empty constructor that is public", e); } catch (NoSuchMethodException e) { throw new InstantiationException("Unable to instantiate fragment " + fname + ": could not find Fragment constructor", e); } catch (InvocationTargetException e) { throw new InstantiationException("Unable to instantiate fragment " + fname + ": calling Fragment constructor caused an exception", e); } }
这个异常是哪里触发的呢?
void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) { // Build the full list of active fragments, instantiating them from // their saved state. mActive = new SparseArray<>(fms.mActive.length); for (int i=0; i<fms.mActive.length; i++) { FragmentState fs = fms.mActive[i]; if (fs != null) { FragmentManagerNonConfig childNonConfig = null; if (childNonConfigs != null && i < childNonConfigs.size()) { childNonConfig = childNonConfigs.get(i); } ViewModelStore viewModelStore = null; if (viewModelStores != null && i < viewModelStores.size()) { viewModelStore = viewModelStores.get(i); } Fragment f = fs.instantiate(mHost, mContainer, mParent, childNonConfig, viewModelStore); if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f); mActive.put(f.mIndex, f); // Now that the fragment is instantiated (or came from being // retained above), clear mInstance in case we end up re-restoring // from this FragmentState again. fs.mInstance = null; } } ... }
然后看一下在Fragment的restoreChildFragmentState方法源码。
void restoreChildFragmentState(@Nullable Bundle savedInstanceState) { if (savedInstanceState != null) { Parcelable p = savedInstanceState.getParcelable( FragmentActivity.FRAGMENTS_TAG); if (p != null) { if (mChildFragmentManager == null) { instantiateChildFragmentManager(); } mChildFragmentManager.restoreAllState(p, mChildNonConfig); mChildNonConfig = null; mChildFragmentManager.dispatchCreate(); } } }
接着看看Fragment中的onCreate方法
@CallSuper public void onCreate(@Nullable Bundle savedInstanceState) { mCalled = true; restoreChildFragmentState(savedInstanceState); if (mChildFragmentManager != null && !mChildFragmentManager.isStateAtLeast(Fragment.CREATED)) { mChildFragmentManager.dispatchCreate(); } }
得出结论