国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

正確使用Handler

2019-11-09 14:23:40
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

下面是一個(gè)沒(méi)問(wèn)題的Handler

public class DActivity extends AppCompatActivity {//    @Inject//    D d;        Handler mHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message message) {            return false;        }    });    @Override    PRotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_d);//        Diiii component = DaggerDiiii.builder().ddasfadfa(new Ddasfadfa()).build();//        component.injectD(this);            }}1,當(dāng)代碼改成下面的時(shí)候就會(huì)出現(xiàn)問(wèn)題

public class DActivity extends AppCompatActivity {//    @Inject//    D d;        Handler mHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message message) {            return false;        }    });    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_d);//        Diiii component = DaggerDiiii.builder().ddasfadfa(new Ddasfadfa()).build();//        component.injectD(this);                mHandler.postDelayed(new Runnable() {            @Override            public void run() {                            }        },500*1000);    }}問(wèn)題的原因在于:

當(dāng)進(jìn)入到這個(gè)界面后,反復(fù)的旋轉(zhuǎn)屏幕,導(dǎo)致這個(gè)頁(yè)面不斷的重新繪制,同時(shí),如果持有很多的資源的話就會(huì)造成OOM;

分析原因:

一開(kāi)始進(jìn)入這個(gè)界面,初始化Handler,開(kāi)啟延時(shí)任務(wù),這時(shí),屏幕旋轉(zhuǎn),該activity需要被銷毀,卻發(fā)現(xiàn),自己有個(gè)孩子還在做延遲任務(wù),那么母親是肯定不能拋棄孩子的,所以,這個(gè)activity就銷毀不了了,當(dāng)不斷的旋轉(zhuǎn)屏幕時(shí),就會(huì)有很多個(gè)activity無(wú)法銷毀,如果持有很多的資源的話,那就更容易OOM了;

內(nèi)部類new Handler(){}持有外部類Activity的引用

內(nèi)部類new Runable(){}持有外部類Activity的引用

2,添加static(注意Handler和Runable都要加static)

public class DActivity extends AppCompatActivity {//    @Inject//    D d;        static Handler mHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message message) {            return false;        }    });    static Runnable task = new Runnable() {        @Override        public void run() {                    }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_d);//        Diiii component = DaggerDiiii.builder().ddasfadfa(new Ddasfadfa()).build();//        component.injectD(this);                mHandler.postDelayed(task,500*1000);    }}分析:

這時(shí)Handler就不再是activity的孩子了,是靜態(tài)成員變量(是屬于類的,不屬于這個(gè)實(shí)例了),這時(shí)activity就可以被銷毀了,同時(shí),Runable也用static修飾了;這樣就不會(huì)造成OOM了。

3,但是,如果在Handler或者在Runable中有引用外部類的成員,那也會(huì)OOM

public class DActivity extends AppCompatActivity {//    @Inject//    D d;
	ImageView iv;
	TextView tv;        static Handler mHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message message) {
	    //tv.setText(“你好”);
	    //iv.set。。。。。。            return false;        }    });    static Runnable task = new Runnable() {        @Override        public void run() {            tv.setText(“你好”);
	    iv.set。。。。。。
	    finish;//引用了this        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_d);//        Diiii component = DaggerDiiii.builder().ddasfadfa(new Ddasfadfa()).build();//        component.injectD(this);                mHandler.postDelayed(task,500*1000);    }}如上,當(dāng)Runable中需要引用imageview和textview時(shí),這時(shí)也會(huì)造成內(nèi)部類持有外部類的引用;如果Handler中有引用的話,也會(huì)造成內(nèi)部類持有外部類的引用,解決辦法是:將tv、iv用靜態(tài)static修飾,這樣就不會(huì)持有其引用了;但是如果,Runable里面有tv、iv、bt等等,很多個(gè)引用呢?代碼改起來(lái)就很麻煩了;這時(shí)想到,造成OOM的問(wèn)題在于Activity想銷毀時(shí),這些成員變量tv、iv。。。卻還在被內(nèi)部類引用著;也就是說(shuō),只要activity被銷毀了,就不讓他執(zhí)行那些邏輯;所以就有下面的代碼:

publicclassMainActivity extends AppCompatActivity {

private Activity mActivity;

privatestaticfinal String TAG="stay4it";

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

init();

}

privatevoidinit(){

mActivity=this;

BetterHandler betterHandler = new BetterHandler(mActivity);

Message message=Message.obtain();

message.what=9527;

betterHandler.sendMessage(message);

betterHandler.postDelayed(new BetterRunnable(), 1000 * 20);

}

privatestaticclassBetterRunnable implements Runnable {

@Override

publicvoidrun() {

Log.i(TAG,"Runnable run()");

}

}

privatestaticclassBetterHandler extends Handler {

private WeakReference<Activity> activityWeakReference;

publicBetterHandler(Activity activity) {

activityWeakReference = new WeakReference<>(activity);

}

@Override

publicvoidhandleMessage(Message msg) {

super.handleMessage(msg);

if (activityWeakReference.get() != null) {

Log.i(TAG,"handle message");

}

}

}

}

就Activity需要用軟引用WeakReference包一下,不然會(huì)造成activity回收不了;如上面的代碼,當(dāng)屏幕旋轉(zhuǎn)后,activity銷毀,activity為null,當(dāng)handler執(zhí)行任務(wù)時(shí),activityWeakReference.get()為null,這樣就不會(huì)執(zhí)行里面的代碼。當(dāng)然這只是其中一種比較好的實(shí)現(xiàn)方式


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 舟曲县| 尚志市| 苏州市| 抚松县| 师宗县| 仁布县| 新宾| 施甸县| 壶关县| 大荔县| 郴州市| 昆明市| 普兰店市| 江安县| 翼城县| 洮南市| 台北市| 万盛区| 卢湾区| 秭归县| 合山市| 洞口县| 开平市| 泰兴市| 建平县| 常德市| 安康市| 闸北区| 封开县| 玉树县| 东光县| 德保县| 观塘区| 濉溪县| 德格县| 黑水县| 如皋市| 刚察县| 桂平市| 呼玛县| 湄潭县|