Android内存泄露处理
Android内存泄露处理
竹蜻蜓O_0纸飞机 发表于2年前
Android内存泄露处理
  • 发表于 2年前
  • 阅读 8
  • 收藏 1
  • 点赞 1
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

看过一些大神分享的文章,吸取一些经验

1、处理Handler造成的内存泄露

创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象,这样虽然避免了Activity泄漏,不过Looper线程的消息队列中还是可能会有待处理的消息,所以我们在Activity的Destroy时或者Stop时应该移除消息队列中的消息

public class MainActivity extends AppCompatActivity {

private MyHandler mHandler = new MyHandler(this);

private TextView mTextView;


private static class MyHandler extends Handler {

private WeakReference<Context> reference;


public MyHandler(Context context) {

        reference = new WeakReference<>(context);

        }


@Override

public void handleMessage(Message msg) {

MainActivity activity = (MainActivity) reference.get();

if (activity != null) {

activity.mTextView.setText("");

}

}

}


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mTextView = (TextView) findViewById(R.id.textview);

loadData();

}


private void loadData() {

// ...request

Message message = Message.obtain();

mHandler.sendMessage(message);

}


@Override

protected void onDestroy() {

super.onDestroy();

mHandler.removeCallbacksAndMessages(null);

}

}


2、线程造成的内存泄漏

static class MyAsyncTask extends AsyncTask<Void, Void, Void> {

    private WeakReference<Context> weakReference;


    public MyAsyncTask(Context context) {

        weakReference = new WeakReference<>(context);

    }


    @Override

    protected Void doInBackground(Void... params) {

        SystemClock.sleep(10000);

        return null;

    }


    @Override

    protected void onPostExecute(Void aVoid) {

        super.onPostExecute(aVoid);

        MainActivity activity = (MainActivity) weakReference.get();

        if (activity != null) {

        //...

        }

    }

}

static class MyRunnable implements Runnable{

    @Override

    public void run() {

        SystemClock.sleep(10000);

    }

}

//——————

new Thread(new MyRunnable()).start();

new MyAsyncTask(this).execute();


一些建议

  1. 对于生命周期比Activity长的对象如果需要应该使用ApplicationContext

  2. 对于需要在静态内部类中使用非静态外部成员变量(如:Context、View ),可以在静态内部类中使用弱引用来引用外部类的变量来避免内存泄漏

  3. 对于不再需要使用的对象,显示的将其赋值为null,比如使用完Bitmap后先调用recycle(),再赋为null

  4. 保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期

  5. 对于生命周期比Activity长的内部类对象,并且内部类中使用了外部类的成员变量,可以这样做避免内存泄漏:

    1. 将内部类改为静态内部类

    2. 静态内部类中使用弱引用来引用外部类的成员变量

  6. 在涉及到Context时先考虑ApplicationContext


共有 人打赏支持
粉丝 6
博文 13
码字总数 2578
×
竹蜻蜓O_0纸飞机
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: