自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android中各種Exception錯(cuò)誤小結(jié)

移動(dòng)開發(fā) Android
通過Binding方式獲取的PreviewView對(duì)象不存在。我們布局中如果是存在該View,但是仍然出現(xiàn)這個(gè)錯(cuò)誤。那么只有一種情況。就是viewBinding還沒有來得及初始化之前,就調(diào)用了viewBinding的方法去獲取PreviewView對(duì)象了。就會(huì)出現(xiàn)上面的問題了。

1. 介紹

匯總了部分的崩潰異常日志內(nèi)容,以及相關(guān)問題的解決方法。希望給大家一點(diǎn)參考。

問題都比較簡(jiǎn)單。

2. Exception

簡(jiǎn)單匯總一些常見的異常情況,以及相關(guān)的解決方法

2.1 IllegalArgumentException錯(cuò)誤

IllegalArgumentException:非法數(shù)據(jù)異常。

問題1:

java.lang.IllegalArgumentException: The key must be an application-specific resource id.

The key must be an application-specific resource id:密鑰必須是特定于應(yīng)用程序的資源id。

解釋:

出現(xiàn)問題的原因在于我們給View添加Tag內(nèi)容時(shí),其中的Key的值并不能隨便寫個(gè)int值,如果隨便寫個(gè)int值就會(huì)出現(xiàn)上面的錯(cuò)誤了。

我們必須在xml文件中創(chuàng)建一個(gè)id值,然后再填寫到key中。

錯(cuò)誤寫法:

binding.tvState.setTag(101, data);

正確寫法:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="key_task" type="id" />
</resources>


binding.tvState.setTag(R.id.key_task, data);

問題2:

java.lang.IllegalArgumentException: Trying to create LifecycleCamera with destroyed lifecycle.

試圖創(chuàng)建生命周期被破壞的LifecycleCamera。

解釋:

也就說我們?cè)谡{(diào)用cameraProvider.bindToLifecycle的時(shí)候。中間步驟出現(xiàn)了崩潰或其他問題。

造成lifecycle被銷毀了。然后出現(xiàn)的錯(cuò)誤。檢測(cè)出現(xiàn)的代碼。

2.2 ExifInterface 異常

在新項(xiàng)目中使用Glide庫進(jìn)行圖片下載的時(shí)候,每加載一次圖片都會(huì)出現(xiàn)下面的異常:

W/ExifInterface: Invalid image: ExifInterface got an unsupported image format file(ExifInterface supports JPEG and some RAW image formats only) or a corrupted JPEG file to ExifInterface.
java.io.IOException: Invalid byte order: ffff8950
at android.media.ExifInterface.readByteOrder(ExifInterface.java:3128)
at android.media.ExifInterface.isOrfFormat(ExifInterface.java:2443)
at android.media.ExifInterface.getMimeType(ExifInterface.java:2321)
at android.media.ExifInterface.loadAttributes(ExifInterface.java:1755)
at android.media.ExifInterface.<init>(ExifInterface.java:1449)
at com.bumptech.glide.load.resource.bitmap.ExifInterfaceImageHeaderParser.getOrientation(ExifInterfaceImageHeaderParser.java:40)
at com.bumptech.glide.load.ImageHeaderParserUtils.getOrientation(ImageHeaderParserUtils.java:92)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decodeFromWrappedStreams(Downsampler.java:269)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:224)
at com.bumptech.glide.load.resource.bitmap.Downsampler.decode(Downsampler.java:173)
at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:31)
at com.bumptech.glide.load.resource.bitmap.ByteBufferBitmapDecoder.decode(ByteBufferBitmapDecoder.java:14)
at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:524)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:488)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:474)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:426)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:390)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:94)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:70)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:74)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:276)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:431)

然后圖片仍然是能夠進(jìn)行加載顯示的。發(fā)現(xiàn)只有鏈接地址是https的圖片才會(huì)出現(xiàn)上面的錯(cuò)誤。而http請(qǐng)求反而不會(huì)出現(xiàn)異常。

運(yùn)行設(shè)備為:Android 10 API 29

解決方法:將Glide插件的版本進(jìn)行了升級(jí),該錯(cuò)誤打印就沒有了。

原版本:

implementation 'com.github.bumptech.glide:glide:4.10.0'

新版本:

implementation 'com.github.bumptech.glide:glide:4.14.2'

問題得到了解決。

2.3 RuntimeException

RuntimeException:運(yùn)行時(shí)異常。只有當(dāng)程序運(yùn)行到該行代碼的時(shí)候,才會(huì)被觸發(fā)的異常情況。

問題1:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.xxx/com.xxx.xx.activity.login.XXXX}: java.lang.NullPointerException: Attempt to read from field 'androidx.camera.view.PreviewView com.xxx.xxx.databinding.XXXXXXXeBinding.previewView' on a null object reference

完整錯(cuò)誤通常如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.xxx/com.xxx.xx.activity.login.XXXX}: java.lang.NullPointerException: Attempt to read from field 'androidx.camera.view.PreviewView com.xxx.xxx.databinding.XXXXXXXeBinding.previewView' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3437)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2041)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)

解決:

通過Binding方式獲取的PreviewView對(duì)象不存在。我們布局中如果是存在該View,但是仍然出現(xiàn)這個(gè)錯(cuò)誤。

那么只有一種情況。就是viewBinding還沒有來得及初始化之前,就調(diào)用了viewBinding的方法去獲取PreviewView對(duì)象了。就會(huì)出現(xiàn)上面的問題了。

通常情況下,我們可能是在View初始化之前,調(diào)用了動(dòng)態(tài)權(quán)限判斷,而動(dòng)態(tài)權(quán)限判斷通過后就直接開啟相機(jī)了。

而在這個(gè)時(shí)候我們View還沒有來得及binding獲取。

通過Binding 方法調(diào)用觸發(fā)view綁定,也是有執(zhí)行順序和時(shí)間的。

問題2:

運(yùn)行時(shí)崩潰異常如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xx.xx/com.xxx.xx.xx.login.xxx}: java.lang.IllegalArgumentException: Provided camera selector unable to resolve a camera for the given use case
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2671)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1483)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6141)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
Caused by: java.lang.IllegalArgumentException: Provided camera selector unable to resolve a camera for the given use case
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:470)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:360)

關(guān)鍵內(nèi)容為:Provided camera selector unable to resolve a camera for the given use case翻譯后顯示:提供的攝像機(jī)選擇器無法解析給定用例的攝像機(jī).

問題在于,我們使用CameraX的時(shí)候,設(shè)備主機(jī)沒有找到攝像頭。通常手機(jī)是不會(huì)出現(xiàn)這個(gè)問題的,只是可能在其他Android主板系統(tǒng)中進(jìn)行開發(fā)時(shí),可能當(dāng)前硬件還沒有來得及配置上攝像頭,而我們的app調(diào)用到了攝像頭相關(guān)代碼。就會(huì)觸發(fā)上面的錯(cuò)誤了。

而CameraX本身默認(rèn)是會(huì)自動(dòng)選擇攝像頭的。但是我們定義了CameraSelector指定了攝像頭。而又找不到指定攝像頭,就會(huì)出現(xiàn)這個(gè)錯(cuò)誤了。

解決:

上面的代碼觸發(fā)的時(shí)候,是在:

cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);

這一行代碼中觸發(fā)的。而這個(gè)配置是在try/cathc包裹中。我們只需要主動(dòng)捕獲一下IllegalArgumentException 異常就可以避免崩潰了。

try {
...
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);

catch (IllegalArgumentException e) {
e.printStackTrace();
catch (Exception e) {
e.printStackTrace();
}

但是,這樣不夠優(yōu)美。最好的方法就是在需要啟動(dòng)相機(jī)相關(guān)界面時(shí),檢測(cè)一下設(shè)備是否存在攝像頭。效果會(huì)更好一些。

檢測(cè)方法比較簡(jiǎn)單

boolean isBack = cameraProvider.hasCamera(CameraSelector.DEFAULT_BACK_CAMERA);  //檢測(cè)默認(rèn)后置攝像頭
boolean isFront = cameraProvider.hasCamera(CameraSelector.DEFAULT_FRONT_CAMERA); //檢測(cè)默認(rèn)前置攝像頭

可以通過這兩個(gè)方法檢測(cè)設(shè)備是否存在默認(rèn)攝像頭,但是如果是通過USB,藍(lán)牙等方式動(dòng)態(tài)添加的攝像頭。上面兩種方法可不會(huì)檢測(cè)到。

我們可以通過獲取CameraInfo列表來判斷是否有相機(jī):

List<CameraInfo> camerList = provider.getAvailableCameraInfos();//得到相機(jī)列表
//然后根據(jù)設(shè)備信息列表,得到硬件等級(jí)最高的相機(jī)
if (camerList == null || camerList.size() == 0) {
return null; //沒有攝像頭
}

問題3:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx.xxx/com.xxx.xxx.activity.xx.xx}: java.lang.IllegalArgumentException: LayoutManager androidx.recyclerview.widget.LinearLayoutManager@ed46d74 is already attached to a RecyclerView: androidx.recyclerview.widget.RecyclerView{584229d VFED..... ......I. 0,0-0,0 #7f0901a0 app:id/recyclerClass}, adapter:com.xxx.xx.xx.xxx@e3cc312, layout:androidx.recyclerview.widget.LinearLayoutManager@ed46d74, context:com.xxx.xx.xx.xxx.xxx@19aeae4
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3437)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2041)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)

解決:

當(dāng)我們?cè)谕粋€(gè)界面中多個(gè)RecyclerView? 使用同一個(gè)LinearLayoutManager?或者GridLayoutManager的時(shí)候就會(huì)觸發(fā)上面的運(yùn)行時(shí)錯(cuò)誤了。程序就會(huì)崩潰

錯(cuò)誤寫法:

LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this,RecyclerView.VERTICAL,false);
viewBinding.recyclerClass.setLayoutManager(linearLayoutManager);

viewBinding.recyclerGrop.setLayoutManager(linearLayoutManager);

在上面,兩個(gè)recyclerView? 使用了同一個(gè)LinearLayoutManager。就會(huì)觸發(fā)崩潰了。

正確寫法為:

viewBinding.recyclerClass.setLayoutManager(new LinearLayoutManager(this,RecyclerView.VERTICAL,false));

viewBinding.recyclerGrop.setLayoutManager(new LinearLayoutManager(this,RecyclerView.VERTICAL,false));
責(zé)任編輯:武曉燕 來源: zinyan
相關(guān)推薦

2009-03-24 08:35:57

AndroidGoogle移動(dòng)os

2009-05-30 09:24:24

AndroidGoogle移動(dòng)OS

2024-10-15 10:57:27

2017-02-15 12:59:23

Android渠道打包技術(shù)小結(jié)

2011-11-29 09:14:48

JavaError異常

2010-01-28 15:20:06

Android Jav

2012-01-16 14:02:52

2014-03-18 11:05:16

Android應(yīng)用導(dǎo)航設(shè)計(jì)錯(cuò)誤

2015-06-09 14:43:36

javascript操作字符串

2011-12-01 10:55:34

2013-09-13 14:43:16

2017-04-27 21:00:33

Android滑動(dòng)分析

2013-08-07 10:16:43

Android內(nèi)存泄漏

2010-03-05 10:50:43

2019-04-16 15:18:28

SQLJOIN數(shù)據(jù)庫

2011-06-24 14:17:58

Qt 容器類 QVector

2009-07-01 16:26:10

jsp web開發(fā)

2013-04-15 09:48:40

AndroidAVD錯(cuò)誤處理方法

2015-06-10 10:54:24

自定義路PHP

2013-07-04 15:05:14

Android
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)