目录(?)[-]
线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。
[html] view plaincopy
- <span style="white-space:pre"> </span>/**
- *
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public class ThreadActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- Create(savedInstanceState);
- setContentView(R.layout.activity_main);
- new MyThread().start();
- }
- private class MyThread extends Thread {
- @Override
- public void run() {
- super.run();
- dosomthing();
- }
- }
- private void dosomthing(){
- }
- }
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。
第二、在线程内部采用弱引用保存Context引用。 代码如下:
[html] view plaincopy
- <span style="white-space:pre"> </span>/**
- *
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public class ThreadAvoidActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- Create(savedInstanceState);
- setContentView(R.layout.activity_main);
- new MyThread(this).start();
- }
- private void dosomthing() {
- }
- private static class MyThread extends Thread {
- WeakReference<ThreadAvoidActivity> mThreadActivityRef;
- public MyThread(ThreadAvoidActivity activity) {
- mThreadActivityRef = new WeakReference<ThreadAvoidActivity>(
- activity);
- }
- @Override
- public void run() {
- super.run();
- if (mThreadActivityRef == null)
- return;
- if (() != null)
- ().dosomthing();
- // dosomthing
- }
- }
- }
有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,
Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,
该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,
因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。
代码如下:
[html] view plaincopy
- /**
- *
- * 弱引用
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
- extends AsyncTask<Params, Progress, Result> {
- protected WeakReference<WeakTarget> mTarget;
- public WeakAsyncTask(WeakTarget target) {
- mTarget = new WeakReference<WeakTarget>(target);
- }
- @Override
- protected final void onPreExecute() {
- final WeakTarget target = ();
- if (target != null) {
- PreExecute(target);
- }
- }
- @Override
- protected final Result params) {
- final WeakTarget target = ();
- if (target != null) {
- return this.doInBackground(target, params);
- } else {
- return null;
- }
- }
- @Override
- protected final void onPostExecute(Result result) {
- final WeakTarget target = ();
- if (target != null) {
- PostExecute(target, result);
- }
- }
- protected void onPreExecute(WeakTarget target) {
- // Nodefaultaction
- }
- protected abstract Result doInBackground(WeakTarget target,
- params);
- protected void onPostExecute(WeakTarget target, Result result) {
- // Nodefaultaction
- }
- }
目录(?)[-]
线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。
[html] view plaincopy
- <span style="white-space:pre"> </span>/**
- *
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public class ThreadActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- Create(savedInstanceState);
- setContentView(R.layout.activity_main);
- new MyThread().start();
- }
- private class MyThread extends Thread {
- @Override
- public void run() {
- super.run();
- dosomthing();
- }
- }
- private void dosomthing(){
- }
- }
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。
第二、在线程内部采用弱引用保存Context引用。 代码如下:
[html] view plaincopy
- <span style="white-space:pre"> </span>/**
- *
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public class ThreadAvoidActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- Create(savedInstanceState);
- setContentView(R.layout.activity_main);
- new MyThread(this).start();
- }
- private void dosomthing() {
- }
- private static class MyThread extends Thread {
- WeakReference<ThreadAvoidActivity> mThreadActivityRef;
- public MyThread(ThreadAvoidActivity activity) {
- mThreadActivityRef = new WeakReference<ThreadAvoidActivity>(
- activity);
- }
- @Override
- public void run() {
- super.run();
- if (mThreadActivityRef == null)
- return;
- if (() != null)
- ().dosomthing();
- // dosomthing
- }
- }
- }
有些人喜欢用Android提供的AsyncTask,但事实上AsyncTask的问题更加严重,
Thread只有在run函数不结束时才出现这种内存泄露问题,然而AsyncTask内部的实现机制是运用了ThreadPoolExcutor,
该类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,
因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。
代码如下:
[html] view plaincopy
- /**
- *
- * 弱引用
- * @version 1.0.0
- * @author Abay Zhuang <br/>
- * Create at 2014-7-17
- */
- public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
- extends AsyncTask<Params, Progress, Result> {
- protected WeakReference<WeakTarget> mTarget;
- public WeakAsyncTask(WeakTarget target) {
- mTarget = new WeakReference<WeakTarget>(target);
- }
- @Override
- protected final void onPreExecute() {
- final WeakTarget target = ();
- if (target != null) {
- PreExecute(target);
- }
- }
- @Override
- protected final Result params) {
- final WeakTarget target = ();
- if (target != null) {
- return this.doInBackground(target, params);
- } else {
- return null;
- }
- }
- @Override
- protected final void onPostExecute(Result result) {
- final WeakTarget target = ();
- if (target != null) {
- PostExecute(target, result);
- }
- }
- protected void onPreExecute(WeakTarget target) {
- // Nodefaultaction
- }
- protected abstract Result doInBackground(WeakTarget target,
- params);
- protected void onPostExecute(WeakTarget target, Result result) {
- // Nodefaultaction
- }
- }
本文发布于:2024-01-31 09:35:21,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170666492427567.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |