| 目录 [+] |
以前从来不用Eclipse的Debug,后来才想起来使用,断点可以动态增减,调试不熟悉的代码还是很有用的。
1 adb
1.1 logcat
> adb logcat查看log,这是最简单用法,更详细的参数可以看adb的帮助文档。
> adb logcat -v thread
这个比较常用。
logcat是全局的log,包括系统的所有log。程序最好不要把敏感信息输出到logcat,因为其他程序可以访问logcat,可能会拿logcat作为日志传到他们服务器。
只在调试模式下才输出log到logcat,用完以后就clear。
> adb logcat -c
清除logcat。
1.2 应用程序自带的log
可以用下面的命令获得自己程序记录的log。> adb shell
adbshell> run-as com.mypackage
adbshell> cd /data/data/com.mypackage
adbshell> cat path/to/myapp.log > /sdcard/myapp.log
> adb pull /sdcard/myapp.log target/path/to/myapp.log
1.3 安装删除应用
> adb install <path-to-apk>> adb shell pm install [options] <PATH>
> adb shell pm uninstall [options] <PACKAGE>
1.4 参考资料
* > adb --help* Reading and Writing Logs - developer.android.com
* Android Debug Bridge (adb) - developer.android.com
* Re: Why do I get access denied to data folder when using adb? - Author: Idolon - stackoverflow.com
2 debug
2.1 开启Eclipse Debug
In the AndroidManifest.xml file, add android:debuggable="true" to the <application> element.--ref: http://developer.android.com/tools/device.html
不添加的话,会提示无法调试。
2.2 Dump the stack trace
To obtain a stack dump from emulator, you can log in with adb shell, use ps to find the process you want, and then kill -3. The stack trace appears in the log file.2.3 参考资料
* Debugging - developer.android.com* Tools Help - developer.android.com
3 AndroidManifest.xml
The AndroidManifest.xml File - developer.android.com3.1 minSdkVersion
<uses-sdk android:minSdkVersion="integer"android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />
minSdkVersion一般都使用7(Android 2.1)。
3.2 参考资料
* <uses-sdk> - developer.android.com* Re: How to change target build on Android project? - Author: Alan Will & todofixthis - stackoverflow.com
4 错误处理
在任何编程当中,这都非常重要。在有异常的系统当中,一般就叫异常处理了。我改进了异常自动提交,大部分异常都会自动提交到服务器,服务器马上会把提交的信息提取出来,然后发送给相关的开发者,开发者第一时间就能看到,不需要通过market账户。这需要以下几个方面的配合,服务器端就不说了。
4.1 DefaultUncaughtExceptionHandler
默认实现就是程序退出之前的那个对话框。这个可以自己实现一个,然后通过Thread.setDefaultUncaughtExceptionHandler - developer.android.com设置。
例子可以参考Re: How do I obtain crash-data from my Android application? - Author: rrainn - stackoverflow.com。
sendToServer方法不能直接访问网络,因为这是在主线程,否则,有些版本是会直接报错的。可以开一个线程池,在线程池里提交错误,在主线程调用future.get()阻塞主线程即可。
我在UncaughtExceptionHandler里直接kill掉当前进程,因为这在我的设计里是不应该发生的错误。
4.2 AsyncTask
耗时的操作应该放到后台线程执行,如果还需要更新UI,那可以使用AsyncTask - developer.android.com。AsyncTask的实现机制是ThreadPoolExecutor + FutureTask + 更新UI的方法,跟SwingWorker没有本质区别,Android使用android.os.Handler更新UI。在线版源码可以看Android 2.1 # AsyncTask.java - grepcode.com。
就算不需要后台运行任务的结果,那也要调用get方法,否则的话,抛出的异常被缓存,无法拿到,这是从ThreadPoolExecutor传播过来的行为。
AsyncTask有个不好的设计,doInBackground方法不能抛出异常,否则就直接由DefaultUncaughtExceptionHandler接管了。我是不能接受在每个doInBackground方法里捕获异常,所以我另外写了一个,行为特征跟SwingWorker.doInBackground方法类似,允许抛出Exception,还有done方法,默认捕获所有异常,让另外一个线程池把异常提交到服务器,这个行为无法Override,有另外一个方法用来扩展done方法。
AsyncTask有一个比SwingWorker好的地方,executeOnExecutor方法,使得executor可以自定义。
5 UI
5.1 UI线程模型
Android的UI框架也是单线程模型。需要在主线程更新UI以及UI需要用到的数据,因为这些数据不是线程安全的,设计上就是只允许主线程来更新这些数据。UI需要用到的数据不仅包括纯model类的对象,还包括其他对象的一些域。5.1.1 深入阅读
* Processes and Threads - developer.android.com* Multithreaded toolkits: A failed dream? - Author: Graham Hamilton - blogs.java.net
* 《Java并发编程实践》,章节:GUI应用程序
5.2 applicationContext
applicationContext很有用,因为很多时候都要用到Context,Activity也是Context,容易消亡,所以我用的是applicationContext。详细介绍在Context.getApplicationContext - developer.android.com。=文章版本=
201201 记录了一些链接20130513 整理成文
No comments:
Post a Comment