android 内存泄漏处理方式
16lz
2021-01-26
由于某个对象持有了其他对象的引用导致 ,导致无法 GC。
1:合理的使用context–比如我们常使用的Toast,Service,最好使用getApplicationContext(),因为这些在activity结束的时候可能仍在运行
下图通过图片说明国关于context的使用)
2:不要在activity中使用AsyncTask的强引用,如下是不行的:
class MyActivity extends Activity { private AsyncTask myTask = new AsyncTask() { //内部类隐含了对activity的一个强引用,强引用是无法被gc回收的; }}
我们异步获取手机音频文件 做个小范例:
private static class ScanRingsPhoneMusic extends AsyncTask { private WeakReference activityReference; // only retain a weak reference to the activity ScanRingsPhoneMusic(MusicListActivity context) { activityReference = new WeakReference<>(context); } @Override protected Void doInBackground(Void... voids) { MusicListActivity activity = activityReference.get(); getAllSongs(activity); return null; } } @Override protected void onDestroy() { super.onDestroy(); PublicUtils.getInstance().mediaPlayerRelease(); mHandler.removeCallbacksAndMessages(null); } public static void getAllSongs(MusicListActivity activity) { Cursor cursor = activity.getApplicationContext().getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.YEAR, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.SIZE, MediaStore.Audio.Media.DATA }, MediaStore.Audio.Media.MIME_TYPE + "=? or " + MediaStore.Audio.Media.MIME_TYPE + "=?", new String[] { "audio/mpeg", "audio/x-ms-wma" }, null); if (cursor.moveToFirst()) { BackGroundMusic backGroundMusic = null; while (cursor.moveToNext()) { backGroundMusic = new BackGroundMusic(); // 文件名 backGroundMusic.setFileName(cursor.getString(1)); // 歌曲名 backGroundMusic.setTitle(cursor.getString(2)); // 时长 backGroundMusic.setDuration(cursor.getInt(3)); // 歌手名 backGroundMusic.setSinger(cursor.getString(4)); // 专辑名 backGroundMusic.setAlbum(cursor.getString(5)); // 年代 if (cursor.getString(6) != null) { backGroundMusic.setYear(cursor.getString(6)); } else { backGroundMusic.setYear("未知"); } // 歌曲格式 if ("audio/mpeg".equals(cursor.getString(7).trim())) { backGroundMusic.setType("mp3"); } else if ("audio/x-ms-wma".equals(cursor.getString(7).trim())) { backGroundMusic.setType("wma"); } // 文件大小 if (cursor.getString(8) != null) { float size = cursor.getInt(8) / 1024f / 1024f; backGroundMusic.setSize((size + "").substring(0, 4) + "M"); } else { backGroundMusic.setSize("未知"); } // 文件路径 if (cursor.getString(9) != null) { backGroundMusic.setFilePath(cursor.getString(9)); } Message message = activity.mHandler.obtainMessage(); message.what = 1; message.obj=backGroundMusic; activity.mHandler.sendMessage(message); Log.i(TAG, backGroundMusic.toString()); } cursor.close(); } return ; }
最后 附加一个 防止handler 内存泄漏的code
/** * weakReference 防止内存泄漏 */ private static class MyHandler extends Handler { private WeakReference weakReference; MyHandler(MusicListActivity activity) { weakReference = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.e(TAG, "handleMessage: "); MusicListActivity activity = weakReference.get(); switch (msg.what) { case 1: if (activity != null) { BackGroundMusic backGroundMusic= (BackGroundMusic) msg.obj; activity.mBackGroundMusicList.add( backGroundMusic); if(activity.mBackGroundMusicList.size()>0){ activity.musicAdapter.notifyDataSetChanged(); } } break; case 2: activity.musicAdapter.notifyDataSetChanged(); break; } } }
关于Android的内存泄漏 小伙伴 学会了吗?
更多相关文章
- Android(安卓)eclipse 异常总结
- 关于android应用--内存的优化
- Google发布Android(安卓)4.4 KitKat和Nexus 5
- 引用JNI版本----MediaMetadataRetriever获取视频缩略图(真机4.0测
- Android初级教程_内存分析工具MemoryAnalizer
- Android跨进程通信IPC之2——Linux的跨进程通信详解
- [Android]高性能MMKV数据交互分析-MMKV初始化
- Android(安卓)内存管理机制
- Android(安卓)App 性能优化之稳定性