• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            This Handler class should be static or leaks might occur Android

            轉載自:http://www.cnblogs.com/jevan/p/3168828.html

            首先解釋下這句話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嵌套類,并且使用對外部類的弱應用。

            使用范例:

               

            1. static class MyHandler extends Handler {
            2.                 WeakReference<PopupActivity> mActivity;
            3.    
            4.                 MyHandler(PopupActivity activity) {
            5.                         mActivity = new WeakReference<PopupActivity>(activity);
            6.                 }
            7.    
            8.                 @Override
            9.                 public void handleMessage(Message msg) {
            10.                         PopupActivity theActivity = mActivity.get();
            11.                         switch (msg.what) {
            12.                         case 0:
            13.                                 theActivity.popPlay.setChecked(true);
            14.                                 break;
            15.                         }
            16.                 }
            17.         };
            18.    
            19.         MyHandler ttsHandler = new MyHandler(this);
            20.         private Cursor mCursor;
            21.    
            22.         private void test() {
            23.                 ttsHandler.sendEmptyMessage(0);
            24.         }

            原文:http://www.cnblogs.com/savagemorgan/archive/2013/01/23/2872371.html

            疑問:是否有其它解決方法?

            這個提示就是由于Handler的直接引用會導致相關的Activity、Service等無法被GC。如果這么弱應用的話,會出現空指針,有其它解決方法?

            抽時間研究下。

               

             ==================================================================================================================================

             原始代碼:

            1. public class MainActivity extends Activity {
            2.  
            3.    private static int urlIndex = 0;
            4.    private final static String TAG = MainActivity.class.getSimpleName();
            5.    private static final String[] url = {
            6.          "http://vdn.apps.cntv.cn/api/getLiveUrlCommonRedirectApi.do?channel=pa://cctv_p2p_hdcctv1&type=ipad",
            7.          "http://74.82.62.53:1935/liverepeater/13.stream/playlist.m3u8", "http://rtmp.cntv.lxdns.com/live/cctv3/playlist.m3u8", };
            8.  
            9.    private static final int MSG_PLAY = 100;
            10.    private static final int MSG_RUN_ADB = 101;
            11.    Handler playHandler = new Handler() {
            12.       @Override
            13.       public void handleMessage(Message msg) {
            14.          switch (msg.what) {
            15.          case MSG_PLAY:
            16.             urlIndex = urlIndex > url.length - 1 ? 0 : urlIndex;
            17.             videoView.setVideoPath(url[urlIndex]);
            18.             ++urlIndex;
            19.             break;
            20.          case MSG_RUN_ADB:
            21.             killMediaServer();
            22.             break;
            23.          }
            24.       }
            25.    };
            26.  
            27.  
            28.  
            29.    @Override
            30.    protected void onCreate(Bundle savedInstanceState) {
            31.       super.onCreate(savedInstanceState);
            32.       requestWindowFeature(Window.FEATURE_NO_TITLE);
            33.       HHVideoView.create();
            34.  
            35.       setContentView(R.layout.activity_main);
            36.       videoView = ((HHVideoView) findViewById(R.id.videoView));
            37.       videoView.setOnPreparedListener(mPreparedListener);
            38.       videoView.setOnCompletionListener(mCompletionListener);
            39.       videoView.setOnErrorListener(mOnErrorListener);
            40.  
            41.       playHandler.sendEmptyMessage(MSG_PLAY);
            42.  
            43.    }
            44.  
            45.    private HHVideoView videoView = null;
            46.    private MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
            47.       public void onPrepared(MediaPlayer paramMediaPlayer) {
            48.          // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
            49.          videoView.start();
            50.       }
            51.    };
            52.  
            53.    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
            54.       public void onCompletion(MediaPlayer paramMediaPlayer) {
            55.  
            56.       }
            57.    };
            58.    private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
            59.       public boolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) {
            60.  
            61.          return false;
            62.       }
            63.    };
            64.  
            65.    @Override
            66.    public boolean onCreateOptionsMenu(Menu menu) {
            67.       // Inflate the menu; this adds items to the action bar if it is present.
            68.       return true;
            69.    }
            70.  
            71.    public boolean onKeyDown(int keyCode, KeyEvent event) {
            72.       if (event.getAction() == KeyEvent.ACTION_DOWN) {
            73.          switch (keyCode) {
            74.  
            75.          case KeyEvent.KEYCODE_0:
            76.  
            77.             playHandler.sendEmptyMessage(MSG_RUN_ADB);
            78.             break;
            79.  
            80.          case KeyEvent.KEYCODE_DPAD_DOWN:
            81.          case KeyEvent.KEYCODE_DPAD_UP:
            82.  
            83.             playHandler.sendEmptyMessage(MSG_PLAY);
            84.             break;
            85.          }
            86.       }
            87.       return super.onKeyDown(keyCode, event);
            88.  
            89.    }
            90.  
            91. }

            修改后的代碼:

            1. //activity code
            2. public class MainActivity extends Activity {
            3.  
            4.    private static int urlIndex = 0;
            5.    private final static String TAG = MainActivity.class.getSimpleName();
            6.    private static final String[] url = {
            7.          "http://vdn.apps.cntv.cn/api/getLiveUrlCommonRedirectApi.do?channel=pa://cctv_p2p_hdcctv1&type=ipad",
            8.          "http://74.82.62.53:1935/liverepeater/13.stream/playlist.m3u8", "http://rtmp.cntv.lxdns.com/live/cctv3/playlist.m3u8", };
            9.  
            10.    PlayHandler playHandler ;
            11.  
            12.  
            13.  
            14.    @Override
            15.    protected void onCreate(Bundle savedInstanceState) {
            16.       super.onCreate(savedInstanceState);
            17.       requestWindowFeature(Window.FEATURE_NO_TITLE);
            18.       HHVideoView.create();
            19.  
            20.       setContentView(R.layout.activity_main);
            21.       videoView = ((HHVideoView) findViewById(R.id.videoView));
            22.       videoView.setOnPreparedListener(mPreparedListener);
            23.       videoView.setOnCompletionListener(mCompletionListener);
            24.       videoView.setOnErrorListener(mOnErrorListener);
            25.  
            26.       playHandler.sendEmptyMessage(PlayHandler.MSG_PLAY);
            27.  
            28.    }
            29.  
            30.    private HHVideoView videoView = null;
            31.    private MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
            32.       public void onPrepared(MediaPlayer paramMediaPlayer) {
            33.          // playerHandler.sendEmptyMessage(uiAction.MEDIAPLAYER_ONPREPAREED);
            34.          videoView.start();
            35.       }
            36.    };
            37.  
            38.    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
            39.       public void onCompletion(MediaPlayer paramMediaPlayer) {
            40.  
            41.       }
            42.    };
            43.    private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
            44.       public boolean onError(MediaPlayer paramMediaPlayer, int paramInt1, int paramInt2) {
            45.  
            46.          return false;
            47.       }
            48.    };
            49.  
            50.    @Override
            51.    public boolean onCreateOptionsMenu(Menu menu) {
            52.       // Inflate the menu; this adds items to the action bar if it is present.
            53.       return true;
            54.    }
            55.  
            56.    public boolean onKeyDown(int keyCode, KeyEvent event) {
            57.       if (event.getAction() == KeyEvent.ACTION_DOWN) {
            58.          switch (keyCode) {
            59.  
            60.          case KeyEvent.KEYCODE_0:
            61.  
            62.             playHandler.sendEmptyMessage(PlayHandler.MSG_RUN_ADB);
            63.             break;
            64.  
            65.          case KeyEvent.KEYCODE_DPAD_DOWN:
            66.          case KeyEvent.KEYCODE_DPAD_UP:
            67.  
            68.             playHandler.sendEmptyMessage(PlayHandler.MSG_PLAY);
            69.             break;
            70.          }
            71.       }
            72.       return super.onKeyDown(keyCode, event);
            73.  
            74.    }
            75.    public void setVideoPath() {
            76.       urlIndex = urlIndex > url.length - 1 ? 0 : urlIndex;
            77.       videoView.setVideoPath(url[urlIndex]);
            78.       ++urlIndex;
            79.    }
            80. }

            Handler代碼:

            1. //handler code
            2. import java.lang.ref.WeakReference;
            3.  
            4. import android.os.Handler;
            5. import android.os.Message;
            6.  
            7. /**
            8.  * @author jevan
            9.  * @version (1.0 at 2013-7-3)
            10.  *
            11.  */
            12. public class PlayHandler extends Handler {
            13.    public static final int MSG_PLAY = 100;
            14.    public static final int MSG_RUN_ADB = 101;
            15.    WeakReference<MainActivity> mActivity;
            16.  
            17.    PlayHandler(MainActivity activity) {
            18.       mActivity = new WeakReference<MainActivity>(activity);
            19.    }
            20.  
            21.    @Override
            22.    public void handleMessage(Message msg) {
            23.       MainActivity theActivity = mActivity.get();
            24.       if(theActivity == null)
            25.          return;
            26.       switch (msg.what) {
            27.       case MSG_PLAY:
            28.          theActivity.setVideoPath();
            29.          break;
            30.       case MSG_RUN_ADB:
            31.  
            32.          break;
            33.       }
            34.    }
            35. }

             

            個人還是傾向使用獨立的Handler(也就是那個外國人的解決方案),上面反映的Activity會被gc掉,導致參數空指針的問題,其實不能算問題。如果Activity被回收掉,那么Handler應該在使用之前對其狀態進行判斷。

            個人推薦這個解決方法,當然代碼會多兩行。

            posted on 2013-11-14 02:48 楊粼波 閱讀(3475) 評論(2)  編輯 收藏 引用

            評論

            # re: This Handler class should be static or leaks might occur Android 2014-01-27 18:23 核桃

            路過,加油  回復  更多評論   

            # re: This Handler class should be static or leaks might occur Android 2014-05-13 17:37 zhoujunhua

            if(theActivity == null)return;的檢測是不是有點多余?
            handler的實例在activity對象上,如果activity都被回收掉了,自然也不會存在消息發送到handleMessage上了,不知道我的邏輯正確不,不過加上這句判斷總是讓人感覺程序要可靠點。  回復  更多評論   

            # re: This Handler class should be static or leaks might occur Android[未登錄] 2014-05-15 13:40 楊粼波

            @zhoujunhua 檢測還是嚴謹一點好。  回復  更多評論   

            国内精品久久久久久99蜜桃 | 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 一本色道久久HEZYO无码| 国内精品久久久久影院薰衣草| 少妇熟女久久综合网色欲| 亚洲欧美日韩久久精品第一区| 久久99精品国产一区二区三区| 久久无码一区二区三区少妇| 日本五月天婷久久网站| 秋霞久久国产精品电影院| 青青草国产97免久久费观看| 精品蜜臀久久久久99网站| 久久久久久国产精品免费免费| 久久综合综合久久综合| 久久精品国产99国产精品| 久久天天躁狠狠躁夜夜躁2O2O | 久久亚洲精品无码AV红樱桃| 久久99免费视频| 亚洲AV日韩精品久久久久久| 麻豆久久| 久久国产综合精品五月天| 精品免费久久久久久久| 欧美精品乱码99久久蜜桃| 精品欧美一区二区三区久久久| 久久精品中文闷骚内射| 国产A三级久久精品| 一本一本久久a久久精品综合麻豆| 色噜噜狠狠先锋影音久久| 久久99精品久久久久久久不卡 | 国产女人aaa级久久久级| 久久天天躁狠狠躁夜夜躁2O2O| 久久久久亚洲AV无码观看| 亚洲国产精品综合久久网络| 久久精品国产72国产精福利| 伊人久久免费视频| 丰满少妇人妻久久久久久4| 久久精品国产影库免费看 | 波多野结衣中文字幕久久| 浪潮AV色综合久久天堂| 国产精品久久久久久吹潮| 精品熟女少妇av免费久久|