Android 常见工具类封装

如何写一个公共的失败重试方法 有时候请求失败了可能需要重试,如何写一个公共重试机制的方法,只需考虑两点: 1.重试次数 重试次数比较简单,作为方法参数,调用方传来即可,然后安重试次数开启循环,int即可。 2.业务逻辑 业务逻辑处理对于重试方法而言并不关心,但是需要能够得到一个处理结果,并能根据处理结果告知是否执行成功,以便可以退出循环,Callable即可。 public interface CallResult { boolean success(); } public static <CR extends Call 阅读详情

1,MD5工具类:

复制代码

public class MD5Util {
    public final static String MD5(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    public static void main(String[] args) {
        System.out.print(MD5Util.MD5("password"));
    }
}

复制代码

 

2,线程睡眠

复制代码

public class CSleep {
    public static final long DEFAULT_SLEEP_TIME = 500;

    private boolean          isRuning           = false;

    public boolean isRuning() {
        return isRuning;
    }

    public void runWithTime(final long defaultSleepTime) {
        isRuning = true;
        new Thread() {

            @Override
            public void run() {
                try {
                    sleep(defaultSleepTime, 0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                isRuning = false;
                super.run();
            }
        }.start();
    }
}

复制代码

 

3,检查网络是否连通

复制代码

 /**
     * 检查网络是否连通
     * 
     * @return boolean
     * @since V1.0
     */
    public boolean isNetworkAvailable(Context context) {
        // 创建并初始化连接对象
        ConnectivityManager connMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        // 判断初始化是否成功并作出相应处理
        if (connMan != null) {
            // 调用getActiveNetworkInfo方法创建对象,如果不为空则表明网络连通,否则没连通
            NetworkInfo info = connMan.getActiveNetworkInfo();
            if (info != null) {
                return info.isAvailable();
            }
        }
        return false;
    }

复制代码

 

4,异常类捕捉

复制代码

/**
 * UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告. 需要在Application中注册,为了要在程序启动器就监控整个程序。
 */
public class CrashHandler implements UncaughtExceptionHandler {
    /** TAG */
    public static final String              TAG       = "CrashHandler";
    /** 系统默认的UncaughtException处理类 */
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    /** CrashHandler实例 */
    private static CrashHandler             mCrashHandler;
    /** 程序的Context对象 */
    private Context                         mContext;
    /** 用来存储设备信息和异常信息 */
    private Map<String, String>             infos     = new HashMap<String, String>();
    /** 用于格式化日期,作为日志文件名的一部分 */
    private DateFormat                      formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /**
     * 私有构造函数
     */
    private CrashHandler() {

    }

    /**
     * 获取CrashHandler实例 ,单例模式
     * 
     * @return
     * @since V1.0
     */
    public static CrashHandler getInstance() {
        if (mCrashHandler == null)
            mCrashHandler = new CrashHandler();
        return mCrashHandler;
    }

    /**
     * 初始化
     * 
     * @param context
     * @since V1.0
     */
    public void init(Context context) {
        mContext = context;
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!handleException(ex) && mDefaultHandler != null) {
            // 如果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                CLog.e(TAG, "uncaughtException() InterruptedException:" + e);
            }
            // 退出程序
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    /**
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     * 
     * @param ex
     * @return true:如果处理了该异常信息;否则返回false.
     * @since V1.0
     */
    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }

        // 收集设备参数信息
        collectDeviceInfo(mContext);

        // 使用Toast来显示异常信息
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show();
                Looper.loop();
            }
        }.start();

        // 保存日志文件
        saveCatchInfo2File(ex);
        return true;
    }

    /**
     * 收集设备参数信息
     * 
     * @param ctx
     * @since V1.0
     */
    public void collectDeviceInfo(Context ctx) {
        try {
            PackageManager pm = ctx.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null" : pi.versionName;
                String versionCode = pi.versionCode + "";
                infos.put("versionName", versionName);
                infos.put("versionCode", versionCode);
            }
        } catch (NameNotFoundException e) {
            CLog.e(TAG, "collectDeviceInfo() an error occured when collect package info NameNotFoundException:", e);
        }
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                infos.put(field.getName(), field.get(null).toString());
                CLog.d(TAG, field.getName() + " : " + field.get(null));
            } catch (Exception e) {
                CLog.e(TAG, "collectDeviceInfo() an error occured when collect crash info Exception:", e);
            }
        }
    }

    /**
     * 保存错误信息到文件中
     * 
     * @param ex
     * @return 返回文件名称,便于将文件传送到服务器
     */
    private String saveCatchInfo2File(Throwable ex) {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infos.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "\n");
        }

        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        try {
            long timestamp = System.currentTimeMillis();
            String time = formatter.format(new Date());
            String fileName = "crash-" + time + "-" + timestamp + ".log";
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                String path = FilePathUtil.getiVMSDirPath() + "/crash/";
                File dir = new File(path);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(path + fileName);
                fos.write(sb.toString().getBytes());
                // 发送给开发人员
                sendCrashLog2PM(path + fileName);
                fos.close();
            }
            return fileName;
        } catch (Exception e) {
            CLog.e(TAG, "saveCatchInfo2File() an error occured while writing file... Exception:", e);
        }
        return null;
    }

    /**
     * 将捕获的导致崩溃的错误信息发送给开发人员 目前只将log日志保存在sdcard 和输出到LogCat中,并未发送给后台。
     * 
     * @param fileName
     * @since V1.0
     */
    private void sendCrashLog2PM(String fileName) {
        if (!new File(fileName).exists()) {
            CLog.e(TAG, "sendCrashLog2PM() 日志文件不存在");
            return;
        }
        FileInputStream fis = null;
        BufferedReader reader = null;
        String s = null;
        try {
            fis = new FileInputStream(fileName);
            reader = new BufferedReader(new InputStreamReader(fis, "GBK"));
            while (true) {
                s = reader.readLine();
                if (s == null)
                    break;
                // 由于目前尚未确定以何种方式发送,所以先打出log日志。
                CLog.e(TAG, s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 关闭流
            try {
                reader.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

复制代码

 

5,弹出框提醒

 public static Dialog showDialog(Context ctx, int layViewID, int ThemeType) {
        Dialog res = new Dialog(ctx, ThemeType);
        res.setContentView(layViewID);
        return res;
    }

 

 

6,图片API类

复制代码

public class ImageAPI {

    public static Bitmap getImageByFilePath(String filePath, int scale) {
        Bitmap res = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        options.inJustDecodeBounds = false;
        options.inSampleSize = scale;
        options.inPreferredConfig = Bitmap.Config.ARGB_4444;
        return res;
    }

    public static Bitmap getImageByFilePath(String filePath, int Towidth, int ToHeight) {
        Bitmap res = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        if (!new File(filePath).exists())
            return res;
        BitmapFactory.decodeFile(filePath, options);

        int origionalWidth = options.outHeight;
        int origionalHeight = options.outWidth;
        options.inJustDecodeBounds = false;
        int scale = Math.max(origionalWidth / Towidth, origionalHeight / ToHeight);
        options.inSampleSize = scale;
        options.inPreferredConfig = Bitmap.Config.ARGB_4444;
        try {
            res = BitmapFactory.decodeFile(filePath, options);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            return null;
        }
        return res;
    }

}

复制代码

 

 

10,提醒封装类

复制代码

public static void showToast(Context ctx, int id, String str) {
        if (str == null) {
            return;
        }

        Toast toast = Toast.makeText(ctx, ctx.getString(id) + str, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }

    public static void showToast(Context ctx, String errInfo) {
        if (errInfo == null) {
            return;
        }

        Toast toast = Toast.makeText(ctx, errInfo, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
AI五大核心方向就业导航:ML/NLP/CV/语音/AI工程化实战指南 人工智能不是单一技术,而是围绕数据、文本、图像、语音和系统交付五大问题域展开的工程实践体系。机器学习聚焦结构化数据决策,自然语言处理应对语义模糊性,计算机视觉直面物理世界不确定性,语音技术跨越声学与语言鸿沟,AI工程化则解决模型落地的稳定性与可维护性。这五大方向构成当前92%以上初级至中级AI岗位的能力基座,也是非科班转行者最可行的切入路径——无需精通全部,但需理解各自的问题本质、技术边界与协作逻辑。本文结合真实招聘JD、转型案例与最小可行项目设计,帮助零基础学习者建立‘问题反射’能力,快速匹配自身优势与岗 阅读详情

相关推荐

Dify插件离线部署全攻略:从下载到安装的完整流程

本文详细介绍了Dify插件离线部署的完整流程,针对企业内网等无网络环境需求。核心步骤包括在联网环境下载插件包、在特定Python 3.12.9环境下使用专用工具进行离线重打包,以及最终在离线Dify环境中安装验证。重点解决了离线安装的核心难题,并提供了环境配置、批量处理和故障排查等实用技巧,帮助用户实现Dify插件的顺利离线部署。

seed的博客 656

android中MD5加密工具类

android中MD5加密工具类

IT晓可程序员之路 3848

Java开发者必看:5分钟搞定PaddleOCR表格识别,导出Excel和HTML超详细教程

本文为Java开发者提供了集成PaddleOCR实现智能表格识别的详细教程,包括环境配置、核心代码实现、结果导出到Excel和HTML的步骤,以及性能优化技巧。通过PaddleOCR技术,开发者可以快速将图片表格转换为结构化数据,大幅提升工作效率。

weixin_30872499的博客 98

安全相关工具类

1.MD5工具类 package com.example.xzy.utilsdemo; import java.security.MessageDigest; /** * MD5工具类 */ public class MD5Util { public final static String MD5(String s) { char hexDigits[] = {

记录移动开发相关的知识 712

PAT|中国大学MOOC-浙江大学翁恺-C语言程序设计习题集(更新中)

##2-0. 整数四则运算 时间限制:400 ms 内存限制:65536 kB 代码长度限制:8000 B 判题程序:Standard 作者:乔林(清华大学) 本题要求编写程序,计算2个正整数的和、差、积、商并输出。题目保证输入和输出全部在整型范围内。 输入格式: 输入在一行中给出2个正整数A和B。 输出格式: 在4行中按照格式“A 运算符 B = 结果”顺序输出和、差、积、商。 输入样例: 3 ...

小鱼波波波 6万+

广义平均(Generalized Mean, GeM)

本位介绍了广义平均操作的定义和简要推导,帮助大家理解其含义。

qq_45802280的博客 4547

md5工具类

import java.security.MessageDigest; public class MD5Util { public static String toMD5(String plainText) { try { // 生成实现指定摘要算法的 MessageDigest 对象。 MessageDigest md = MessageDigest.getInstance("

从事移动开发八年,csdn博客专家,阿里云特邀专家,华为云云享专家,高级网络信息安全工程师,大数据工程师(高级),python技术开发(高级),HarmonyOS 应用开发者高级认证,现在某学校任教。 2万+

DEM高程数据的获取、合并与坐标转换

DEM高程数据的获取、合并与坐标转换一、DEM数据的获取二、数据合并三、投影转换方法一四、投影转换方法二 今天用DEM数据做了一个坡度分析,数据使用过程中涉及到投影坐标转换,由于不是很熟悉所以费了一番功夫。经过一番折腾总结出两个方法,方法一自认为比较便捷的方法,即通过BIGMAP软件中工具列表中的投影转换功能进行。方法二为传统方法,即在Arcgis中用投影栅格工具进行转换。 一、DEM数据的获取 在地理空间数据云网站下载DEM数据(精度包括30米和90米),数据格式为tif格式或img格式,坐标为WGS_1

weixin_48625651的博客 1万+

【Android Kotlin协程】利用CoroutineContext实现网络请求失败后重试逻辑

在Android开发中有一个典型场景:网络请求失败后重试:一般的逻辑是弹出一个Dialog提醒用户“网络请求失败”,并提供重试的按钮。如果当前页面只有一个网络请求,那么逻辑就很简单了:只需要再调用一下发起这个网络请求的方法就可以了。而当一个页面有多个网络请求时,我常用的办法为失败回调加状态,根据不同的状态调用不同的方法。但是这个方法不免有些繁琐,也有点不安全。首先,你要额外的增加状态,并将它传来传去。有些情况下,你甚至还需要重新初始化网络请求参数。更要命的是:你还要管理这个状态,一旦管理不善,就会导致调用了

xiaokangss的博客 915

别再纠结了!实测罗技Flow、对拷线、微软Mouse without Borders,我的最终选择是...

本文通过实测对比罗技Flow、对拷线和微软Mouse without Borders等多设备控制方案,详细分析了各自的优缺点及适用场景。作者最终选择了对拷线与罗技键鼠的组合方案,为专业用户提供了稳定可靠的多设备协同办公解决方案,特别适合需要频繁传输大文件和跨设备操作的用户。

weixin_33696106的博客 405

10X Visium空间转录组学入门:从芯片结构到数据分析全流程解析(附避坑指南)

本文全面解析10X Visium空间转录组学技术,从芯片物理结构、探针化学原理到湿实验全流程操作与避坑指南,并详细介绍了从FASTQ数据到空间可视化的核心分析流程。文章旨在帮助科研人员跨越从理论到实操的鸿沟,掌握从样本准备、文库构建到使用Space Ranger和Seurat进行数据分析与可视化的完整路径,为组织生物学研究提供清晰的实践指引。

weixin_29306011的博客 163

android常用类封装,Android 常见工具类封装

1,MD5工具类:public class MD5Util {public final static String MD5(String s) {char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };try {byte[] btInput = s.ge...

weixin_31034309的博客 349

QML 果冻抖动:用 Scale 动画模拟 Q 弹反馈

介绍果冻抖动效果:点击后卡片通过多段 ParallelAnimation 实现 Scale X/Y 反向缩放和逐步衰减,模拟果冻弹性形变;进阶版本加入小幅 Rotation 增加活泼感,适合游戏、儿童应用等趣味反馈场景。

u011186532的专栏 424

Android常见工具类封装

MD5加密 import android.annotation.SuppressLint; import java.security.MessageDigest; public class MD5 { @SuppressLint("DefaultLocale") public static String hex(byte[] array) { S

一个有趣、有料、有内涵的地方! 2022

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android 加解密算法工具类封装:AES、RSA、MD5 一站式解决方案

在 Android 开发中,数据的安全性非常重要,尤其是敏感数据的存储和传输。为了实现数据加密和解密,我们可以封装一个通用的加解密工具类,支持常见的加密算法(如 AES、RSA、DES 等)。MD5 是一种广泛使用的哈希算法,通常用于生成数据的唯一摘要(哈希值)。以下是 MD5 工具类的封装,并附带使用示例。使用 decrypt() 方法,传入加密后的 Base64 编码字符串和私钥,返回解密后的原始数据。使用 encrypt() 方法,传入原始数据和公钥,返回加密后的 Base64 编码字符串。

tangweiguo03051987的博客 968

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

android sharedpreferences 工具类,android sharedpreferences工具类

释放双眼,带上耳机,听听看~!今天,简单讲讲如何写一个sharedpreferences的工具类。很简单,把一些重复的操作封装在工具类里,其他地方调用就可以。在网上搜索了比较多的资料,找到一个比较好的工具类。import android.content.Context;import android.content.SharedPreferences;/*** 作者:Yzp on 2017-03-2...

weixin_42099530的博客 383

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android 主流工具类的封装和使用

Android主流工具类的封装和使用(一) 具体使用和案例可以查看https://github.com/zhiyongshuangquan/utils 一:Intent 工具类封装和使用import android.app.Activity; import android.content.Context; import android.content.Intent; import androi

qq_35115643的博客 724
上一篇: 热修复技术
下一篇: [Android]今日头条的屏幕适配方案,简单又粗暴!
ZyClient
博客等级 码龄10年 29粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值