6 单元测试
1、 每个独立模块都要有单元测试。
2、 程序中:Log.i(TAG, \日志信息\;TAG格式=包名.类名 3、 例如:
AndroidManifest.xml文件
说明:第9行中引进单元测试包 第19行和20行中 android:targetPackage的包为第3行中的包 编写单元测试类 继承AndroidCase 测试方法以开头 7 编译 1、 尽量不要出现警告。 2、 对于每个警告,要弄清原因。 8 一些关乎性能、稳定性和灵活性的原则 8.1 避免内存泄露 7.1.1 原则1:及时回收Bitmap资源 对于在代码中创建出来的Bitmap资源,一定要在适当的时候通过Bitmap.recycle()予以销毁,系统不会对通过Bitmap.createBitmap方式创建出来的Bitmap进行回收。合理的时候比如在Activity::onDestroy()中销毁Bitmap. 7.1.1 原则2:register注册的响应钩子,一定要有unRegister 无论何时register注册的响应钩子,一定要有unRegister的时候,否则该引用不能被系统正确回收。 示例: Public void onCreate() { setCallback(mycallback); RegisterReceiver(myReceiver); } Public void onStop() { setCallback(null); unRegisterFilter(myReceiver); } Regiser注册的内容很多,请务必仔细,如contentObserver, Cursor, CallBack函数都是需要清理的对象。 7.1.1 原则3:使用Adapter时要尽量使用convertView缓存 引用 在使用Adapter的时候,要尽量使用convertView缓存引用,以便节省内存空间。 示例: View Adapter::getView(View converView , int pos) { View v ; if(convertView != null) //如果converView存在,那么使用converView来作为创建出的View引用。 v = convertView; else //如果convertView不存在,则创建新的View引用。 v = makeNewView(); v.setData();//给View引用设置数据 return v; } 7.1.1 原则4:从网络下载的数据和保存的临时文件要及时清 理 7.1.1 原则5:内存使用不能超过上限 系统中,除特殊应用外,其他所有应用都应有内存上限(待定),超过这个上限应用程序就会崩溃,在设计UI和编写代码的时候应该警惕内存使用,尤其是图片加载。 7.1.1 原则6:避免使用Finalizer Finalizer是object在被垃圾回收时执行的一段代码,用finalizer的好处是可以在一段代码里释放不需要的资源,但建议不要用finalizer。因为不能保证什么时候会调用finalize的代码,甚至不能保证是否会调用finalizer的代码。 7.1.1 原则7:使用软应用cache private final HashMap mCache.put(key, new SoftReference public T get(String key, ValueBuilder builder) { T value = null; SoftReference value = reference.get(); } // Not in cache or gc'd if (value == null) { value = builder.build(key); mCache.put(key, new SoftReference return value; } 8.2 避免出现系统超时无响应 (有时也表现为打开/关闭窗 口刷新不正常) 在使用过程中,我们有时候会遇到界面无响应,弹出对话框询问是关闭进程还是继续等待,发生该异常的原因是应用主线程在某处阻塞,导致新的系统消息(如广播Intent, Key事件, Touch事件)不能正常处理,系统端迟迟收不到应用返回的消息已处理事件,从而判定应用无响应,弹出提示对话框。同时,长时间的阻塞主线程可能会导致WindowManagerService不能正确处理窗口切换刷新,引起打开/关闭Activity时出现刷新不正常。 发生异常时常见的Log有: Activitiy Idle timeout … Activity Launch timeout Service execute timeout Key dispatch timeout Broadcast Receiver Intent *** timeout 避免这个问题有以下几个原则。 7.2.1 原则1 需要时间很长的操作,须要单独启动新的线程执行。 例如: 搜索网络,Wifi 网络访问 加载/卸载Sd卡 大量读写数据库 读写较大文件(比如大尺寸的图片) 通常与底层数据读取相关的函数需要重点关注。 启动新线程要使用Thread.start()函数,而不是用Thread.run()函数。使用线程一定要注意synchronized同步以及资源回收。 7.2.1 原则2 对于结构不易另外开新线程的代码, 或者调用Binder与其它能够联系的代码 , 应该尽量避免在系统回调函数中直接运行,要通过sendMessage来异步调用,这样可以保证系统能够及时从应用获得消息处理完毕的事件。 例如: startActivity() 打开Activity startService() 打开Service sendBroadcast() 发Intent广播 showDialog() 显示对话框 耗时长的事件可能较多,需要实际分析,比如获取当前网络,硬件,等底层状态都可能会导致阻塞 需要避免出现代码示例: Public void onCreate() { sendBroadcast(Intent); } 在onCreate回调函数中发送广播以及显示对话框,有可能会造成系统端阻塞 正确示例: Public int _MSG = 0; Public Handler myHandler = new Handler( Public void handleMessage(Message msg) { Switch(msg.what) { Case _MSG: sendBroadCast(myintent); break; } } }; Public void onCreate() { myHandler.sendMessage(myHandler.obtainMessage(_MSG)); } 通过发送Message的方式来异步调用。 请注意: 发送Message只是将要执行的操作放到onCreate()回调函数之外去操作,并不是启动新线程进行,如果需要时间过长,同样可能引发阻塞。 7.2.1 原则3 某些代码调用应该坚持少访问数据库,少读取文件,少访问网络的设计原则 例如: Settings.System.getInt() 操作会读取数据库 ,可以通过使用变量或者System.Properties的方式来替代。 8.3 使用Http连接需要加入超时时间限制 示例: