App Center Crashes for Android - Visual Studio - Microsoft Docs

文章推薦指數: 80 %
投票人數:10人

Collecting crashes works for both beta and live apps, i.e. those submitted to Google Play. Crash logs contain valuable information for you ... Skiptomaincontent Thisbrowserisnolongersupported. UpgradetoMicrosoftEdgetotakeadvantageofthelatestfeatures,securityupdates,andtechnicalsupport. DownloadMicrosoftEdge Moreinfo Tableofcontents Exitfocusmode Language ReadinEnglish Save Tableofcontents ReadinEnglish Save Feedback Edit Twitter LinkedIn Facebook Email Tableofcontents AppCenterCrashes(Android) Article 03/23/2021 10minutestoread 20contributors Isthispagehelpful? Yes No Anyadditionalfeedback? FeedbackwillbesenttoMicrosoft:Bypressingthesubmitbutton,yourfeedbackwillbeusedtoimproveMicrosoftproductsandservices.Privacypolicy. Submit Thankyou. Inthisarticle Android iOS ReactNative Xamarin UWP WPF/WinForms Unity macOS tvOS Cordova AppCenterCrasheswillautomaticallygenerateacrashlogeverytimeyourappcrashes.Thelogisfirstwrittentothedevice'sstorageandwhentheuserstartstheappagain,thecrashreportwillbesenttoAppCenter.Collectingcrashesworksforbothbetaandliveapps,i.e.thosesubmittedtoGooglePlay.Crashlogscontainvaluableinformationforyoutohelpfixthecrash. FollowtheGettingStartedsectionifyouhaven'tsetuptheSDKinyourapplicationyet. Generateatestcrash AppCenterCrashesprovidesyouwithanAPItogenerateatestcrashforeasytestingoftheSDK.ThisAPIcanonlybeusedindebugbuildsandwon'tdoanythinginreleasebuilds. Crashes.generateTestCrash(); Crashes.generateTestCrash() Getmoreinformationaboutapreviouscrash AppCenterCrasheshastwoAPIsthatgiveyoumoreinformationincaseyourapphascrashed. Didtheappreceivealowmemorywarningintheprevioussession? AtanytimeafterstartingtheSDK,youcancheckiftheappreceivedamemorywarningintheprevioussession: Crashes.hasReceivedMemoryWarningInLastSession(); Crashes.hasReceivedMemoryWarningInLastSession() ThisAPIisasynchronous,youcanreadmoreaboutthatinourAppCenterAsynchronousAPIsguide. Note ThismethodmustonlybeusedafterCrasheshasbeenstarted,itwillalwaysreturnfalsebeforestart. Note Insomecases,adevicewithlowmemorycan'tsendevents. Didtheappcrashintheprevioussession? AtanytimeafterstartingtheSDK,youcancheckiftheappcrashedinthepreviouslaunch: Crashes.hasCrashedInLastSession(); Crashes.hasCrashedInLastSession() ThisAPIisasynchronous,youcanreadmoreaboutthatinourAppCenterAsynchronousAPIsguide. ThiscomesinhandyincaseyouwanttoadjustthebehaviororUIofyourappafteracrashhasoccurred.SomedeveloperschosetoshowadditionalUItoapologizetotheirusers,orwantwaytogetintouchafteracrashhasoccurred. Note ThismethodmustonlybeusedafterCrasheshasbeenstarted,itwillalwaysreturnfalsebeforestart. Detailsaboutthelastcrash Ifyourappcrashedpreviously,youcangetdetailsaboutthelastcrash. Crashes.getLastSessionCrashReport(); Crashes.getLastSessionCrashReport() ThisAPIisasynchronous,youcanreadmoreaboutthatinourAppCenterAsynchronousAPIsguide. TherearenumeroususecasesforthisAPI,themostcommononeispeoplewhocallthisAPIandimplementtheircustomCrashesListener. Note ThismethodmustonlybeusedafterCrasheshasbeenstarted,itwillalwaysreturnnullbeforestart. CustomizeyourusageofAppCenterCrashes AppCenterCrashesprovidescallbacksfordeveloperstoperformadditionalactionsbeforeandwhensendingcrashlogstoAppCenter. Tohandlethecallbacks,eitherimplementallmethodsintheCrashesListenerinterface,oroverridetheAbstractCrashesListenerclassandpickonlytheonesyou'reinterestedin. UseyourownCrashesListener CreateyourownCrashesListenerandassignitlikethis: CrashesListenercustomListener=newCrashesListener(){ //Implementallcallbackshere. }; Crashes.setListener(customListener); valcustomListener=object:CrashesListener{ //Implementallcallbackshere. } Crashes.setListener(customListener) Incaseyou'reonlyinterestedincustomizingsomeofthecallbacks,usetheAbstractCrashesListenerinstead: AbstractCrashesListenercustomListener=newAbstractCrashesListener(){ //Implementanycallbackhereasrequired. }; Crashes.setListener(customListener); valcustomListener=object:AbstractCrashesListener(){ //Implementanycallbackhereasrequired. } Crashes.setListener(customListener) Note SetthelistenerbeforecallingAppCenter.start(),sinceAppCenterstartsprocessingcrashesimmediatelyafterthestart. Shouldthecrashbeprocessed? Implementthiscallbackifyouwanttodecideifaparticularcrashneedstobeprocessedornot.Forexample,therecouldbeasystemlevelcrashthatyou'dwanttoignoreandthatyoudon'twanttosendtoAppCenter. @Override publicbooleanshouldProcess(ErrorReportreport){ returntrue;//returntrueifthecrashreportshouldbeprocessed,otherwisefalse. } overridefunshouldProcess(report:ErrorReport?):Boolean{ returntrue } Askfortheuser'sconsenttosendacrashlog Ifuserprivacyisimportanttoyou,youmightwanttogetuserconfirmationbeforesendingacrashreporttoAppCenter.TheSDKexposesacallbackthattellsAppCenterCrashestoawaituserconfirmationbeforesendinganycrashreports. Ifyouchosetodoso,you'reresponsibleforobtainingtheuser'sconfirmation,e.g.throughadialogpromptwithoneofthefollowingoptions:AlwaysSend,Send,andDon'tsend.Basedontheinput,you'lltellAppCenterCrasheswhattodoandthecrashwillthenbehandledaccordingly. Note TheSDKdoesn'tdisplayadialogforthis,theappmustprovideitsownUItoaskforuserconsent. ThefollowingcallbackshowshowtotelltheSDKtowaitforuserconfirmationbeforesendingcrashes: @Override publicbooleanshouldAwaitUserConfirmation(){ //BuildyourownUItoaskforuserconsenthere.SDKdoesn'tprovideonebydefault. //ReturntrueifyoubuiltaUIforuserconsentandarewaitingforuserinputonthatcustomUI,otherwisefalse. returntrue; } overridefunshouldAwaitUserConfirmation():Boolean{ returntrue } Ifyoureturntrue,yourappmustobtain(usingyourowncode)theuser'spermissionandmessagetheSDKwiththeresultusingthefollowingAPI: //Dependingontheuser'schoice,callCrashes.notifyUserConfirmation()withtherightvalue. Crashes.notifyUserConfirmation(Crashes.DONT_SEND); Crashes.notifyUserConfirmation(Crashes.SEND); Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND); Crashes.notifyUserConfirmation(Crashes.DONT_SEND) Crashes.notifyUserConfirmation(Crashes.SEND) Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND) Asanexampleyoucanrefertoourcustomdialogexample. Getinformationaboutthesendingstatusforacrashlog Attimes,youwanttoknowthestatusofyourappcrash.AcommonusecaseisthatyoumightwanttoshowUIthattellstheusersthatyourappissubmittingacrashreport,or,incaseyourappiscrashingquicklyafterthelaunch,youwanttoadjustthebehavioroftheapptomakesurethecrashlogscanbesubmitted.AppCenterCrasheshasthreedifferentcallbacksthatyoucanuseinyourapptobenotifiedofwhat'sgoingon: ThefollowingcallbackwillbeinvokedbeforetheSDKsendsacrashlog @Override publicvoidonBeforeSending(ErrorReporterrorReport){ //Yourcode,e.g.topresentacustomUI. } overridefunonBeforeSending(report:ErrorReport?){ //Yourcode,e.g.topresentacustomUI. } Incasewehavenetworkissuesoranoutageontheendpoint,andyourestarttheapp,onBeforeSendingistriggeredagainafterprocessrestart. ThefollowingcallbackwillbeinvokedaftertheSDKsentacrashlogsuccessfully @Override publicvoidonSendingSucceeded(ErrorReportreport){ //Yourcode,e.g.tohidethecustomUI. } overridefunonSendingSucceeded(report:ErrorReport?){ //Yourcode,e.g.tohidethecustomUI. } ThefollowingcallbackwillbeinvokediftheSDKfailedtosendacrashlog @Override publicvoidonSendingFailed(ErrorReportreport,Exceptione){ //Yourcodegoeshere. } overridefunonSendingFailed(report:ErrorReport?,e:Exception?){ //Yourcodegoeshere. } ReceivingonSendingFailedmeansanon-recoverableerrorsuchasa4xxcodeoccurred.Forexample,401meanstheappSecretiswrong. Thiscallbackisn'ttriggeredifit'sanetworkissue.Inthiscase,theSDKkeepsretrying(andalsopausesretrieswhilethenetworkconnectionisdown). Addattachmentstoacrashreport Youcanaddbinaryandtextattachmentstoacrashreport.TheSDKwillsendthemalongwiththecrashsothatyoucanseetheminAppCenterportal.Thefollowingcallbackwillbeinvokedrightbeforesendingthestoredcrashfrompreviousapplicationlaunches.Itwon'tbeinvokedwhenthecrashhappens.Besuretheattachmentfileisn'tnamedminidump.dmpasthatnameisreservedforminidumpfiles.Here'sanexampleofhowtoattachtextandanimagetoacrash: @Override publicIterablegetErrorAttachments(ErrorReportreport){ //Attachsometext. ErrorAttachmentLogtextLog=ErrorAttachmentLog.attachmentWithText("Thisisatextattachment.","text.txt"); //Attachbinarydata. byte[]binaryData=getYourBinary(); ErrorAttachmentLogbinaryLog=ErrorAttachmentLog.attachmentWithBinary(binaryData,"your_filename.jpeg","image/jpeg"); //Returnattachmentsaslist. returnArrays.asList(textLog,binaryLog); } overridefungetErrorAttachments(report:ErrorReport?):MutableIterable{ //Attachsometext. valtextLog=ErrorAttachmentLog.attachmentWithText("Thisisatextattachment.","text.txt") //Attachbinarydata. valbinaryData=getYourBinary() valbinaryLog=ErrorAttachmentLog.attachmentWithBinary(binaryData,"your_filename.jpeg","image/jpeg") //Returnattachmentsaslist. returnlistOf(textLog,binaryLog) } Note Thesizelimitiscurrently7MB.Attemptingtosendalargerattachmentwilltriggeranerror. EnableordisableAppCenterCrashesatruntime YoucanenableanddisableAppCenterCrashesatruntime.Ifyoudisableit,theSDKwon'tdoanycrashreportingfortheapp. Crashes.setEnabled(false); Crashes.setEnabled(false) ToenableAppCenterCrashesagain,usethesameAPIbutpasstrueasaparameter. Crashes.setEnabled(true); Crashes.setEnabled(true) Thestateispersistedinthedevice'sstorageacrossapplicationlaunches. ThisAPIisasynchronous,youcanreadmoreaboutthatinourAppCenterAsynchronousAPIsguide. Note ThismethodmustonlybeusedafterCrasheshasbeenstarted. CheckifAppCenterCrashesisenabled YoucanalsocheckifAppCenterCrashesisenabledornot: Crashes.isEnabled(); Crashes.isEnabled() ThisAPIisasynchronous,youcanreadmoreaboutthatinourAppCenterAsynchronousAPIsguide. Note ThismethodmustonlybeusedafterCrasheshasbeenstarted,itwillalwaysreturnfalsebeforestart. HandledErrors AppCenteralsoallowsyoutotrackerrorsbyusinghandledexceptions.Todoso,usethetrackErrormethod: try{ //yourcodegoeshere. }catch(Exceptionexception){ Crashes.trackError(exception); } try{ //yourcodegoeshere. }catch(exception:Exception){ Crashes.trackError(exception) } Anappcanoptionallyattachpropertiestoahandlederrorreporttoprovidefurthercontext.Passthepropertiesasamapofkey/valuepairs(stringsonly)asshownintheexamplebelow. try{ //yourcodegoeshere. }catch(Exceptionexception){ Mapproperties=newHashMap(){{ put("Category","Music"); put("Wifi","On"); }}; Crashes.trackError(exception,properties,null); } try{ //yourcodegoeshere. }catch(exception:Exception){ valproperties=mapOf("Category"to"Music","Wifi"to"On") Crashes.trackError(exception,properties,null) } Youcanalsooptionallyaddbinaryandtextattachmentstoahandlederrorreport.PasstheattachmentsasanIterableasshownintheexamplebelow. try{ //yourcodegoeshere. }catch(Exceptionexception){ //Attachsometext. ErrorAttachmentLogtextLog=ErrorAttachmentLog.attachmentWithText("Thisisatextattachment.","text.txt"); //Attachbinarydata. byte[]binaryData=getYourBinary(); ErrorAttachmentLogbinaryLog=ErrorAttachmentLog.attachmentWithBinary(binaryData,"your_filename.jpeg","image/jpeg"); //Trackanexceptionwithattachments. Crashes.trackError(exception,null,Arrays.asList(textLog,binaryLog)); } try{ //yourcodegoeshere. }catch(exception:Exception){ //Attachsometext. valtextLog=ErrorAttachmentLog.attachmentWithText("Thisisatextattachment.","text.txt") //Attachbinarydata. valbinaryData=getYourBinary() valbinaryLog=ErrorAttachmentLog.attachmentWithBinary(binaryData,"your_filename.jpeg","image/jpeg") //Trackanexceptionwithattachments. Crashes.trackError(exception,null,listOf(textLog,binaryLog)) } ReportingNDKcrashes Reportingcrashes ToreceivepropercrashreportsinAppCenter,firstmakesureyouhavetheAppCenterCrashesSDKsetupbyfollowingtheinstructionslistedabove. Buildingthebreakpadlibrary Next,includeandcompileGoogleBreakpadbyfollowingtheinstructionslistedintheofficialGoogleBreakpadforAndroidREADME. Note TheAppCenterSDKdoesn'tbundleGoogleBreakpadbydefault. Attachingtheexceptionhandler OnceyouhaveGoogleBreakpadincluded,attachtheNDKCrashHandlerafterAppCenter.start: //AttachNDKCrashHandlerafterSDKisinitialized. Crashes.getMinidumpDirectory().thenAccept(newAppCenterConsumer(){ @Override publicvoidaccept(Stringpath){ //PathisnullwhenCrashesisdisabled. if(path!=null){ setupNativeCrashesListener(path); } } }); ThemethodsetupNativeCrashesListenerisanativemethodthatyoumustimplementinC/C++: #include"google-breakpad/src/client/linux/handler/exception_handler.h" #include"google-breakpad/src/client/linux/handler/minidump_descriptor.h" voidJava_com_microsoft_your_package_YourActivity_setupNativeCrashesListener( JNIEnv*env,jobject,jstringpath){ constchar*dumpPath=(char*)env->GetStringUTFChars(path,NULL); google_breakpad::MinidumpDescriptordescriptor(dumpPath); newgoogle_breakpad::ExceptionHandler(descriptor,NULL,dumpCallback,NULL,true,-1); env->ReleaseStringUTFChars(path,dumpPath); } WheredumpCallbackisusedfortroubleshooting: /* *Triggeredautomaticallyafteranattempttowriteaminidumpfiletothebreakpadfolder. */ booldumpCallback(constgoogle_breakpad::MinidumpDescriptor&descriptor, void*context, boolsucceeded){ //Allowsystemtologthenativestacktrace. __android_log_print(ANDROID_LOG_INFO,"YourLogTag", "Wrotebreakpadminidumpat%ssucceeded=%d\n",descriptor.path(), succeeded); returnfalse; } Oncethesemethodsareproperlysetup,theappsendstheminidumptoAppCenterautomaticallyuponrestart. Totroubleshoot,youcanuseverboselogs(AppCenter.setLogLevel(Log.VERBOSE)beforeAppCenter.start)tocheckifminidumpsaresentaftertheappisrestarted. Note AppCenterusesthereservednameminidump.dmpforminidumpattachments.Makesuretogiveyourattachmentadifferentnameunlessit'saminidumpfilesowecanhandleitproperly. Note There'saknownbuginbreakpadwhichmakesitimpossibletocapturecrashesonx86emulators. Symbolication SeetheDiagnosticsdocumentationformoreinformationregardingtheprocessingofcrashes. Feedback Submitandviewfeedbackfor Thisproduct Thispage Viewallpagefeedback Inthisarticle



請為這篇文章評分?