pull/32/head
parent
f47765d1c6
commit
2f3093c2a9
@ -0,0 +1,150 @@ |
||||
package io.legado.app.help |
||||
|
||||
import android.annotation.SuppressLint |
||||
import android.content.Context |
||||
import android.content.pm.PackageManager |
||||
import android.os.Build |
||||
import android.os.Handler |
||||
import android.os.Looper |
||||
import android.util.Log |
||||
import android.widget.Toast |
||||
import java.io.File |
||||
import java.io.FileOutputStream |
||||
import java.io.PrintWriter |
||||
import java.io.StringWriter |
||||
import java.text.SimpleDateFormat |
||||
import java.util.* |
||||
|
||||
/** |
||||
* 异常管理类 |
||||
*/ |
||||
class CrashHandler : Thread.UncaughtExceptionHandler { |
||||
private val tag = this.javaClass.simpleName |
||||
/** |
||||
* 系统默认UncaughtExceptionHandler |
||||
*/ |
||||
private var mDefaultHandler: Thread.UncaughtExceptionHandler? = null |
||||
|
||||
/** |
||||
* context |
||||
*/ |
||||
private var mContext: Context? = null |
||||
|
||||
/** |
||||
* 存储异常和参数信息 |
||||
*/ |
||||
private val paramsMap = HashMap<String, String>() |
||||
|
||||
/** |
||||
* 格式化时间 |
||||
*/ |
||||
@SuppressLint("SimpleDateFormat") |
||||
private val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss") |
||||
|
||||
fun init(context: Context) { |
||||
mContext = context |
||||
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler() |
||||
//设置该CrashHandler为系统默认的 |
||||
Thread.setDefaultUncaughtExceptionHandler(this) |
||||
} |
||||
|
||||
/** |
||||
* uncaughtException 回调函数 |
||||
*/ |
||||
override fun uncaughtException(thread: Thread, ex: Throwable) { |
||||
handleException(ex) |
||||
mDefaultHandler?.uncaughtException(thread, ex) |
||||
} |
||||
|
||||
/** |
||||
* 处理该异常 |
||||
*/ |
||||
private fun handleException(ex: Throwable?) { |
||||
if (ex == null) return |
||||
//收集设备参数信息 |
||||
collectDeviceInfo(mContext!!) |
||||
//添加自定义信息 |
||||
addCustomInfo() |
||||
kotlin.runCatching { |
||||
//使用Toast来显示异常信息 |
||||
Handler(Looper.getMainLooper()).post { |
||||
Toast.makeText( |
||||
mContext, |
||||
ex.message, |
||||
Toast.LENGTH_LONG |
||||
).show() |
||||
} |
||||
} |
||||
//保存日志文件 |
||||
saveCrashInfo2File(ex) |
||||
} |
||||
|
||||
/** |
||||
* 收集设备参数信息 |
||||
*/ |
||||
private fun collectDeviceInfo(ctx: Context) { |
||||
//获取versionName,versionCode |
||||
kotlin.runCatching { |
||||
val pm = ctx.packageManager |
||||
val pi = pm.getPackageInfo(ctx.packageName, PackageManager.GET_ACTIVITIES) |
||||
if (pi != null) { |
||||
val versionName = if (pi.versionName == null) "null" else pi.versionName |
||||
val versionCode = pi.versionCode.toString() + "" |
||||
paramsMap["versionName"] = versionName |
||||
paramsMap["versionCode"] = versionCode |
||||
} |
||||
} |
||||
|
||||
//获取所有系统信息 |
||||
val fields = Build::class.java.declaredFields |
||||
kotlin.runCatching { |
||||
for (field in fields) { |
||||
field.isAccessible = true |
||||
paramsMap[field.name] = field.get(null).toString() |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 添加自定义参数 |
||||
*/ |
||||
private fun addCustomInfo() { |
||||
Log.i(tag, "addCustomInfo: 程序出错了...") |
||||
} |
||||
|
||||
/** |
||||
* 保存错误信息到文件中 |
||||
*/ |
||||
private fun saveCrashInfo2File(ex: Throwable) { |
||||
kotlin.runCatching { |
||||
val sb = StringBuilder() |
||||
for ((key, value) in paramsMap) { |
||||
sb.append(key).append("=").append(value).append("\n") |
||||
} |
||||
|
||||
val writer = StringWriter() |
||||
val printWriter = PrintWriter(writer) |
||||
ex.printStackTrace(printWriter) |
||||
var cause: Throwable? = ex.cause |
||||
while (cause != null) { |
||||
cause.printStackTrace(printWriter) |
||||
cause = cause.cause |
||||
} |
||||
printWriter.close() |
||||
val result = writer.toString() |
||||
sb.append(result) |
||||
val timestamp = System.currentTimeMillis() |
||||
val time = format.format(Date()) |
||||
val fileName = "crash-$time-$timestamp.log" |
||||
val path = mContext?.externalCacheDir?.toString() + "/crash/" |
||||
val dir = File(path) |
||||
if (!dir.exists()) { |
||||
dir.mkdirs() |
||||
} |
||||
val fos = FileOutputStream(path + fileName) |
||||
fos.write(sb.toString().toByteArray()) |
||||
fos.close() |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue