相关文章 1.Android 开发中不得不知道的 Tips 集合 (持续更新 ing) 2.Android 开发中不得不知道的 Tips 集合 (第二波))
1.应用又崩溃啦!!!
开发过程中,受种种因素影响(机型适配问题、程序员技术功底等),已发布上线的应用难免回出现Crash,如果我们不做处理,崩溃后系统会弹出对话框(xxx应用已停止).这时候用户手一哆嗦就直接卸载了有木有。so,既然开发人员不能阻止Crash的出现,那就得从崩溃后的提示入手了,将对用户的影响降到最低。
解决方案: 利用Thread的setDefaultUncaughtExceptionHandler方法,将未知的异常进行捕获,然后友好的提示用户,重新启动应用。(伸手党可直接拿走哈) 有图有真相:
1.新建CrashHandler类,这个类负责捕获未处理的异常
/**
* Created by weixinjie on 2017/6/1.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler mDefaultHandler;
public static final String TAG = "CatchExcep";
SampleApplication application;
public CrashHandler(SampleApplication application) {
//获取系统默认的UncaughtException处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
this.application = application;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
}
Intent intent = new Intent(application.getApplicationContext(), MainActivity.class);
PendingIntent restartIntent = PendingIntent.getActivity(
application.getApplicationContext(), 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
//退出程序
AlarmManager mgr = (AlarmManager) application.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000,
restartIntent); // 1秒钟后重启应用
System.exit(0);
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
//使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(application, "应用异常,正在重启", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
return true;
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
//使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
ToastUtil.toastLong(R.string.error_for_restart);
Looper.loop();
}
}.start();
return true;
}
}
复制代码
2.在应用的Application的onCreate方法中调用如下代码:
@Override
public void onCreate() {
initCrashHandler();
}
private void initCrashHandler() {
//设置该CrashHandler为程序的默认处理器
CrashHandler catchExcep = new CrashHandler(this);
Thread.setDefaultUncaughtExceptionHandler(catchExcep);
}
复制代码
3.在清单文件中将自定义的Application注册一下.
2.为什么要用IntentService而不用Thread
面试的时候大家经常会被问IntentService跟Thread有什么区别吧?比如App升级的时候,去服务端下载apk包的时候为什么要开一个IntertService而不是Thread. Answer:我们要从Android系统的5大进程级别来看待这个事情,分别为“前台进程”,“可视进程”,“服务进程”,“后台进程”,“空进程”.当系统的内存不足时,会根据进程的级别来回收这些进程.即回收的顺序为:“空进程”->...->“前台进程”.很明显,如果用户按下home键之后,我们的进程会变成一个后台进程,此时很容易被系统回收掉,那咱们在Thread中所做的操作就白扯了,而如果我们开一个IntentService的话,我们的进程会变成一个Service进程,被回收的几率就大大降低了。 当然,这种问题我们不应该只停留在理论阶段,应付面试是一方面,我们还是要多看系统的文档,这也是我等菜鸟通往高级工程师必不可少的一环。 祭上官方文档:https://developer.android.com/guide/components/processes-and-threads.html?hl=zh-cn (科学上网哈)
3.Gradle脚本中已删除的sdk,发布release包的事后报NoClassDefFoundError错误
缘由:项目在内测阶段用到了BugTags来指Bug (BugTags确实可以大大提高测试的效率,建议大家在内测阶段接入他们的服务进行测试) ,发布release版本的时候,为了减少包体,便将该sdk从gradle脚本中剔除了。然后打出release包之后。一打开就闪退,并且报如下错误
4.用adb进行wifi链接真机调试(不需root呦)。
方案如下: 1.手机与你的电脑要在同一个局域网下 2.配置你电脑上的adb命令。不要告诉我你不会配,请自行百度哈。 3.用usb链接电脑跟手机,在命令窗口输入:[ adb tcpip 5555 ]
5.通往大牛的路上,怎能不看系统源码
前段时间项目赶,没时间继续我的看系统源码计划,还好,现在项目进入正常迭代周期,我又有时间可以折腾源码啦。 推荐给大家一个Chrome插件:https://chrome.google.com/webstore/search/Android%20SDK%20Reference%20Search%20 安装之后,你用Chrome浏览器去Android Developer上查api的时候,会自动加入这么一个东东,你就可以enjoy看系统源码带给你的充实啦。
About Me
contact way | value |
---|---|
weixinjie1993@gmail.com | |
W2006292 | |
github | https://github.com/weixinjie |
blog | https://juejin.im/user/57673c83207703006bb92bf6 |