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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 在做项目时,无论为了功能还是调试,很多时候都需要获取到当前类的类名,包名,路径等等。在这里总结一下,以便总结和以后需要的时候更快的解决问题。

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


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


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日志并进行多维度分析。
相关文章
|
6月前
|
安全 Java Android开发
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
如何解压OTA升级包、编辑升级包内容(例如移除不需要更新的分区)、重新打包、签名以及验证OTA文件的过程。
520 2
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
|
6月前
|
Android开发 开发者
Android、Flutter为不同的CPU架构包打包APK(v7a、v8a、x86)
Android、Flutter为不同的CPU架构包打包APK(v7a、v8a、x86)
456 1
|
8月前
|
存储 Android开发
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
详细解读Android获取已安装应用信息(图标,名称,版本号,包)
129 0
|
9月前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
412 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能
|
9月前
|
Java 开发工具 Android开发
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
77 4
|
9月前
|
JSON Android开发 数据格式
Android 打开系统文件管理器,并返回选中文件的路径
Android 打开系统文件管理器,并返回选中文件的路径
317 0
|
9月前
|
数据挖掘 开发工具 Android开发
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
|
9月前
|
存储 缓存 安全
Android系统 应用存储路径与权限
Android系统 应用存储路径与权限
518 0
Android系统 应用存储路径与权限
|
9月前
|
网络协议 测试技术 网络性能优化
Android系统 以太网吞吐量和丢包测试
Android系统 以太网吞吐量和丢包测试
351 1
|
9月前
|
存储 Java API
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
1095 0

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    Android历史版本与APK文件结构
  • 3
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 1
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    24
  • 2
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    33
  • 3
    Android历史版本与APK文件结构
    121
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    57
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 8
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    73
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    119
  • 10
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29