全局监听Crash

package com.example.crashcatch;

import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

/**
 * 处理系统未捕捉到的异常,防止app崩溃出现的不好体验
 * @author yWX206812
 *
 */
public class CrashHandler implements Thread.UncaughtExceptionHandler{
	CrashApplication crashApplication;
	UncaughtExceptionHandler defaultUncaughtExceptionHandler;
	SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-mm-dd_HH-mm-ss");
	private static CrashHandler crashHandler=new CrashHandler();

	private CrashHandler() {
		super();
		// TODO Auto-generated constructor stub
	}

	public static CrashHandler getInstance(){
		return crashHandler;
	}
	public void init(CrashApplication crashApplication){
		this.crashApplication=crashApplication;
		defaultUncaughtExceptionHandler=Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		// TODO Auto-generated method stub
		if(!catchHandler(ex)){
			defaultUncaughtExceptionHandler.uncaughtException(thread, ex);
		}
	}

	/**
	 * 异常处理
	 * @param ex
	 * @return
	 */
	public boolean catchHandler(Throwable ex){
		boolean result=false;
		try {
			Log.e("------------------异常捕获--------------","写入文档");
			result= saveExceptionInfo(ex);
			Toast.makeText(crashApplication.getCurrentContext(), "程序异常", Toast.LENGTH_SHORT).show();
			crashApplication.getCurrentContext().sendBroadcast(new Intent(CrashActivity.crashAction));
			Log.e("------------------异常捕获--------------","发送广播");
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 获取设备和app的基本信息
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	public Map<String, String> getBaseInfo() throws IllegalArgumentException, IllegalAccessException{
		Map<String, String> map=new HashMap<String, String>();
		long currTime=System.currentTimeMillis();
		String timeStr=simpleDateFormat.format(new Date(currTime));
		map.put("当前时间", timeStr);
		Class bClass=Build.class.getClass();
		Field[] fields=bClass.getFields();
		for (int i = 0; i < fields.length; i++) {
			String key=fields[i].getName();
			String val=fields[i].get(null).toString();
			map.put(key, val);
		}
		return map;
	}

	public boolean saveExceptionInfo(Throwable ex) throws IllegalArgumentException, IllegalAccessException, IOException{
		Map<String, String> map=getBaseInfo();
		map.put("", ex.getMessage());
		Set<String> keys=map.keySet();
		Iterator<String> iterator=keys.iterator();
		StringBuilder sb=new StringBuilder();
		while (iterator.hasNext()) {
			String key=iterator.next();
			String val=map.get(key);
			sb.append(key+":"+val+"\n");
		}
		String packageName=crashApplication.getCurrentContext().getPackageName();
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
			File sdDir=Environment.getExternalStorageDirectory();
			File dir=new File(sdDir,packageName+"/"+"crash_log");
			if(!dir.exists()){
				dir.mkdirs();
			}
			String currLogTime=simpleDateFormat.format(new Date(System.currentTimeMillis()));
			String fileName="crash_"+currLogTime+".log";
			return SDCardUtil.writeFile(dir, fileName,sb.toString());
		}
		return false;
	}

}
package com.example.crashcatch;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

public class CrashActivity extends Activity {
	public static final String crashAction="CrashCatch";
	public CrashReceiver crashReceiver=new CrashReceiver();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		((CrashApplication)getApplication()).setCurrentContext(this);
		Log.e("-----------------crashReceiver-----------------","注册广播");
		IntentFilter intentFilter=new IntentFilter();
		intentFilter.addAction(CrashActivity.crashAction);
		registerReceiver(crashReceiver, intentFilter);
		Log.e("-----------------crashReceiver-----------------","注册完毕");
	}

	class CrashReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			Log.e("-----------------crashReceiver-----------------",intent.getAction());
			if(intent.getAction().equals(crashAction)){
				new AlertDialog.Builder(CrashActivity.this).setMessage("程序出现异常,是否退出").setNegativeButton("确认", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						unregisterReceiver(crashReceiver);
						android.os.Process.killProcess(android.os.Process.myPid());
						System.exit(0);
					}
				}).create().show();
			}
		}
	}

}

  

 

 SD卡检测

package com.example.crashcatch;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import android.util.Log;

public class SDCardUtil {

	/**
	 * 读取文件返回字节数组
	 * @param filePath
	 * @return
	 */
	public static  byte[] readFile(String filePath) {
		return new byte[1];
	}

	/**
	 * 写入文件
	 * @param filePath
	 * @param bytes
	 * @return
	 * @throws IOException
	 */
	public static boolean writeFile(String filePath,String content) throws IOException {
		File f=getFile(filePath);
		if(f!=null){
			f.delete();
		}
		f=new File(filePath);
		try {
			FileWriter fw=new FileWriter(f);
			fw.write(content);
			fw.close();
			Log.e("------------------写入文件--------------","写入完毕");
			return true;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			throw e;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw e;
		}
	}

	/**
	 * 写入文件
	 * @param dir
	 * @param fileName
	 * @param bytes
	 * @return
	 * @throws IOException
	 */
	public static boolean writeFile(File dir,String fileName,String content) throws IOException {
		File f=getFile(dir,fileName);
		if(f!=null){
			f.delete();
		}
		f=new File(dir,fileName);
		return writeFile(f.getAbsolutePath(), content);
	}

	public static File getFile(String filePath) {
		File file = new File(filePath);
		return getFile(file);
	}

	public static File getFile(File file) {
		if (file.exists() && file.isFile()) {
			return file;
		}
		return null;
	}

	public static File getFile(File dir, String fileName) {
		File file = new File(dir, fileName);
		return getFile(file);
	}
}

  

全局监听Crash

时间: 2024-10-08 18:18:10

全局监听Crash的相关文章

全局监听SCREEN_ON和SCREEN_OFF的替代方法--监听屏幕解锁事件

在做一个程序的时候,需要时刻保持某一服务是启动的,因此想到了通过监听屏幕SCREEN_ON和SCREEN_OFF这两个action.奇怪的是,这两个action只能通过代码的形式注册,才能被监听到,使用AndroidManifest.xml 完全监听不到.查了一下,发现这是PowerManager那边在发这个广播的时候,做了限制,限制只能有register到代码中的receiver才能接收. view plain private void registerScreenActionReceiver

以全局监听的方式处理img的error事件

http://www.ovaldi.org/2015/09/11/%E4%BB%A5%E5%85%A8%E5%B1%80%E7%9B%91%E5%90%AC%E7%9A%84%E6%96%B9%E5%BC%8F%E5%A4%84%E7%90%86img%E7%9A%84error%E4%BA%8B%E4%BB%B6/ 在开发一些电商页面时,往往会有大量的商品图片信息,当图片加载失败时,我们希望以一种更加友好的的方式改善用户体验:比如,换成一张友好的提示图片. img标签在加载失败时,会触发err

Windows API 教程(七) hook 钩子监听

Windows API 教程(七) hook 钩子监听 Posted on 2013-08-15 茵蒂克丝 如何创建一个窗口 手动创建窗口的流程 实际代码 安装钩子 (Install hook) 钩子简介 SetWindowsHookEx 函数 设置监听[键盘]消息 设置监听[鼠标]消息 如何创建一个窗口 另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口. 那么,为什么讲到 hook(钩子)的时候要

基于CSS class的事件监听管理机制 (转)

背景: 做了那么多web项目,总会发现到处都是事件绑定,同一个按钮的执行动作,也许会分布在多个js文件中. 而且对于js动态生成的文档片段,里面会经常出现“onclick=...”之类的代码,一到功能升级,或者代码重构的时候, 就会发现,这个难度以及工作量,和重写一遍没什么区别,有时候甚至工作量更大! 基于各种情况的分析.以及以往的经验总结,百度空间则有了一套自己的事件监听管理机制:基于CSS class的事件监听管理机制 方案: 1.js代码中,不出现对某节点的事件监听,如:$('#elm')

C#全局键盘监听(Hook)的使用

一.为什么需要全局键盘监听? 在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下快捷键使用此功能... 这个时候在程序中添加键盘监听肯定不能满足需求了,当用户焦点不在App上时(如最小化,或者用户在处理其它事物等等)键盘监听就失效了 二.怎样才能实现全局键盘监听? 这里需要用到Windows API,源码如下:(可以作为一个工具类[KeyboardHook.cs]收藏起来) u

【转】【C#】全局键盘监听

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Reflection; namespace 梦琪动漫屋 { /// <summary> /// 键盘钩子/// </summary> class KeyboardHook { public ev

v-once指令、v-cloak指令、条件指令家族、原义指令、循环指令、todolist案例、实例成员-符号、实例成员-计算属性、实例成员-属性监听、监听的案例、局部组件、全局组件、组件交互(父传子、子传父)

v-once指令: v-once:单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) <div id="app"> <input type="text" v-model="msg"> <!-- 一旦赋值,只可主动更改 --> <input type="text" v-model="msg" v-once> <p>{{ m

computed 和 watch 组合使用,监听数据全局数据状态

我要实现的就是,当接口返回数据时,我在任何组件中都能感知到到该数据的变化,然后根据业务逻辑进行处理.展示. 实现这个效果的方式很多,比如当接口返回数据后,就emit这数据,在另外组件中on接收渲染即可,但是我不想用这种, 所以就换了另外一种方式:当接口返回数据时,将数据commit到state,需要对其作出反应的组件中,使用computed将 计算属性将混入到 Vue 实例中.同时使用watch对其属性变化进行监听,且进行相关处理. 相关代码如下: 接口返回数据后,commit更新state中的

ORACLE RAC 下非缺省端口监听配置(listener.ora tnsnames.ora)

不论是单实例还是RAC,对于非缺省端口下(1521)的监听器,pmon进程不会将service/instance注册到监听器,即不会实现动态注册.与单实例相同,RAC非缺省端口的监听器也是通过设置参数local_listener来达到目的.除此之外,还可以对实例进行远程注册,以达到负载均衡的目的.这是通过一个参数remote_listener来实现. 有关Oracle 网络配置相关基础以及概念性的问题请参考:      配置ORACLE 客户端连接到数据库   配置非默认端口的动态服务注册