使用kotlin写个异常小框架
2017-05-21 20:06 阅读(282)


当捕获到异常时把异常的关键信息打印出来


import android.content.Context
import android.graphics.Color
import android.graphics.PixelFormat
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.TextView
import java.io.FileNotFoundException


/**
 * Created by lin on 2017/5/21.
 */
//实现OnClickLintener接口
class ExceptionUtils : View.OnClickListener {
    override fun onClick(v: View?) {
        dismiss()
    }

    private var mContext: Context? = null
    // 用来往顶层布局加或删视图
    private var mWm: WindowManager? = null
    // 吐司展示的布局
    private var mView: TextView? = null
    // 布局参数对象
    private var mParams: WindowManager.LayoutParams? = null


    constructor(context: Context) {
        mContext = context
        mWm = mContext?.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        mParams = WindowManager.LayoutParams()
        mParams?.width = WindowManager.LayoutParams.MATCH_PARENT
        // layout_height
        mParams?.height = WindowManager.LayoutParams.WRAP_CONTENT
        // gravity
        mParams?.gravity = Gravity.CENTER
        mParams?.format = PixelFormat.TRANSPARENT//
        mParams?.x = 100
        mParams?.y = 100
        // 类型
        mParams?.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE
        // 特殊属性
        mParams?.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE


    }

    fun show(exception: Exception,name:String) {
        dismiss()
        //创建TextView
        mView = TextView(mContext)
        mView?.setBackgroundColor(Color.GREEN)

        exception.printStackTrace()
        var content: String = ""
        val stackTrace = exception.stackTrace
        if (stackTrace.size > 0) {
            var error: String = ""
            if (exception is NullPointerException) {
                error = "NullPointerException(空指针异常)"
            } else if (exception is IllegalArgumentException) {
                error = "IllegalArgumentException(非法参数异常)"
            } else if (exception is ClassNotFoundException) {
                error = "ClassNotFoundException(找不到这个类(使用反射可能出现))"
            } else if (exception is FileNotFoundException) {
                error = "FileNotFoundException(找不到文件夹)"
            }else if (exception is ArithmeticException) {
                error = "ArithmeticException(计算异常)"
            }else if (exception is ArrayIndexOutOfBoundsException) {
                error = "ArrayIndexOutOfBoundsException(数组越界异常)"
            } else if (exception is RuntimeException) {
                error = "RuntimeException(运行时异常)"
            }
            var index: Int = 0
            for (i in 0..stackTrace.size - 1) {
                val element = stackTrace.get(i)
                if (element.className.equals(name)) {
                    index = i
                    break
                }
            }

            content = "class:" + stackTrace[index].className + "\n lineNumber:" + stackTrace[index].lineNumber + "\n caused:" + exception.message + "\n error:" + error
        }
        mView?.text=content
        mView?.setOnClickListener(this)

//        将TextView加到window
        mWm?.addView(mView, mParams)// 1.布局 2.布局参数对象
    }


    fun dismiss() {
        if (mView != null) {
            mWm?.removeView(mView)
            mView = null
        }
    }

}

在window需要 权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

测试


布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <Button
        android:id="@+id/button"
        android:text="计算"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import com.newframwork.utils.ExceptionUtils
import kotlinx.android.synthetic.main.activity_main2.*

class Main2Activity : AppCompatActivity(), View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        //不需要findViewById,导对包就能只接用id做变量
        button.setOnClickListener(this)
    }
    override fun onClick(v: View?) {
        if (v?.id == R.id.button) {
            try {
                var i:Int = 10/0;
            } catch (e: Exception) {
                e.printStackTrace()
                ExceptionUtils(this).show(e,javaClass.name);
            }
        }
    }
}



作者:敲代码的皮皮虾