android捕捉異常
1. Android性能優化之ANR異常監測
ANR是Application Not Responding的縮寫,即應用程序無響應。簡單來說,就是應用的界面突然卡住了,無法響應用戶的操作如觸摸事件等。
解決ANR問題,首先要做的是找到問題,線下我們可以通過ADB命令導出ANR文件進行分析,線上我們可以使用FileObserver或ANR-WatchDog保存ANR堆棧信息,然後上傳到伺服器。
2.1導出ANR文件
ANR發生之後我們可以使用以下命令導出ANR文件:
或者
使用方法:
ANR-WatchDog
Git地址: ANR-WatchDog
ANR-WatchDog是一個非侵入式的ANR監控組件。
使用步驟:
ANR發生之後可直接在日誌中查看堆棧信息:
也可以在Application中監聽ANR-WatchDog返回的錯誤日誌。
原理
ANRWatchDog繼承子Thread,所以它最重要的就是run方法。核心內容可以分為以下幾點:
ANR異常我們可分為線上監測和線下監測兩個方向
2. Android開發常見異常與錯誤系列(一)
一、前言
這系列文章是自己在平時開發過程中遇到的問題。之前只是記在雲筆記上面,現在整理一下,發出來共享。
ps:像那些什麼沒有注冊Activity呀,許可權呀等最基本的就不再贅述。
二、ADB連接異常
有時我們發現,即使自己從任務管理器裡面把adb.exe給幹掉了,但還是不行,這時,你就可以嘗試以下操作:
[2014-07-30 17:09:11 - QtActivity] The connection to adb is down, and a severe error has occured.
[2014-07-30 17:09:11 - QtActivity] You must restart adb and Eclipse.
[2014-07-30 17:09:11 - QtActivity] Please ensure that adb is correctly located at 『D:\InstallFile\AndroidDevelop\ADT\sdk\platform-tools\adb.exe』 and can be executed.
adb起動失敗:
1,殺掉其它的adb.exe看,如果不行,
2,看sdk\tools路徑下面有沒有
hprof-conv.exe
如果有,則把它復制到sdk\platform_tools下
3,如果沒有,剛看sdk\platform_tools下有沒有
hprof-conv.exe
如果有,剛復制到tools下。
4,如果兩者都沒有,剛下一個
hprof-conv.exe
三、java.lang.IllegalStateException: Activity has been destroyed
這個異常在切換Fragment中比較容易出現,稍不注意就會出現如下異常:
FATAL EXCEPTION: main12-0909:20:14.689: E/AndroidRuntime(31223): java.lang.IllegalStateException: Activity has been destroyed12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)12-0909:20:14.689: E/AndroidRuntime(31223): at cn.com.topsky.community.tfd.DongTaiFragment.init(DongTaiFragment.java:209)12-0909:20:14.689: E/AndroidRuntime(31223): at cn.com.topsky.community.tfd.DongTaiFragment.onCreateView(DongTaiFragment.java:68)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Handler.handleCallback(Handler.java:605)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Handler.dispatchMessage(Handler.java:92)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Looper.loop(Looper.java:154)12-0909:20:14.689: E/AndroidRuntime(31223): at android.app.ActivityThread.main(ActivityThread.java:4624)12-0909:20:14.689: E/AndroidRuntime(31223): at java.lang.reflect.Method.invokeNative(Native Method)12-0909:20:14.689: E/AndroidRuntime(31223): at java.lang.reflect.Method.invoke(Method.java:511)12-0909:20:14.689: E/AndroidRuntime(31223): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)12-0909:20:14.689: E/AndroidRuntime(31223): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)12-0909:20:14.689: E/AndroidRuntime(31223): at dalvik.system.NativeStart.main(Native Method)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
經查,說這個是當前android-support-v4版本的一個bug,因為在當fragment進行到detached狀態時,它會重置它的內部狀態。
然而,它並沒有重置mChildFragmentManager.這導致在Fragment重新attach時,它(fragment)沒有重新attachm childFragmentManager,從而引發了上面的異常.
解決方案:
在每個調用getChildFragmentManager()的fragment中復寫onDetach()方法:
@OverridepublicvoidonDetach() {super.onDetach();try{Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");childFragmentManager.setAccessible(true);childFragmentManager.set(this,null);}catch(NoSuchFieldException e) {thrownewRuntimeException(e);}catch(IllegalAccessException e) {thrownewRuntimeException(e);}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
四、java.lang.IllegalArgumentException: Illegal character in query at index
這個異常,在我們拼接請求參數時,可能會碰到,原因是裡面的特殊字元轉換異常。解決辦法如下:
url轉換問題
String url = baseUrl + 「?」 + 「name=」 + name + 「&age=」 + age;
url = url.replaceAll(「&」, 「%26」);
url = url.replaceAll(」 「, 「%20」);
解釋如下:
特殊符號替換符號
?%3F
&%26
|%124
=%3D
#%23
/%2F
+%2B
%%25
空格%20
五、eclipse連接小米2S調試程序的問題
雖然快2年沒用過eclipse了,但這個問題還是貼出來,也許正好有正在用eclipse的同學遇到了此問題:
小米Mi2S連接到eclipse上無法識別。即使開啟了調試模式,也無法識別.終於找到了一個可用的方法。
方法
用數據線連接手機和電腦。
打開手機撥號界面。
在撥號界面按 # #717717# # 自動就開啟了。
在通知欄會出現一個 Diag USB port enable。
當然,應該是需要ROOT許可權的。
這時候你的PC機會彈出安裝設備驅動。
如果不成功,多插拔幾次試試。
ok!安裝完就搞定了!這時候打開eclipse就會在Driver裡面看到你的手機了。
注意事項
在PC機上安裝新硬體向導時候可能會遭遇到缺少dll文件,比如我就遇到缺少了WinUSBCoInstaller2.dll,這個問題。這時候就要去網上找找嘍。這個東西分x64 和 x86的,注意不要搞錯了!
如果先打開eclipse,再安裝的話,可能導致eclipse掛掉,不明原因,可能是我機器配置不行。兩次均有這種狀況。所以建議先安裝後再開eclipse。
3. androidstudio中怎麼捕獲異常
//可以使用try catch finally語句來捕獲異常。
//代碼格式:
try{
//如果要捕獲異常,需要將代碼放置在這try的代碼塊范圍內
}catch(IOException ex){//異常范圍IOException 以及它的派生類異常
//此處編寫發生 IOException 或其派生類異常時處理方案
}catch(Exception ex){//異常范圍Exception 以及它的派生類異常
//此處編寫發生Exception 或其派生類異常時處理方案
}finally{
//此處無論上方的代碼中是否出現了異常、return語句,這里必定執行。
}
/*
try catch語句至少需要有一個catch,卻可以同時有多個catch。
其中catch語句塊的異常范圍從上到下順序書寫時應當從小范圍到達范圍,如果將Exception的catch與IOException的catch位置對換,那麼永遠不會執行IOException的catch塊的代碼
finally語句代碼塊是可選的。可以有它,也可以不使用它,具體是否啟用它需要根據業務邏輯決定
*/
4. android 怎麼捕獲app異常閃退的日誌
1、通過集成第三方SDK,如網路統計、友盟統計等
2、發版時使用加固工具,他們也會收集錯誤日誌,如360加固
3、在程序中添加程序異常崩潰的捕捉代碼,保存到本地文件中。
5. android 程序怎樣捕捉全局異常
Android系統的「程序異常退出」,給應用的用戶體驗造成不良影響。為了捕獲應用運行時異常並給出友好提示,便可繼承UncaughtExceptionHandler類來處理。通過Thread.()方法將異常處理類設置到線程上即可。
1、異常處理類,代碼如下:
[java] view plain
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE = new CrashHandler();
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler;
private CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE;
}
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.();
Thread.(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// if (!handleException(ex) && mDefaultHandler != null) {
// mDefaultHandler.uncaughtException(thread, ex);
// } else {
// android.os.Process.killProcess(android.os.Process.myPid());
// System.exit(10);
// }
System.out.println("uncaughtException");
new Thread() {
@Override
public void run() {
Looper.prepare();
new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)
.setMessage("程序崩潰了...").setNeutralButton("我知道了", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
})
.create().show();
Looper.loop();
}
}.start();
}
/**
* 自定義錯誤處理,收集錯誤信息 發送錯誤報告等操作均在此完成. 開發者可以根據自己的情況來自定義異常處理邏輯
*
* @param ex
* @return true:如果處理了該異常信息;否則返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
// new Handler(Looper.getMainLooper()).post(new Runnable() {
// @Override
// public void run() {
// new AlertDialog.Builder(mContext).setTitle("提示")
// .setMessage("程序崩潰了...").setNeutralButton("我知道了", null)
// .create().show();
// }
// });
return true;
}
}
2、線程綁定異常處理類
[java] view plain
public class CrashHandlerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this); //傳入參數必須為Activity,否則AlertDialog將不顯示。
// 創建錯誤
throw new NullPointerException();
}
}
6. android開發中什麼時候要用捕捉異常
一種是必須要寫的,系統會提示你要寫,不寫會報錯的
二種就是你自己的需求,比如內存不夠的時候你希望程序不直接死到影響用戶體驗,就可以在內存吃緊的地方加上異常捕獲,然後對用戶做出友好提示。
7. Android 捕獲全局異常CrashHandler,防止異常閃退,記錄異常日誌
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Looper;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* UncaughtException handler class
*
*/
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
public static final String PROGRAM_BROKEN_ACTION = "com.teligen.wccp.PROGRAM_BROKEN";
private UncaughtExceptionHandler mDefaultHandler;
private static CrashHandler instance = new CrashHandler();
private Context mContext;
private Class<?> mainActivityClass;
private Map<String, String> infos = new HashMap<String, String>();
private CrashHandler() {
}
public static CrashHandler getInstance() {
return instance;
}
public void init(Context context, Class<?> activityClass) {
mContext = context;
this.setMainActivityClass(activityClass);
mDefaultHandler = Thread.();
Thread.(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
} else {
System.out.println("uncaughtException--->" + ex.getMessage());
// Log.e(TAG, ex.getMessage());
logError(ex);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// Log.e("debug", "error:", e);
}
exitApp();
}
}
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext.getApplicationContext(),
"unknown exception and exiting...Please checking logs in sd card!", Toast.LENGTH_LONG).show();
Looper.loop();
}
}).start();
collectDeviceInfo(mContext.getApplicationContext());
logError(ex);
return true;
}
private void exitApp() {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(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) {
e.printStackTrace();
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
} catch (Exception e) {
}
}
}
private void logError(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");
}
int num = ex.getStackTrace().length;
for (int i=0;i<num;i++){
sb.append(ex.getStackTrace()[i].toString());
sb.append("\n");
}
File file = new File(filePath+"/log.txt");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write((sb.toString()+"exception:"+ex.getLocalizedMessage()).getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Class<?> getMainActivityClass() {
return mainActivityClass;
}
public void setMainActivityClass(Class<?> mainActivityClass) {
this.mainActivityClass = mainActivityClass;
}
}
filePath是記錄日誌的路徑
在Applicaton中初始化
@Override
public void onCreate() {
super.onCreate();
CrashHandler mCrashHandler = CrashHandler.getInstance();
mCrashHandler.init(getApplicationContext(), getClass());
initFile();
}
8. android全局捕獲異常使用詳解
2.2: 在自己程序中BaseApplication中的onCreate()方法設置全局異常捕捉類
2.3:直接在MainActivity的initData()初始化數據方法中,獲取上次崩潰信息,然後列印即可
以上就是全局異常捕獲及使用步驟,如若需要,直接拷貝到自己項目中即可使用
地址如下
https://www.jianshu.com/u/c5fabe27176e
9. 一段別人寫的Android 全局捕獲異常
已經上線的App,如果遇到異常就崩潰、閃退,給用戶的體驗就會很不友好。為了不崩潰,於是就會有全局捕獲異常的做法。最近看到如下代碼:
這段代碼寫在Application里。Handler那部分是處理主線程的。Thread.這一部分應該是處理所有線程的吧?難道它沒有包含主線程嗎?如果包含了主線程,那麼上面Handler那一部分豈不是多餘的嗎?
10. Android 捕捉Intent 異常
try
{
Intent
intent
=
new
Intent();
intent.setClass(MainMenu.this,Diamond.class);
startActivity(intent);//啟動一個新的activity
MainMenu.this.finish();
}
catch
(Exception
e)
{
Log.i("異常標簽",e);//不要用e.printStackTrace();Android一般都不提倡使用
}