Android 获取当前的类名,包名,路径等

在做项目时,无论为了功能还是调试,很多时候都需要获取到当前类的类名,包名,路径等等。

在这里总结一下,以便总结和以后需要的时候更快的解决问题。

1.在当前类获取当前的类名:

strings.add(getClass().getName());  //base.activity.SplashActivity
strings.add(getClass().toString()); //class base.activity.SplashActivity
strings.add(getClass().getSimpleName()); //SplashActivity
strings.add(getClass().getCanonicalName());//base.activity.SplashActivity
strings.add(getClass().getTypeName());//base.activity.SplashActivity
strings.add(getPackageName());//com.vkkk.kzb
strings.add(getLocalClassName());//base.activity.SplashActivity
LogUtils.iTag("类名测试",strings);

2.检测某ActivityUpdate是否在当前Task的栈顶(获取当前正在栈顶的任务)

public static boolean isTopActivy(String cmdName, Context context)
    {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(Integer.MAX_VALUE);//取个1
        String cmpNameTemp = null;
        if (null != runningTaskInfos)
        {
            //获取栈顶activity信息  获取到的是完整路径名,而不是简化,简化的请用getSimpleName。
            cmpNameTemp = runningTasks.get(0).topActivity.getClassName();
        }
        if (null == cmpNameTemp)
        {
            return false;
        }
        return cmpNameTemp.equals(cmdName);
    }

1.在项目中,需要拦截当前崩溃的信息和当前acticity以便于后台统计。所以我在父类BaseActicity中初始化CrashUtils工具类:

CrashUtils工具类会打印Bug的具体信息,以供技术人员更好的发现和解决问题,在blankj工具库里面,直接调用就行

CrashUtils.init(new CrashUtils.OnCrashListener() {
            @Override
            public void onCrash(CrashUtils.CrashInfo crashInfo) {
                String str = crashInfo.toString();
                LogUtils.eTag("崩溃拦截",str);
                SP.getInstance().setErr(str);//存储错误信息到本地

                ActivityManager manager = (ActivityManager)application.getSystemService(Context.ACTIVITY_SERVICE);
                List<ActivityManager.RunningTaskInfo> runningTasks = manager .getRunningTasks(1);
                //获取栈顶Activity
                ActivityManager.RunningTaskInfo cinfo = runningTasks.get(0);

                ComponentName component = cinfo.topActivity;
                Log.e("崩溃拦截-当前类名方式一", component.getClassName());

                String string2 = runningTasks.get(0).topActivity.getClassName();
                Log.e("崩溃拦截-当前类名方式二", string2);
                //存储当前崩溃类名到本地,可用于统计崩溃次数等
                SP.getInstance().setErrPagename(component.getClassName());

            }
        });

2.在之前的项目中,使用的是Thread.UncaughtExceptionHandler 来捕捉异常信息,这个的实现也很简单

在其他类初始它就行了。这儿我用的kotlin

CrashCollectHandler.Companion.getInstance().init(app.getApplicationContext());
class CrashCollectHandler : Thread.UncaughtExceptionHandler {  //处理非正常的线程中止
    var mContext: Context? = null
    var mDefaultHandler: Thread.UncaughtExceptionHandler? = null

    companion object {
        val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { CrashCollectHandler() }
    }

    fun init(pContext: Context) {
        this.mContext = pContext
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this)
    }

    //当UncaughtException发生时会转入该函数来处理
    override fun uncaughtException(t: Thread?, e: Throwable?) {
        if (!handleException(e)) {
            //如果用户没有处理则让系统默认的异常处理器来处理
            if (t != null && e != null) mDefaultHandler?.uncaughtException(t, e)
        } else {
            try {
                //给Toast留出时间
                Thread.sleep(2000)
//                AppInitData.appError(mContext, e.toString(), null)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            } finally {
//                android.os.Process.killProcess(android.os.Process.myPid()) //杀死进程
                AppUtils.exitApp() //app
            }
        }

    }

    fun handleException(ex: Throwable?): Boolean {
        if (ex == null) {
            return false
        }
        Thread {
            Looper.prepare()
            Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出", Toast.LENGTH_SHORT).show()
            Looper.loop()
        }.start()
        //存储错误信息
        SP.getInstance().err = ex.toString();
        //收集设备参数信息
        //collectDeviceInfo(mContext);
        //保存日志文件
        //saveCrashInfo2File(ex);
        // 注:收集设备信息和保存日志文件的代码就没必要在这里贴出来了
        //文中只是提供思路,并不一定必须收集信息和保存日志
        //因为现在大部分的项目里都集成了第三方的崩溃分析日志,如`Bugly` 或 `啄木鸟等`
        //如果自己定制化处理的话,反而比较麻烦和消耗精力,毕竟开发资源是有限的
        return true
    }
}

扩展

之前用CrashUtils来捕获异常,获取类名时用了RunningTaskInfo,emmmm,还是自己慢慢试出来的,结果今天前辈直接用CrashUtils的方法就解决了,还是对源码的了解程度不够啊。

 public static void initCrash(Context context) {
        CrashUtils.init(crashInfo -> {
            if (App.DEBUG) LogUtils.eTag("崩溃拦截", crashInfo.getThrowable());

            AppCrashErrorMobile mobile = new AppCrashErrorMobile();
            mobile.setDetailMessage(crashInfo.getThrowable().getMessage());
            mobile.setStackTrace(crashInfo.getThrowable().getStackTrace()[0]);

            SP.getInstance().setErr(mobile);

        });

直接用crashInfo.getThrowable().getStackTrace()[0]获取为栈顶的崩溃类。

下面为实体类,其中使用stacktrace的getClassName获取类名,getLineNumber获取行号,getMethodName获取报错方法名。

import java.io.Serializable;

/**
 * app错误实体
 */
public class AppCrashErrorMobile implements Serializable {

//    private String time = DateUtil.getDateTimeSecond(TimeUtils.getNowMills(), DateUtil.DATE_TIME_FORMAT); //错误时间
    private String detailMessage = ""; //错误详情
    private StackTraceElement stackTrace; //堆栈列表

    public String getDetailMessage() {
        return detailMessage;
    }

    public void setDetailMessage(String detailMessage) {
        this.detailMessage = detailMessage;
    }

    public StackTraceElement getStackTrace() {
        return stackTrace;
    }

    public void setStackTrace(StackTraceElement stackTrace) {
        this.stackTrace = stackTrace;
    }

    @Override
    public String toString() {
        String strMsg = /*"\n" + "错误时间:" + time +*/ "\n" + "错误详情:" + detailMessage;

        if (stackTrace != null)
            strMsg = "\n" + "错误目标类:" + stackTrace.getClassName()
                    + "\n" + "错误目标行号:" + stackTrace.getLineNumber()
                    + "\n" + "错误目标方法:" + stackTrace.getMethodName() + strMsg;
        return strMsg;
    }
}

这样简介明了,既然别人封装的方法,肯定考虑的比我们全面,以后还是得多阅读源码,灵活应用~

2021.3.11  CrashUtils在由于异步问题,有时候拦截的日志并不能成功写入,项目改回使用  Thread.UncaughtExceptionHandler 。

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值