Android开发中的异常统一处理
来源:互联网 发布:中国烟草待遇 知乎 编辑:程序博客网 时间:2024/05/16 12:03
Android开发中的异常统一处理
实际开发中为了防止程序异常奔溃,而使得开发人员不知道奔溃原因,且影响用户体验:所以我们应该在app中统一处理异常,拦截异常信息,上报服务器。
一自定义异常拦截实现Thread.UncaughtExceptionHandler重写拦截异常方法
public class CrashHandler implements Thread.UncaughtExceptionHandler{ public static final String TAG = "CrashHandler"; //系统默认的UncaughtException处理类 private Thread.UncaughtExceptionHandler mDefaultHandler; //CrashHandler实例 private static volatile CrashHandler instance; //程序的Context对象 private Context mContext; //创建警告对话框 private Dialog dialog; //异常文件存储路径 private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/myExceptionCatch/log/"; //异常文件存储名字 private static final String FILE_NAME = "catch"; //异常文件存储后缀 private static final String FLIE_NAME_SUFFIX = ".log"; /** * 无参构造 */ public CrashHandler() { } /** * 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { if (instance == null) synchronized (CrashHandler.class) { if (instance == null) { instance = new CrashHandler(); } } return instance; } /** * 初始化 */ public void init(Context context) { mContext = context.getApplicationContext(); //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); } /** * 程序崩溃会被该方法捕获到 在此添加逻辑是自己处理还是交给系统异常处理 * handleException是自己处理异常的方法 */ @Override public void uncaughtException(Thread thread, Throwable throwable) { if (!handleException(throwable) && mDefaultHandler != null) { //如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, throwable); } else { Log.d("flag","----------------获取到异常了else");// try {// Thread.sleep(3000);// } catch (InterruptedException e) {// Log.e(TAG, "error : ", e);// }// //退出程序// android.os.Process.killProcess(android.os.Process.myPid());// System.exit(1); } } /** * 添加自己处理异常的方法 在这里收集收集的设备信息 保存异常文件 */ private boolean handleException(final Throwable ex) { if (ex == null || mContext == null) { return false; } new Thread(new Runnable() { @Override public void run() { Looper.prepare(); try { //先获取手机的基本信息 将异常信息一起写入文件 上传服务器 savcExceptionToSDCard(ex); } catch (IOException e) { e.printStackTrace(); } Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show(); try { Thread.sleep(3000); } catch (InterruptedException e) { Log.e(TAG, "error : ", e); } //退出程序 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); Looper.loop(); } }).start(); return true; } /** * 出现异常写到内存卡上 然后读文件上传到服务器 */ private void savcExceptionToSDCard(final Throwable ex) throws IOException { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Log.w("TAG", "sdcard unmounted,skip save exception"); } File dir = new File(PATH); if (!dir.exists()) { dir.mkdirs(); } long current = System.currentTimeMillis(); final String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current)); File file = new File(PATH + FILE_NAME + FLIE_NAME_SUFFIX); try { //写入时间 PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file))); pw.println(time); //写入手机信息 savePhoneInfo(pw, ex); } catch (Exception e) { } //上传服务器 uploadToServer(file); } /** * 写入手机基本信息 异常机型 异常原因等 */ private void savePhoneInfo(PrintWriter pw, Throwable ex) throws PackageManager.NameNotFoundException { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); pw.print("App version: "); pw.print(pi.versionName); pw.print('_'); pw.println(pi.versionCode); //Android版本号 pw.print("OS Version: "); pw.print(Build.VERSION.RELEASE); pw.print(" _ sdk: "); pw.println(Build.VERSION.SDK_INT); //手机制造商 pw.print("Vendor: "); pw.println(Build.MANUFACTURER); //手机型号 pw.print("Model: "); pw.println(Build.MODEL); //CPU架构 pw.print("CPU ABI : "); pw.println(Build.CPU_ABI); pw.println(); //异常信息 ex.printStackTrace(pw); pw.close(); } /** * 读取文件转换成字符串 * 参数一 输入文件file * * @return */ public String readFromFile(File file) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(file)); StringBuilder stringBuilder = new StringBuilder(); String content; while ((content = bufferedReader.readLine()) != null) { stringBuilder.append(content); } return stringBuilder.toString(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } finally { try { if (bufferedReader != null) { bufferedReader.close(); } } catch (IOException e) { e.printStackTrace(); } } } private void uploadToServer(File file) { String ec=readFromFile(file); OkhttpUtils.upEcInfo(ec,"服务器的url"); }}
二为了实现app全局监听 在App的application里进行注册
public class MyApplication extends Application { private static MyApplication instance; @Override public void onCreate() { super.onCreate(); //获取CrashHandler实例并初始化CrashHandler CrashHandler.getInstance().init(getApplicationContext()); } public static MyApplication getInstance() { if (instance == null) { instance = new MyApplication(); } return instance; }}
三清单文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.wbxu.myexceptiondemo"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application></manifest>
四上传工具本文使用okhttp
public class OkhttpUtils { //上传字符串 private static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); public static OkHttpClient mOkHttpClient; // public static String SessionKey; // 1静态代码块初始化OkHttpClient static { // 2创建OkHttpClient构建器 OkHttpClient.Builder builder = new OkHttpClient.Builder(); // 3设置网络的链接超时时间 builder.connectTimeout(50, TimeUnit.SECONDS); // 4使用构建器 构建出OkHttpClient mOkHttpClient = builder.build(); } //获取OkHttpClient的方法 public static OkHttpClient getOkHttpClient(){ return mOkHttpClient; } public static void upEcInfo(String ecInfo,String url){ RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, ecInfo); //4创建请求对象 Request request = new Request.Builder() .url(url) .post(requestBody) .build(); //5执行请求 enqueue异步请求 mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("Flag","------上传异常失败错误信息为:e.getLocalizedMessage() = " + e.getLocalizedMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { String strInfo = response.body().string(); Log.d("flag", "----------------门店检查图片信息上传返回的请求体为" + strInfo); } }); }}
五mainActivity里创建异常进行测试
public class MainActivity extends AppCompatActivity { private TextView ecTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ecTextView= (TextView) findViewById(R.id.tv); } /** * 制造异常 */ public void buildEc(View view) { new Thread(new Runnable() { @Override public void run() { ecTextView.setText("异常捕获"); } }).start(); }}
源码下载:http://download.csdn.net/detail/xuwb123xuwb/9872496
阅读全文
0 0
- Android开发中的异常统一处理
- Android异常统一处理
- SpringMVC中的统一异常处理
- Android全局异常统一处理
- 统一的处理异常
- 统一异常处理
- strut2 统一异常处理
- Spring统一异常处理
- 异常的统一处理
- sprimgmvc统一处理异常
- springmvc统一异常处理
- Spring > 统一异常处理
- MVC统一异常处理
- SpringMVC异常统一处理
- SpringMVC统一异常处理
- springMVC统一异常处理
- Jersey 统一异常处理
- springmvc 统一处理异常
- 微信开发之自定义菜单
- Django-part2
- Spring MVC 初识
- jQuery Validator remote 远程Ajax校验器
- JavaScript里的小妖精———this!!
- Android开发中的异常统一处理
- 【Jquery学习】第二部分
- 如何实现PLC与THINGWORX工业物联网平台对接
- 欢迎使用CSDN-markdown编辑器
- 【Linux】Shell
- 【handlerbars】模板引擎备忘录
- MATLAB绪言
- 第一章 绪言
- tomcat_ssl环境配置实现单向和双向认证