Androidはappシステムで未処理の異常をキャプチャ


転載は出典を明記してください.http://blog.csdn.net/u011546655/article/details/45566741
一:どうして処理しますか.
実は私达はすべて知っていて、开発の过程の中で、自分のappシステムは多くの隠れた异常があるかもしれなくて、自分で捉えていないで、それでは异常な捕捉について、これはかなり重要で、もしシステムが崩壊するならば、少なくともシステムをシステムの中に挂けることができて、どんなシステムが直接退いたことを発见することができなくて、あるいはカードが死んで、このようにして、ユーザーの体験効果をさらに高めることができて、自分でもユーザーがいったいどんな異常が発生しているのかを発見することができて、自分が後でこの問題を処理するのに便利で、自分のシステムを最適化して処理します.
二:どのように解決するか
Android開発では、自身にシステムデフォルトの異常処理インタフェース、UncaughtExceptionHandlerがあります.このインタフェースは、プログラムで発生する異常をうまく処理できるので、開発者が好んで使うことが多く、非常に簡単で使いやすいものです.
三、具体的な実現
(1)UncaughtExceptionHandlerインタフェースを実現するクラス
package com.x1.tools;

import java.lang.Thread.UncaughtExceptionHandler;

import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Looper;
import android.util.Log;

import com.x1.dao.SubmitConfigBugs;
import com.x1.ui.R;

/**
 *         
 * 
 * @author zengtao 2015 5 6 
 *
 *
 */
public class CrashHandlers implements UncaughtExceptionHandler {

	public static final String TGA = "CrashHandlers";

	//      UncaughtException   
	private Thread.UncaughtExceptionHandler mDefaultHandler;

	// CrashHandler  
	private static CrashHandlers instance;
	//    Context  
	private Context mContext;

	private GetPhoneInfo phone;

	/**       CrashHandler   */
	private CrashHandlers() {
	}

	/**   CrashHandler   ,     */
	public synchronized static CrashHandlers getInstance() {
		if (instance == null) {
			instance = new CrashHandlers();
		}
		return instance;
	}

	/**
	 *    
	 * 
	 * @param context
	 */
	public void init(Context context) {
		mContext = context;
		//        UncaughtException   
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		//    CrashHandler         
		Thread.setDefaultUncaughtExceptionHandler(this);
		phone = new GetPhoneInfo(context);
	}

	/**
	 *  UncaughtException            
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(thread, ex) && mDefaultHandler != null) {
			//                        
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				Log.e(TGA, e.toString());
			}
			//     
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(1);
		}
	}

	/**
	 *        ,                     .
	 * 
	 * @param ex
	 * @return true:          ;    false.
	 */
	private boolean handleException(Thread thread, Throwable ex) {
		if (ex == null) {
			return false;
		}
		//   Toast       
		new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				ShowToast.show(mContext, " ,   ,      ,    !",
						R.drawable.error_icon);
				Looper.loop();
			}
		}.start();
		//                 
		subMitThreadAndDeviceInfo(mContext, thread, ex);
		return true;
	}

	//         
	public void subMitThreadAndDeviceInfo(Context ctx, Thread thread,
			Throwable ex) {
		//        
		String Account = null;
		if (Config.getCachedAccount(ctx) != null) {
			Account = Config.getCachedAccount(ctx);
		} else {
			Account = "       ";
		}
		//        
		String PhoneModel = phone.PhoneModel;
		String PhoneVersion = phone.PhoneVersion;
		String PhoneResolution = phone.PhoneResolution;
		String ZcmVersion = phone.ZcmVersion;
		String AvailableRom = phone.AvailableRom;
		//            Activity      
		ActivityManager am = (ActivityManager) ctx
				.getSystemService(Context.ACTIVITY_SERVICE);
		ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
		//                
		final String content = "thread: " + thread + " , name: "
				+ thread.getName() + ", id: " + thread.getId()
				+ ", exception: " + ex + ", " + cn.getClassName();

		//     ,           
		new SubmitConfigBugs(0, ctx, Account, PhoneModel, PhoneVersion,
				PhoneResolution, ZcmVersion, AvailableRom, content,
				new SubmitConfigBugs.SuccessCallback() {
					@Override
					public void onSuccess() {
						Log.e(TGA, content + "
"); } }, new SubmitConfigBugs.FailCallback() { @Override public void onFail() { Log.e(TGA, content + "
"); } }); } }

(2)実体類:携帯電話情報
package com.x1.tools;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.view.Display;
import android.view.WindowManager;

/**
 *                    
 * 
 * @author zengtao 2015 5 6 
 *
 *
 */
public class GetPhoneInfo {
	private Context context;
	public String PhoneModel;
	public String PhoneVersion;
	public String PhoneResolution;
	public String ZcmVersion;
	public String AvailableRom;

	public GetPhoneInfo(Context context) {
		this.context = context;
		PhoneModel = android.os.Build.MODEL;
		PhoneVersion = android.os.Build.VERSION.RELEASE;
		PhoneResolution = getDisplayWAndH();
		ZcmVersion = getAppVersionName(this.context);
		AvailableRom = "ROM      : " + getAvailableInternalMemorySize() + "MB"
				+ ",  SDCard      : " + getAvailableExternalMemorySize() + "MB";
	}

	//        
	private String getAppVersionName(Context context) {
		String versionName = "";
		try {
			PackageManager packageManager = context.getPackageManager();
			PackageInfo packageInfo = packageManager.getPackageInfo(
					"com.x1.ui", 0);
			versionName = packageInfo.versionName;
			if (TextUtils.isEmpty(versionName)) {
				return "";
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return versionName;
	}

	//        
	@SuppressWarnings("deprecation")
	private String getDisplayWAndH() {
		WindowManager wm = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = wm.getDefaultDisplay();
		String string = "     : " + display.getWidth() + "x"
				+ display.getHeight();
		return string;
	}

	/**
	 * 
	 * @return ROM    
	 */
	private String getInternalMemoryPath() {
		return Environment.getDataDirectory().getPath();
	}

	/**
	 * 
	 * @return   sd   
	 */
	private String getExternalMemoryPath() {
		return Environment.getExternalStorageDirectory().getPath();
	}

	/**
	 * 
	 * @param path
	 *                
	 * @return      StatFs  
	 * @throws Exception
	 *                        
	 */
	private StatFs getStatFs(String path) {
		try {
			return new StatFs(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * @param stat
	 *              StatFs  
	 * @return        MB 
	 * 
	 */
	@SuppressWarnings("deprecation")
	private float calculateSizeInMB(StatFs stat) {
		if (stat != null)
			return stat.getAvailableBlocks()
					* (stat.getBlockSize() / (1024f * 1024f));
		return 0.0f;
	}

	/**
	 * 
	 * @return ROM       MB 
	 */
	private float getAvailableInternalMemorySize() {

		String path = getInternalMemoryPath();//       
		StatFs stat = getStatFs(path);
		return calculateSizeInMB(stat);
	}

	/**
	 * 
	 * @return   SDCard      MB 
	 */
	private float getAvailableExternalMemorySize() {

		String path = getExternalMemoryPath();//       
		StatFs stat = getStatFs(path);
		return calculateSizeInMB(stat);

	}
}

四:まとめ
以上のように、プログラムで処理されていない異常を直接キャプチャすることができ、システム自体の開発がクラッシュしたときに、ユーザーがデータをサーバに提出することはありません.これは、プログラムでは、このような処理を行う必要があります.これは自分の考えによって実现することができて、私はこの中で、携帯电话の提出したいくつかの情报と间违った情报をサーバーに送って、完成して、このように自分に知ってもらうことができて、どんな携帯电话の间违いで、目的があって処理して、もっと良いのは自分の系统を维持します.