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 。



 


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
9天前
|
存储 Java API
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
52 0
|
8月前
|
开发工具 Android开发
Mac 安卓(Android) 配置adb路径
Mac 安卓(Android) 配置adb路径
213 0
|
3天前
|
数据挖掘 开发工具 Android开发
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
|
8天前
|
存储 缓存 安全
Android系统 应用存储路径与权限
Android系统 应用存储路径与权限
8 0
Android系统 应用存储路径与权限
|
2月前
|
Android开发
Android 开发 读取excel文件 jxl.jar包
Android 开发 读取excel文件 jxl.jar包
8 0
|
2月前
|
Java Android开发
Android Studio的使用导入第三方Jar包
Android Studio的使用导入第三方Jar包
12 1
|
9月前
|
SQL 数据库 Android开发
Android 访问系统相册选中图片,并返回该图片的路径
Android 访问系统相册选中图片,并返回该图片的路径
102 0
|
5月前
|
缓存 安全 Java
安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】-1
安卓现代化开发系列——从生命周期到Lifecycle【扩展包1已更新】
65 0
|
6月前
|
Shell 数据库 开发工具
(超详细)android中SqLite数据库的使用(一文包懂包会)
(超详细)android中SqLite数据库的使用(一文包懂包会)
138 0
|
10月前
|
移动开发 编解码 缓存
Android包体积过大,真的会影响绩效
Apk瘦身,做为一个Android开发者,这是多多少少都会接触到的,同样功能的App,200M和150M,给用户的第一直觉是不一样的,如果不是刚需,体积越大,用户的排斥也就越大,所以啊,铁子们,你以为瘦身,是简简单单的把体积变小,殊不知,直接影响着用户的真实体验,在开发中,是很有必要进行实施的,毕竟影响着网络数据流量和下载的等待时间。
100 0