• <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>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            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

            轉(zhuǎn)載自:http://www.cnblogs.com/jevan/p/3168828.html

            首先解釋下這句話This Handler class should be static or leaks might occur,大致意思就是說(shuō):Handler類應(yīng)該定義成靜態(tài)類,否則可能導(dǎo)致內(nèi)存泄露。

            具體如何解決,在國(guó)外有人提出,如下:

            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 類應(yīng)該應(yīng)該為static類型,否則有可能造成泄露。在程序消息隊(duì)列中排隊(duì)的消息保持了對(duì)目標(biāo)Handler類的應(yīng)用。如果Handler是個(gè)內(nèi)部類,那 么它也會(huì)保持它所在的外部類的引用。為了避免泄露這個(gè)外部類,應(yīng)該將Handler聲明為static嵌套類,并且使用對(duì)外部類的弱應(yīng)用。

            使用范例:

               

            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

            疑問(wèn):是否有其它解決方法?

            這個(gè)提示就是由于Handler的直接引用會(huì)導(dǎo)致相關(guān)的Activity、Service等無(wú)法被GC。如果這么弱應(yīng)用的話,會(huì)出現(xiàn)空指針,有其它解決方法?

            抽時(shí)間研究下。

               

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

             原始代碼:

            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. }

             

            個(gè)人還是傾向使用獨(dú)立的Handler(也就是那個(gè)外國(guó)人的解決方案),上面反映的Activity會(huì)被gc掉,導(dǎo)致參數(shù)空指針的問(wèn)題,其實(shí)不能算問(wèn)題。如果Activity被回收掉,那么Handler應(yīng)該在使用之前對(duì)其狀態(tài)進(jìn)行判斷。

            個(gè)人推薦這個(gè)解決方法,當(dāng)然代碼會(huì)多兩行。

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

            評(píng)論

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

            路過(guò),加油  回復(fù)  更多評(píng)論   

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

            if(theActivity == null)return;的檢測(cè)是不是有點(diǎn)多余?
            handler的實(shí)例在activity對(duì)象上,如果activity都被回收掉了,自然也不會(huì)存在消息發(fā)送到handleMessage上了,不知道我的邏輯正確不,不過(guò)加上這句判斷總是讓人感覺(jué)程序要可靠點(diǎn)。  回復(fù)  更多評(píng)論   

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

            @zhoujunhua 檢測(cè)還是嚴(yán)謹(jǐn)一點(diǎn)好。  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            2021国产成人精品久久| 91精品国产综合久久香蕉| 欧美粉嫩小泬久久久久久久 | 欧美一区二区三区久久综合| 国产L精品国产亚洲区久久| 国产成年无码久久久免费| 久久96国产精品久久久| 久久久久亚洲AV片无码下载蜜桃 | 久久国产三级无码一区二区| 久久久亚洲欧洲日产国码二区| 久久亚洲天堂| 久久伊人精品一区二区三区| 久久久国产精品| 三级三级久久三级久久| 欧美精品久久久久久久自慰| 久久精品一区二区国产| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久免费视频一区| 99久久精品免费看国产一区二区三区| 久久婷婷成人综合色综合| 91亚洲国产成人久久精品网址| 久久久久噜噜噜亚洲熟女综合| 一本久道久久综合狠狠爱| 久久免费视频观看| 色综合久久夜色精品国产| 国产亚洲色婷婷久久99精品91| 丁香五月综合久久激情| 日韩电影久久久被窝网| 久久精品国产国产精品四凭| 亚洲人成无码www久久久| 青青草原精品99久久精品66| 99久久无码一区人妻| 伊人久久精品无码二区麻豆| 国产成人精品久久一区二区三区av| 九九精品久久久久久噜噜| 狠狠色丁香婷婷久久综合不卡 | 精品国产青草久久久久福利| 国产999精品久久久久久| 奇米综合四色77777久久| 久久综合色之久久综合| 久久99国产精品一区二区|