編輯:關於Android編程

public void init(Context context) {
try {
if (context == null)
throw new NullPointerException("Application 的Context不能為空");
this.mContext = context;
/**
* 獲取系統默認的異常處理類
*/
mUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
/**
* 在獲取系統異常類之前子類可以先做一些初始化的操作
*/
initParams(this);
/**
* 使用當前的類為異常處理類
*/
Thread.setDefaultUncaughtExceptionHandler(this);
}catch (Exception e){
Log.e(TAG, "init - "+e.getMessage());
}
}
/**
* 此類是當應用出現異常的時候執行該方法
* @param thread
* @param throwable
*/
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
try {
/**
* hanlderException此方法是是否處理異常日志,如果處理那麼就返回tru * e,如果處理遇到問題那麼就返回false,交由系統默認處理
**/
if (!hanlderException(throwable) && mUncaughtExceptionHandler != null) {
/**
* 如果此異常不處理則由系統自己處理
*/
this.mUncaughtExceptionHandler.uncaughtException(thread, throwable);
}else{
/**
* 可以延遲一秒鐘在退出
*/
// Thread.sleep(1000);
//如果開發者自己處理一場那麼就自己處理,這裡我處理的是退出進程
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}catch (Exception e) {
Log.e(TAG, "uncaughtException - "+e.getMessage());
}
}
/**
* 用戶處理異常日志
* @param throwable
* @return
*/
private boolean hanlderException(Throwable throwable) {
try {
if (throwable == null)
return false;
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "程序崩潰", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}).start();
/**
* 收集應用信息
*/
collectCrashLogInfo(mContext);
/**
* 將日志寫入文件
*/
writerCrashLogToFile(throwable);
/**
* 限制日子志文件的數量
*/
limitAppLogCount(LIMIT_LOG_COUNT);
} catch (Exception e) {
Log.e(TAG, "hanlderException - " + e.getMessage());
}
return false;
}
/**
* 獲取應用信息
* @param mContext
*/
private void collectCrashLogInfo(Context mContext) {
try {
if (mContext == null)
return ;
PackageManager packageManager = mContext.getPackageManager();
if (packageManager != null) {
PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
if (packageInfo != null) {
String versionName = packageInfo.versionName;
String versionCode = ""+packageInfo.versionCode;
String packName = packageInfo.packageName;
crashAppLog.put("versionName",versionName);
crashAppLog.put("versionCode",versionCode);
crashAppLog.put("packName",packName);
}
}
/**
* 獲取手機型號,系統版本,以及SDK版本
*/
crashAppLog.put("手機型號:", android.os.Build.MODEL);
crashAppLog.put("系統版本", ""+android.os.Build.VERSION.SDK);
crashAppLog.put("Android版本", android.os.Build.VERSION.RELEASE);
Field[] fields = Build.class.getFields();
if (fields != null && fields.length > 0) {
for (Field field:fields) {
if (field != null) {
field.setAccessible(true);
crashAppLog.put(field.getName(), field.get(null).toString());
}
}
}
}catch (Exception e) {
Log.e(TAG, "collectDeviceInfo - "+e.getMessage());
}
}
/**
* 寫入文件中
* @param ex
*/
private void writerCrashLogToFile(Throwable ex) {
try {
StringBuffer buffer = new StringBuffer();
if (crashAppLog != null && crashAppLog.size() >0) {
for (Map.Entry entry:crashAppLog.entrySet()) {
buffer.append(entry.getKey()+":"+entry.getValue()+"\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.flush();
printWriter.close();
String result = writer.toString();
buffer.append("Exception:+\n");
buffer.append(result);
writerToFile(buffer.toString());
}catch (Exception e) {
Log.e(TAG, "writerCrashLogToFile - "+e.getMessage());
}
}
//將文件寫入
private void writerToFile(String s) {
try {
/**
* 創建日志文件名稱
*/
String curtTimer = ""+System.currentTimeMillis();
if (formate == null) {
formate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
}
String timer = formate.format(new Date());
String fileName = "crash-"+timer+"-"+curtTimer+".log";
/**
* 創建文件夾
*/
File folder = new File(CAHCE_CRASH_LOG);
if (!folder.exists())
folder.mkdirs();
/**
* 創建日志文件
*/
File file = new File(folder.getAbsolutePath()+File.separator+fileName);
if (!file.exists())
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(s);
bufferedWriter.flush();
bufferedWriter.close();
sendCrashLogToServer(folder, file);
}catch (Exception e) {
Log.e(TAG, "writerToFile - "+e.getMessage());
}
}
/**
* 最大文件數量
* @param limitLogCount
*/
private void limitAppLogCount(int limitLogCount) {
try {
File file = new File(CAHCE_CRASH_LOG);
if (file != null && file.isDirectory()) {
File[] files = file.listFiles(new CrashLogFliter());
if(files != null && files.length >0) {
Arrays.sort(files, comparator);
if (files.length > LIMIT_LOG_COUNT) {
for (int i = 0 ; i < files.length - LIMIT_LOG_COUNT ;i++) {
files[i].delete();
}
}
}
}
}catch (Exception e) {
Log.e(TAG, "limitAppLogCount - "+e.getMessage());
}
}
//這裡限制文件的數量我使用的文件類型過濾和排序
/**
* 日志文件按日志大小排序
*/
private Comparator comparator = new Comparator() {
@Override
public int compare(File l, File r) {
if (l.lastModified() > r.lastModified())
return 1;
if (l.lastModified() < r.lastModified())
return -1;
return 0;
}
};
/**
* 過濾.log的文件
*/
public class CrashLogFliter implements FileFilter {
@Override
public boolean accept(File file) {
if (file.getName().endsWith(".log"))
return true;
return false;
}
}
/**
* 默認放在內存卡的root路徑
*/
private String CAHCE_CRASH_LOG = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator;
/**
* 抽象方法,
* 在該類初始化的時候使用
*/
public abstract void initParams(CrashAppLog crashAppLog);
/**
* 發送一場日志文件到服務器
* @param folder 文件路徑
* @param file 文件
*/
public abstract void sendCrashLogToServer(File folder, File file);
/**
* 允許最大日志文件的數量
*/
private int LIMIT_LOG_COUNT = 10;
//這兩個變量是可以通過父類調用的,比如可以進行對緩存目錄更改和文件數量更改
public int getLIMIT_LOG_COUNT() {
return LIMIT_LOG_COUNT;
}
public void setLIMIT_LOG_COUNT(int LIMIT_LOG_COUNT) {
this.LIMIT_LOG_COUNT = LIMIT_LOG_COUNT;
}
public String getCAHCE_CRASH_LOG() {
return CAHCE_CRASH_LOG;
}
public void setCAHCE_CRASH_LOG(String CAHCE_CRASH_LOG) {
this.CAHCE_CRASH_LOG = CAHCE_CRASH_LOG;
}
//initParams這個抽象方法拋出父類進行一些操作;
//sendCrashLogToServer(File folder, File file)這個是在異常日志寫入文件之後進行用開發者進行發送給服務器
package com.base.crash;
import android.os.Environment;
import android.util.Log;
import java.io.File;
/**
* Created by 東帥 on 2016/9/6.
*/
public class CrashApphandler extends CrashAppLog {
public static CrashApphandler mCrashApphandler = null;
//實現單例
private CrashApphandler(){};
public static CrashApphandler getInstance() {
if (mCrashApphandler == null)
mCrashApphandler = new CrashApphandler();
return mCrashApphandler;
}
@Override
public void initParams(CrashAppLog crashAppLog) {
if (crashAppLog != null){
//動態的改變緩存目錄和緩存文件數量
crashAppLog.setCAHCE_CRASH_LOG(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"crashLog");
crashAppLog.setLIMIT_LOG_COUNT(5);
}
}
@Override
public void sendCrashLogToServer(File folder, File file) {
//發送服務端
Log.e("*********", "文件夾:"+folder.getAbsolutePath()+" - "+file.getAbsolutePath()+"");
}
}
package com.base.crash;
import android.app.Application;
/**
* Created by 東帥 on 2016/9/6.
*/
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化一下就行了,別忘記了
CrashApphandler.getInstance().init(this);
}
}
// *** 最後加上權限
Android之通知使用權
通知使用權打開方式設置——提示音和通知——通知使用權。詳細界面如圖:存在需要擁有通知使用權應用時:不存在需要擁有通知使用權
Android學習總結之WIN上搭建環境
引言 本系列適合0基礎的人員,因為我就是從0開始的,此系列記錄我步入Android開發的一些經驗分享,望與君共勉!作為Android隊伍中的一個新人的我,如果有什麼不對
Android TV開發總結(五)TV上屏幕適配總結
前言:前面幾篇總結一些TV上的小Sample,開源到GitHub:https://github.com/hejunlin2013/TVSample, 點擊鏈接,可以持續關
Android自定義ProgressDialog
我們在開發Android上應用程序時,有很多時候會遇到“延時”等待的情況,例如數據加載時,尤其是在聯網的時候,請求網絡會有個等待時間