A.詳細崩潰日誌信息php
# 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.查看崩潰類信息java
本機
的方法的適當本機語言定義,則引起。public class UnsatisfiedLinkError extends LinkageError { private static final long serialVersionUID = -4019343241616879428L; public UnsatisfiedLinkError() { super(); } public UnsatisfiedLinkError(String s) { super(s); } }
C.項目中異常分析react
F.解決辦法linux
報這個錯誤一般是so庫加載失敗,或者找不到準備執行的JNI方法:android
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.知識延申git
A.詳細崩潰日誌信息github
再給它添加Fragment就會出錯。面試
IllegalStateException: Can not perform this action after onSaveInstanceState:
B.查看崩潰類信息sql
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.項目中異常分析shell
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.解決辦法
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
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}" }
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(); } }
得出結論