<Android 初步> Handler-------内存泄漏分析

来源:互联网 发布:数据集成方案ppt 编辑:程序博客网 时间:2024/05/22 04:36

如下代码分析:
public class MainActivity extends AppCompatActivity {    private TextView textView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        textView = (TextView)findViewById(R.id.textView);    }    private Handler handler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);           while (msg.what ==100){               textView.setText("android Thread");               break;           }        }    };    public void sendTheadCilck(View view){        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                handler.sendEmptyMessage(100);            }        }).start();    }}

这个段简单的代码是可以运行的,不会报错,那我们为什么它来作为  Handler内存泄漏的例子呢?

经过网上搜索和以及查看java的内部类知识,我们可以得出:

当我们把 Handler 当作内部类使用的时候,Handler其实可以引用其外部类所有的引用,那为什么会造成内存泄漏呢?
原因就是:如果如以上代码写的内部类,当Activity退出时,Handler其实还没有结束,这就会造成当我们退出这个程序时,Handler还在占用内存(Handler没有随着activity的结束而结束运行),所有造成不必要的内存泄漏。


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

所以我们就可以自己写一个Handlerlei类 去extends Handler 来防止内存泄漏
private static class myHandler extends Handler{}
在这个类的内部中,我们需要定义myHandler对Activity的弱引用
 private WeakReference<HandlerMemoryActivity> handlerMemoryActivityWeakReference;
弱引用的通俗解释就是(当Activity结束时,其内部类也会随之结束,释放内存)     -------强弱引用的原理请查阅java知识

然后定义一个构造方法,把Activity传进去
public myHandler(HandlerMemoryActivity handlerMemoryActivity){            handlerMemoryActivityWeakReference = new WeakReference<>(handlerMemoryActivity);        }
接下来就是重写handMessage()方法,在方法中,我们必须判断Activity是否为空
若不为空,则可以对Ui线程进行访问
 @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            HandlerMemoryActivity handlerMemoryActivity = handlerMemoryActivityWeakReference.get();            if (handlerMemoryActivity!=null){                if (msg.what==100){                    handlerMemoryActivity.textView.setText("handlerMemory");                }            }        }

以上,就是防止handler内存泄漏的正确写法。
程序修改源代码如下:
public class HandlerMemoryActivity extends AppCompatActivity {    private TextView textView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_handler_memory);        textView = (TextView) findViewById(R.id.textView_HandlerMemory);    }    //使用Handler正确写法    private static class myHandler extends Handler {        private WeakReference<HandlerMemoryActivity> handlerMemoryActivityWeakReference;        public myHandler(HandlerMemoryActivity handlerMemoryActivity) {            handlerMemoryActivityWeakReference = new WeakReference<>(handlerMemoryActivity);        }        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            HandlerMemoryActivity handlerMemoryActivity = handlerMemoryActivityWeakReference.get();            if (handlerMemoryActivity != null) {                if (msg.what == 100) {                    handlerMemoryActivity.textView.setText("handlerMemory");                }            }        }    }    private final myHandler handler = new myHandler(this);    public void sendNewHandlerCilck(View view) {        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(3000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                handler.sendEmptyMessage(100);            }        }).start();    }}


以上纯属个人理解的主观观点,不喜勿喷


0 0
原创粉丝点击