Android 常見bug匯總及解決方案
作為開發人員,平時總會遇到各種各樣的問題,之前都沒有收集bug的習慣,遇到相同的問題總會有種莫名的熟悉感,或許把問題都匯總,方便查找,也可以給大傢踩踩坑,後面會陸續更新補充!
1、關於使用OkHttp運行時出現的錯誤
報錯如下:
Static interface methods are only supported starting with Android N (--min-api 24): okhttp3.Request okhttp3.Authenticator.lambda$static$0(okhttp3.Route, okhttp3.Response)
大概意思就是靜態接口方法隻從Android N開始使用。
解決方案:
因為靜態接口需要在Java 8 下才支持使用,所以我們要使用靜態接口,就需要在app的build.gradle文件中配置聲明,使用Java 8編譯。
所以需要加入以下代碼來聲明:
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }
修改如下圖所示:
添加完成以後,同步一下,然後重新運行項目就可以啦。
2、圖片輪播控件com.youth.banner使用Glide異步加載圖片時發生的崩潰
錯誤信息:
java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity at com.b.a.e.m.b(RequestManagerRetriever.java:311) at com.b.a.e.m.a(RequestManagerRetriever.java:130) at com.b.a.e.m.a(RequestManagerRetriever.java:114) at com.b.a.d.c(Glide.java:697) at com.company.h5.c.ag$b.a(MainFragment.java:1079) at com.company.h5.c.ag$b.displayImage(MainFragment.java:1063) at com.youth.banner.Banner.setImageList(Banner.java:354) at com.youth.banner.Banner.start(Banner.java:262)
根據錯誤信息找到發生閃退的代碼位置:
//自定義的圖片加載器 private class ImgLoader extends ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { RoundedCorners roundedCorners = new RoundedCorners(20); RequestOptions options = new RequestOptions().bitmapTransform(roundedCorners); //報錯地方 Glide.with(context).load((String) path).apply(options).into(imageView); } }
跟蹤日志進入Glide調用的地方發現,出現在
RequestManagerRetriever.assertNotDestroyed()
方法中:
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private static void assertNotDestroyed(Activity activity) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) { throw new IllegalArgumentException("You cannot start a load for a destroyed activity"); } }
這個錯誤是使用Glide異步加載圖片的時候,Activity已經Destroyed
解決方案:
1、在使用Glide加載圖片前,先進行Activity是否Destroy的判斷:
/** * 判斷Activity是否Destroy * @param activity * @return */ public static boolean isDestroy(Activity mActivity) { if (mActivity== null || mActivity.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mActivity.isDestroyed())) { return true; } else { return false; } }
2、在錯誤的位置進行替換:
//自定義的圖片加載器 private class ImgLoader extends ImageLoader { @Override public void displayImage(Context context, Object path, ImageView imageView) { //添加判斷 if(!isDestroy((Activity)context)){ RoundedCorners roundedCorners = new RoundedCorners(20); RequestOptions options = new RequestOptions().bitmapTransform(roundedCorners); Glide.with(context).load((String) path).apply(options).into(imageView); } } }
這樣就解決啦。
3、接入容聯七陌客服系統,進入客服界面時閃退問題
錯誤信息:
圖片看起來不清晰,看報錯代碼:
java.lang.NoSuchMethodError: No virtual method into (Landroid/widget/ImageView;)Lcom/bumptech/glide/request/target/Target; in class Lcom/a/a/i; or its super classes (declaration of 'com.a.a.i' appears in/data/app/com.sami91sami.h5-1/base.apk)
我們可以根據報錯,跳到報錯的地方:
該報錯的意思就是:沒有
into(Landroid/widget/ImageView)
的方法,代碼能編譯通過,說明項目中肯定是添加依賴瞭,那怎麼還會報這個錯誤呢?還沒添加依賴之前,項目中也是使用的Glide進行圖片的加載,會不會是項目中的Glide與容聯Demo中的Glide有沖突呢。
我們可以根據報錯的地方into方法,點進入看源碼:
可以看到容聯Demo使用的Glide版本是3.7.0。
再來看看項目中Glide使用的版本:
可以看到項目中使用的Glide版本是4.5.0。
這時就想到真的很大概率是兩者的Glide版本有沖突瞭。
果然將容聯Demo中的Glide版本改成4.5.0之後,編譯運行進入客服界面後,沒有報錯瞭,完美解決。
4、android 7.0系統解決拍照的問題
報錯信息:
# main(1) android.os.FileUriExposedException file:///storage/emulated/0/xiangmu/3462884.jpg exposed beyond app through ClipData.Item.getUri() android.os.StrictMode.onFileUriExposed(StrictMode.java:1816) android.net.Uri.checkFileUriExposed(Uri.java:2350)
解決方法如下:
1.在相對應的頁面中,寫如下的方法:
private void initPhotoError(){ // android 7.0系統解決拍照的問題 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure(); }
2.在onCreate中調用上述的方法。
5、使用RecyclerView滑動閃退問題
錯誤信息:
圖片看起來不清晰,看報錯代碼:
IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter
看這個代碼,隻是並沒有報到我們自己的代碼裡面來,在底層就崩潰瞭,在app層面並沒有,彈出一個框,說應用程序已奔潰,而是直接就沒瞭,用戶感覺很奇怪。這種異常並不是很容易出現,而是偶爾出現,我的也是在後臺奔潰日志中,發現瞭這種異常,我們自己都不知道什麼地方報錯的。
解決方案如下:
1、創建一個類LinearLayoutManagerWrapper
繼承LinearLayoutManager,重寫onLayoutChildren方法
public class WrapContentLinearLayoutManager extends LinearLayoutManager { public WrapContentLinearLayoutManager(Context context) { super(context); } public WrapContentLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } public WrapContentLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { try { super.onLayoutChildren(recycler, state); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } }
2、設置RecyclerView的佈局管理為
WrapContentLinearLayoutManager對象
mRecyclerView.setLayoutManager(new WrapContentLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
其實這也不是什麼解決方案,隻是把這個異常捕獲瞭,不讓他奔潰瞭,這個問題的終極解決方案還是得讓google去修復。
以上就是Android 常見bug匯總及解決方案的詳細內容,更多關於Android 常見BUG及解決的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Android圖片加載庫Glide用法
- Android Coil對比Glide深入分析探究
- Android如何使用Glide加載清晰長圖
- Android實現簡單的banner輪播圖
- Android基礎入門之dataBinding的簡單使用教程