This Handler class should be static or leaks might occur Android
来源:互联网 发布:域名备案名称 编辑:程序博客网 时间:2024/06/04 19:29
首先解释下这句话This Handler class should be static or leaks might occur,大致意思就是说:Handler类应该定义成静态类,否则可能导致内存泄露。
具体如何解决,在国外有人提出,如下:
Issue: Ensures that Handler classes do not hold on to a reference to an outer class
In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class.
大体翻译如下:
Handler 类应该应该为static类型,否则有可能造成泄露。在程序消息队列中排队的消息保持了对目标Handler类的应用。如果Handler是个内部类,那 么它也会保持它所在的外部类的引用。为了避免泄露这个外部类,应该将Handler声明为static嵌套类,并且使用对外部类的弱应用。
使用范例:
- staticclass MyHandler extends Handler {
- WeakReference<PopupActivity> mActivity;
- MyHandler(PopupActivity activity) {
- mActivity =new WeakReference<PopupActivity>(activity);
- }
- @Override
- publicvoid handleMessage(Message msg) {
- PopupActivity theActivity = mActivity.get();
- switch (msg.what) {
- case 0:
- theActivity.popPlay.setChecked(true);
- break;
- }
- }
- };
- MyHandler ttsHandler =new MyHandler(this);
- private Cursor mCursor;
- privatevoid test() {
- ttsHandler.sendEmptyMessage(0);
- }
原文:http://www.cnblogs.com/savagemorgan/archive/2013/01/23/2872371.html
疑问:是否有其它解决方法?
这个提示就是由于Handler的直接引用会导致相关的Activity、Service等无法被GC。如果这么弱应用的话,会出现空指针,有其它解决方法?
抽时间研究下。
==================================================================================================================================
原始代码:
- publicclass MainActivity extends Activity {
- privatestatic int urlIndex = 0;
- privatefinal static String TAG = MainActivity.class.getSimpleName();
- privatestatic final String[] url = {
- "http://vdn.apps.cntv.cn/api/getLiveUrlCommonRedirectApi.do?channel=pa://cctv_p2p_hdcctv1&type=ipad",
- "http://74.82.62.53:1935/liverepeater/13.stream/playlist.m3u8", "http://rtmp.cntv.lxdns.com/live/cctv3/playlist.m3u8", };
- privatestatic final int MSG_PLAY = 100;
- privatestatic final int MSG_RUN_ADB = 101;
- Handler playHandler =new Handler() {
- @Override
- publicvoid handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_PLAY:
- urlIndex = urlIndex > url.length - 1 ? 0 : urlIndex;
- videoView.setVideoPath(url[urlIndex]);
- ++urlIndex;
- break;
- case MSG_RUN_ADB:
- killMediaServer();
- break;
- }
- }
- };
- @Override
- protectedvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- HHVideoView.create();
- setContentView(R.layout.activity_main);
- videoView = ((HHVideoView) findViewById(R.id.videoView));
- videoView.setOnPreparedListener(mPreparedListener);
- videoView.setOnCompletionListener(mCompletionListener);
- videoView.setOnErrorListener(mOnErrorListener);
- playHandler.sendEmptyMessage(MSG_PLAY);
- }
- private HHVideoView videoView =null;
- private MediaPlayer.OnPreparedListener mPreparedListener =new MediaPlayer.OnPreparedListener() {
- publicvoid onPrepared(MediaPlayer paramMediaPlayer) {
- // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
- videoView.start();
- }
- };
- private MediaPlayer.OnCompletionListener mCompletionListener =new MediaPlayer.OnCompletionListener() {
- publicvoid onCompletion(MediaPlayer paramMediaPlayer) {
- }
- };
- private MediaPlayer.OnErrorListener mOnErrorListener =new MediaPlayer.OnErrorListener() {
- publicboolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) {
- returnfalse;
- }
- };
- @Override
- publicboolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- returntrue;
- }
- publicboolean onKeyDown(int keyCode, KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_0:
- playHandler.sendEmptyMessage(MSG_RUN_ADB);
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- playHandler.sendEmptyMessage(MSG_PLAY);
- break;
- }
- }
- returnsuper.onKeyDown(keyCode, event);
- }
- }
修改后的代码:
- //activity code
- publicclass MainActivity extends Activity {
- privatestatic int urlIndex = 0;
- privatefinal static String TAG = MainActivity.class.getSimpleName();
- privatestatic final String[] url = {
- "http://vdn.apps.cntv.cn/api/getLiveUrlCommonRedirectApi.do?channel=pa://cctv_p2p_hdcctv1&type=ipad",
- "http://74.82.62.53:1935/liverepeater/13.stream/playlist.m3u8", "http://rtmp.cntv.lxdns.com/live/cctv3/playlist.m3u8", };
- PlayHandler playHandler ;
- @Override
- protectedvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- HHVideoView.create();
- setContentView(R.layout.activity_main);
- videoView = ((HHVideoView) findViewById(R.id.videoView));
- videoView.setOnPreparedListener(mPreparedListener);
- videoView.setOnCompletionListener(mCompletionListener);
- videoView.setOnErrorListener(mOnErrorListener);
- playHandler.sendEmptyMessage(PlayHandler.MSG_PLAY);
- }
- private HHVideoView videoView =null;
- private MediaPlayer.OnPreparedListener mPreparedListener =new MediaPlayer.OnPreparedListener() {
- publicvoid onPrepared(MediaPlayer paramMediaPlayer) {
- // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
- videoView.start();
- }
- };
- private MediaPlayer.OnCompletionListener mCompletionListener =new MediaPlayer.OnCompletionListener() {
- publicvoid onCompletion(MediaPlayer paramMediaPlayer) {
- }
- };
- private MediaPlayer.OnErrorListener mOnErrorListener =new MediaPlayer.OnErrorListener() {
- publicboolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) {
- returnfalse;
- }
- };
- @Override
- publicboolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- returntrue;
- }
- publicboolean onKeyDown(int keyCode, KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_0:
- playHandler.sendEmptyMessage(PlayHandler.MSG_RUN_ADB);
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- playHandler.sendEmptyMessage(PlayHandler.MSG_PLAY);
- break;
- }
- }
- returnsuper.onKeyDown(keyCode, event);
- }
- publicvoid setVideoPath() {
- urlIndex = urlIndex > url.length - 1 ? 0 : urlIndex;
- videoView.setVideoPath(url[urlIndex]);
- ++urlIndex;
- }
- }
Handler代码:
- //handler code
- import java.lang.ref.WeakReference;
- import android.os.Handler;
- import android.os.Message;
- /**
- * @author jevan
- * @version (1.0 at 2013-7-3)
- *
- */
- publicclass PlayHandler extends Handler {
- publicstatic final int MSG_PLAY = 100;
- publicstatic final int MSG_RUN_ADB = 101;
- WeakReference<MainActivity> mActivity;
- PlayHandler(MainActivity activity) {
- mActivity =new WeakReference<MainActivity>(activity);
- }
- @Override
- publicvoid handleMessage(Message msg) {
- MainActivity theActivity = mActivity.get();
- if(theActivity ==null)
- return;
- switch (msg.what) {
- case MSG_PLAY:
- theActivity.setVideoPath();
- break;
- case MSG_RUN_ADB:
- break;
- }
- }
- }
个人还是倾向使用独立的Handler(也就是那个外国人的解决方案),上面反映的Activity会被gc掉,导致参数空指针的问题,其实不能算问题。如果Activity被回收掉,那么Handler应该在使用之前对其状态进行判断。
个人推荐这个解决方法,当然代码会多两行。
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur.
- Android 关于Handler警告处理 This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur Android
- This Handler class should be static or leaks might occur Android
- This Handler class should be static or leaks might occur Android
- This Handler class should be static or leaks might occur Android
- Android“This Handler class should be static or leaks might occur”警告的处理方法
- This Handler class should be static or leaks might occur Android
- android之lint警告This Handler class should be static or leaks might occur
- This Handler class should be static or leaks might occur Android
- android上的缓存、缓存算法和缓存框架
- 归并排序
- ScrollView嵌套GridView的导致的冲突解决办法
- uva12118(不用dfs的方法!)
- intent.getSerializableExtra序列化的用法
- This Handler class should be static or leaks might occur Android
- docker环境下搭建wordpress
- sql大全
- mini2440 nandflash裸机驱动
- Swarm创建docker集群:服务发现-配置文件法
- LinkedBlockingQueue的用法
- 【Android动画】之Tween动画 (渐变、缩放、位移、旋转)
- 监听dialog被取消
- Linux crontab 命令