相信大家看到close、recycle、unregister、null,大概已经猜到要说什么了,没错,这一篇都是大家熟知的部分。不过,既然是说内存溢出与优化,这些东西确实又是不可忽略的,懂得的朋友可以跳过,新手朋友请多注意!这些多是系统给出的对象占用,需要主动释放,如果不释放,这些对象将一直占用内存,造成内存泄露!下面的例子,就直接上代码了,相信大家都懂。
*****个人经验狭隘,难免有所疏漏,若有问题,恳请斧正!*****
1.数据库的操作,使用完后要close()
下面是一个数据库查询的代码例子:
/** * 查询号码是否存在 * * @param number 手机号码 * @return */ public boolean find(String number) { SQLiteDatabase database = mHelper.getWritableDatabase(); Cursor cursor = database.query("blackNumber", new String[]{"number", "mode"}, "number=?", new String[]{number}, null, null, null); boolean exist = false; if (cursor.moveToFirst()) { exist = true; } cursor.close();//cursor用完后要关闭,释放资源 database.close();//database用完后要关闭,释放资源 return exist; }
2.I/O流及其相关的操作,使用完后要close()
下面是一个缓存文件读取的代码例子:
上面的关闭操作,使用了一个工具IOUtils,主要是简化try catch代码,方便阅读,该工具类如下:/** * 读取缓存 */ private String getCache(int index) { File cacheDir = UIUtils.getContext().getCacheDir();//本应用的缓存文件夹 File cacheFile = new File(cacheDir, getKey() + "?index=" + index + getParams());//生成缓存文件 if (cacheFile.exists()) { //判断缓存是否存在 //判断缓存是否超过有效期 BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(cacheFile)); long deadline = Long.parseLong(reader.readLine());//读取第一行 if (System.currentTimeMillis() < deadline) { //缓存有效 StringBuffer sb = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { //line不包含有效期,因为前面已经读取过第一行了 sb.append(line); } return sb.toString(); } } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.close(reader);//关闭reader } } return null; }
/** * IO流关闭工具类 */ public class IOUtils { /** * 关闭流 */ public static boolean close(Closeable io) { if (io != null) { try { io.close(); } catch (IOException e) { LogUtils.e(e); } } return true; } }
3.TypeArray使用完后要recycle()
制作自定义控件时,我们会用到TypeArray,用完请记得recycle(),例子如下:
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.RoundProgressWithProgress); int Radius = (int) ta.getDimension(R.styleable.RoundProgressWithProgress_radius, mRadius);//获取自定义属性 ta.recycle();//用完后,释放资源
4.Bitmap在确定不再被使用后,最好recycle()
Bitmap在开发中是经常用到的,图片占用资源相当大,大量的占用就容易造成内存问题。每当我们确定一
张图片不再被使用后,可以主动将其释放recycle(),而不是等待垃圾回收机来释放。具体操作如下:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); //中间做一些相关操作 bitmap.recycle();//确定Bitmap不再使用了,recycle()
5.Receiver、Service的注销与null
加油!!!在开发中,我们可能会启动一个服务去监听广播,例如监听锁屏广播,这时可以这样做,代码如下:
/** * 锁屏监听 * * @author ALion */ public class MyService extends Service{ private InnerScreenOffReceiver mReceiver; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); //注册广播,监听屏幕关闭 mReceiver = new InnerScreenOffReceiver(); IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(mReceiver, filter); } @Override public void onDestroy() { super.onDestroy(); //注销广播 unregisterReceiver(mReceiver); mReceiver = null; } class InnerScreenOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //监听到锁屏后,要做的操作 } } }
在代码中,可以看到在Service的onDestroy()方法中需要unregisterReceiver(mReceiver),并且
mReceiver = null。同时如果Service不需要的时候,也要记得stop。