java crash是什么,讓我們一起了解一下:
Crash就是由于代碼異常而導致App非正常退出現象,也就是常說的崩潰。在工作目錄下會產生一個日志文件,而java crash通過簡單的方式就能夠捕獲到異常。
那么在java進程中crash產生錯誤了怎么辦?
如果有一個嚴重的錯誤引起Java進程非正常退出,我們叫Crash,這時候會產生一個日志文件,缺省情況下,這個文件會產生在工作目錄下,但是,可以在Java啟動參數通過下面的設置,來改變這個文件的位置和命名規則。例如:java -XX:ErrorFile=/var/log/java/java_error_%p.log。就將這個錯誤文件放在/var/log/java下,并且以java_error_pid.log的形式出現。
#!/usr/sbin/dtrace?-qs proc:::signal-send /args[1]->pr_pid?==?$1/ { printf("%s(pid:%d)?is?sending?signal?%d?to?%s"n",?execname,?pid,?args[2],args[1]->pr_fname); }
案例分析java crash的具體使用:以Android Crash之Java Crash為例。
首先我們要了解Android的Crash類型,那在Android中通常有兩種Crash類型,分別是Java Crash和Native Crash。
Java Crash在Android上的特點是什么?1、這類錯誤一般是由Java層代碼觸發的。2、一般情況下程序出錯時會彈出提示框,JVM虛擬機退出。3、一般的Crash工具都能夠捕獲,系統也提供了API。
我們通過UncaughtExceptionHandler來記錄dump異常日志代碼如下:
package?com.devilwwj.androidcrashdemo; /** ?*?com.devilwwj.androidcrashdemo ?*?Created?by?devilwwj?on?16/5/27. ?*/ import?android.content.Context; import?android.content.pm.PackageInfo; import?android.content.pm.PackageManager; import?android.content.pm.PackageManager.NameNotFoundException; import?android.os.Build; import?android.os.Environment; import?android.os.Process; import?android.util.Log; import?java.io.BufferedWriter; import?java.io.File; import?java.io.FileWriter; import?java.io.IOException; import?java.io.PrintWriter; import?java.lang.Thread.UncaughtExceptionHandler; import?java.text.SimpleDateFormat; import?java.util.Date; public?class?CrashHandler?implements?UncaughtExceptionHandler?{ ????private?static?final?String?TAG?=?"CrashHandler"; ????private?static?final?boolean?DEBUG?=?true; ????private?static?final?String?PATH?=?Environment ????????????.getExternalStorageDirectory()?+?"/CrashDemo/log/"; ????private?static?final?String?FILE_NAME?=?"crash"; ????private?static?final?String?FILE_NAME_SUFFIX?=?".trace"; ????private?static?final?String?ABOLUTE_PATH?=?PATH?+?FILE_NAME?+?FILE_NAME_SUFFIX; ????private?String?deviceToken; ????private?static?CrashHandler?sInstance?=?new?CrashHandler(); ????private?UncaughtExceptionHandler?mDefaultCrashHandler; ????private?Context?mContext; ????private?CrashHandler()?{ ????} ????public?static?CrashHandler?getInstance()?{ ????????return?sInstance; ????} ????public?void?init(Context?context)?{ ????????mDefaultCrashHandler?=?Thread.getDefaultUncaughtExceptionHandler(); ????????Thread.setDefaultUncaughtExceptionHandler(this); ????????mContext?=?context.getApplicationContext(); ????} ????/** ?????*?這個是最關鍵的函數,當程序中有未被捕獲的異常,系統將會自動調用#uncaughtException方法 ?????*?thread為出現未捕獲異常的線程,ex為未捕獲的異常,有了這個ex,我們就可以得到異常信息。 ?????*/ ????@Override ????public?void?uncaughtException(Thread?thread,?Throwable?ex)?{ ????????try?{ ????????????//?導出異常信息到SD卡中 ????????????dumpExceptionToSDCard(ex); ????????}?catch?(IOException?e)?{ ????????????e.printStackTrace(); ????????} ????????ex.printStackTrace(); ????????//?如果系統提供了默認的異常處理器,則交給系統去結束我們的程序,否則就由我們自己結束自己 ????????if?(mDefaultCrashHandler?!=?null)?{ ????????????mDefaultCrashHandler.uncaughtException(thread,?ex); ????????}?else?{ ????????????Process.killProcess(Process.myPid()); ????????} ????} ????private?File?dumpExceptionToSDCard(Throwable?ex)?throws?IOException?{ ????????//?如果SD卡不存在或無法使用,則無法把異常信息寫入SD卡 ????????if?(!Environment.getExternalStorageState().equals( ????????????????Environment.MEDIA_MOUNTED))?{ ????????????if?(DEBUG)?{ ????????????????Log.w(TAG,?"sdcard?unmounted,skip?dump?exception"); ????????????????return?null; ????????????} ????????} ????????File?dir?=?new?File(PATH); ????????if?(!dir.exists())?{ ????????????dir.mkdirs(); ????????} ????????long?current?=?System.currentTimeMillis(); ????????String?time?=?new?SimpleDateFormat("yyyy-MM-dd?HH:mm:ss") ????????????????.format(new?Date(current)); ????????//?File?file?=?new?File(PATH?+?FILE_NAME?+?time?+?"_"+?deviceToken?+ ????????//?FILE_NAME_SUFFIX); ????????File?file?=?new?File(PATH?+?FILE_NAME?+?FILE_NAME_SUFFIX); ????????if?(!file.exists())?{ ????????????file.createNewFile(); ????????}?else?{ ????????????try?{ ????????????????//?追加內容 ????????????????PrintWriter?pw?=?new?PrintWriter(new?BufferedWriter( ????????????????????????new?FileWriter(file,?true))); ????????????????pw.println(time); ????????????????dumpPhoneInfo(pw); ????????????????pw.println(); ????????????????ex.printStackTrace(pw); ????????????????pw.println("---------------------------------分割線----------------------------------"); ????????????????pw.println(); ????????????????pw.close(); ????????????}?catch?(Exception?e)?{ ????????????????Log.e(TAG,?"dump?crash?info?failed"); ????????????} ????????} ????????return?file; ????} ????private?void?dumpPhoneInfo(PrintWriter?pw)?throws?NameNotFoundException?{ ????????PackageManager?pm?=?mContext.getPackageManager(); ????????PackageInfo?pi?=?pm.getPackageInfo(mContext.getPackageName(), ????????????????PackageManager.GET_ACTIVITIES); ????????pw.print("App?Version:?"); ????????pw.print(pi.versionName); ????????pw.print('_'); ????????pw.println(pi.versionCode); ????????//?android版本號 ????????pw.print("OS?Version:?"); ????????pw.print(Build.VERSION.RELEASE); ????????pw.print("_"); ????????pw.println(Build.VERSION.SDK_INT); ????????//?手機制造商 ????????pw.print("Vendor:?"); ????????pw.println(Build.MANUFACTURER); ????????//?手機型號 ????????pw.print("Model:?"); ????????pw.println(Build.MODEL); ????????//?cpu架構 ????????pw.print("CPU?ABI:?"); ????????pw.println(Build.CPU_ABI); ????} ????/** ?????*?提供方法上傳異常信息到服務器 ?????*?@param?log ?????*/ ????private?void?uploadExceptionToServer(File?log)?{ ????????//?TODO?Upload?Exception?Message?To?Your?Web?Server ????} }
上面是核心代碼,可以直接拿去用,可以在Application類中進行初始化。
以上就是小編今天的分享了,希望可以幫助到大家。