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

首頁 > 學院 > 開發設計 > 正文

正確使用Handler

2019-11-09 13:44:40
字體:
來源:轉載
供稿:網友

下面是一個沒問題的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,當代碼改成下面的時候就會出現問題

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);    }}問題的原因在于:

當進入到這個界面后,反復的旋轉屏幕,導致這個頁面不斷的重新繪制,同時,如果持有很多的資源的話就會造成OOM;

分析原因:

一開始進入這個界面,初始化Handler,開啟延時任務,這時,屏幕旋轉,該activity需要被銷毀,卻發現,自己有個孩子還在做延遲任務,那么母親是肯定不能拋棄孩子的,所以,這個activity就銷毀不了了,當不斷的旋轉屏幕時,就會有很多個activity無法銷毀,如果持有很多的資源的話,那就更容易OOM了;

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

內部類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);    }}分析:

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

3,但是,如果在Handler或者在Runable中有引用外部類的成員,那也會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);    }}如上,當Runable中需要引用imageview和textview時,這時也會造成內部類持有外部類的引用;如果Handler中有引用的話,也會造成內部類持有外部類的引用,解決辦法是:將tv、iv用靜態static修飾,這樣就不會持有其引用了;但是如果,Runable里面有tv、iv、bt等等,很多個引用呢?代碼改起來就很麻煩了;這時想到,造成OOM的問題在于Activity想銷毀時,這些成員變量tv、iv。。。卻還在被內部類引用著;也就是說,只要activity被銷毀了,就不讓他執行那些邏輯;所以就有下面的代碼:

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包一下,不然會造成activity回收不了;如上面的代碼,當屏幕旋轉后,activity銷毀,activity為null,當handler執行任務時,activityWeakReference.get()為null,這樣就不會執行里面的代碼。當然這只是其中一種比較好的實現方式


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大英县| 石景山区| 钟山县| 察雅县| 扶余县| 含山县| 金堂县| 海宁市| 曲麻莱县| 仁布县| 株洲县| 县级市| 张北县| 邻水| 遵义县| 清水县| 毕节市| 九江市| 阳泉市| 固始县| 安徽省| 绥芬河市| 旬阳县| 蓬安县| 资溪县| 晋州市| 新巴尔虎右旗| 民丰县| 凤城市| 潮州市| 甘谷县| 九龙城区| 保定市| 临城县| 特克斯县| 邯郸县| 金阳县| 怀仁县| 邹城市| 泊头市| 石门县|