This Handler class should be static or leaks might occur Android
首先解释下这句话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嵌套类,并且使用对外部类的弱应用。
使用范例:
- static
class MyHandler extends Handler { - WeakReference<PopupActivity> mActivity;
- MyHandler(PopupActivity activity) {
- mActivity = new WeakReference<PopupActivity>(activity);
- }
- @Override
- public
void 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;
- private
void test() { - ttsHandler.sendEmptyMessage(0);
- }
原文:http://www.cnblogs.com/savagemorgan/archive/2013/01/23/2872371.html
疑问:是否有其它解决方法?
这个提示就是由于Handler的直接引用会导致相关的Activity、Service等无法被GC。如果这么弱应用的话,会出现空指针,有其它解决方法?
抽时间研究下。
==================================================================================================================================
原始代码:
- public
class MainActivity extends Activity { - private
static
int urlIndex = 0; - private
final
static String TAG = MainActivity.class.getSimpleName(); - private
static
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", };
- private
static
final
int MSG_PLAY = 100; - private
static
final
int MSG_RUN_ADB = 101; - Handler playHandler = new Handler() {
- @Override
- public
void 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
- protected
void 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() {
- public
void onPrepared(MediaPlayer paramMediaPlayer) { - // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
- videoView.start();
- }
- };
- private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
- public
void onCompletion(MediaPlayer paramMediaPlayer) { - }
- };
- private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
- public
boolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) { - return
false; - }
- };
- @Override
- public
boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present.
- return
true; - }
- public
boolean 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;
- }
- }
- return
super.onKeyDown(keyCode, event); - }
- }
修改后的代码:
- //activity code
- public
class MainActivity extends Activity { - private
static
int urlIndex = 0; - private
final
static String TAG = MainActivity.class.getSimpleName(); - private
static
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
- protected
void 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() {
- public
void onPrepared(MediaPlayer paramMediaPlayer) { - // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
- videoView.start();
- }
- };
- private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
- public
void onCompletion(MediaPlayer paramMediaPlayer) { - }
- };
- private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
- public
boolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) { - return
false; - }
- };
- @Override
- public
boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present.
- return
true; - }
- public
boolean 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;
- }
- }
- return
super.onKeyDown(keyCode, event); - }
- public
void 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)
- *
- */
- public
class PlayHandler extends Handler { - public
static
final
int MSG_PLAY = 100; - public
static
final
int MSG_RUN_ADB = 101; - WeakReference<MainActivity> mActivity;
- PlayHandler(MainActivity activity) {
- mActivity = new WeakReference<MainActivity>(activity);
- }
- @Override
- public
void 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 Android的更多相关文章
- Android“This Handler class should be static or leaks might occur”警告的处理方法
此文属于转载! 最近用到handle在线程中改变UI,会跟给出“This Handler class should be static or leaks might occur”的警告,网上看了很多解 ...
- Android - This Handler class should be static or leaks might occur.
今天学习了使用 HTTP协议,从Android客户端往Tomcat服务器端以GET发送请求,途中无意中发现自己写的Handler类被Android提示:This Handler class shoul ...
- This Handler class should be static or leaks might occur(null) 解决办法 (转)
原文链接:http://blog.csdn.net/wuleihenbang/article/details/17126371 首先解释下这句话This Handler class should be ...
- android之lint警告This Handler class should be static or leaks might occur
更新到adt2.0的开发者们可能会在handler上发现这么一条警告:This Handler class should be static or leaks might occur . 首先在ADT ...
- This Handler class should be static or leaks might occur,Handler和Context使用的注意事项!
Android中.在使用到Handler的时候,假设按例如以下代码编写: private Handler handler; @Override public void onCreate(Bundle ...
- Handler classes should be static or leaks might occur
http://droidyue.com/blog/2014/12/28/in-android-handler-classes-should-be-static-or-leaks-might-occur ...
- 85、android handler的警告Handler Class Should be Static or Leaks Occur
转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...
- 【Android】[转] Android Handler应设为static
android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur.意为handler应用s ...
- Handler Should be static or leaks Occur?
解决办法: public class SampleActivity extends Activity { /** * Instances of static inner classes do not ...
随机推荐
- JavaScript 毒瘤和糟粕(需要注意的地方)
简介 我想这是在我总结JavaScript系列中最为需要注意的,最为重要的内容.你必须要去了解这些问题特性,才能准备好应对措施,这真的很重要. 毒瘤 全局变量 全局变量的存在的确是带来了方便,但是我觉 ...
- .Net Core迁移到MSBuild的多平台编译问题
一.前言 本篇主要讨论.NET Core应用程序项目结构的主题,重点探索.NET Core应用程序的多平台编译问题,这里指的多平台是指.NET Framework..NET Core App..NET ...
- 【Java基础】 static
static static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念.被 ...
- 利用jink调试程序,时间不准的解决办法
前几天,做工程,遇到了利用jlink的SWD的模式调试程序,定时器延时不准的问题,上网搜了好多,终于找到了问题所在,感谢万能的网友.时间不对是因为Keil的设置问题. 以下是转自网友: 一.先说说仿真 ...
- 整型转字符串(convert int to char)优化实践
0. 前言 其实基本都没什么机会做这么一个基础的优化,一般基础库里就有函数可以直接拿来用. 这里以snprintf为基准,给大家展示一下每一个优化带来的些许收益. 1. 优化过程 1.最初使用的是sn ...
- 规范 : angular ui router path & params
在seo文章中提到url的path 必须是 why-us,而不是whyUS 所以定了规范,所有的path 必须why-us path ?后尾的是用来filter的,所以可以WhyUs 如果是不需要给s ...
- VUE2.0实现购物车和地址选配功能学习第一节(来源--慕课网河畔一角)
第一节 vue知识 vue-resource:和后台交互的一个插件,实现get.post和jsonp等功能.(替代jQuery) vue特点: 1.易用:通过创建vue实例,{{}}绑定数据十分方便 ...
- 关于Dapper.NET的相关论述
年少时,为何不为自己的梦想去拼搏一次呢?纵使头破血流,也不悔有那年少轻狂.感慨很多,最近事情也很多,博客也很少更新了,毕竟每个人都需要为自己的生活去努力. 最近在一个群里遇到一个人说的话,在这里不再赘 ...
- Java并发之线程异常捕获
由于线程的本质特性,使得你不能捕获从线程中逃逸的异常,如: import java.util.concurrent.ExecutorService; import java.util.concurre ...
- React+webpack开发环境的搭建
首先创建项目,确保该项目已经安装了webpack和webpack-dev-server具体安装方法请参考上章所述. 在上一章说过babel是一个javascript编辑器,在react项目中使用bab ...