1. Singleton mode
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
Copy the code
The static nature of the singleton pattern makes the instance life cycle as long as the Application. If the context of an object is passed to construct the singleton pattern, when the object is no longer used and the singleton still holds the reference to the object, it can not be released, resulting in memory leakage.
Solution: Use ApplicationContext
2. Create static instances with non-static inner classes
public class MainActivity extends AppCompatActivity {
private static TestResource mResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mResource == null){
mResource = new TestResource();
}
//...
}
class TestResource {
//...
}
}
Copy the code
Effect: Prevents duplicate resource creation. Non-static internal classes hold references to external classes by default. The static instance has the same life cycle as the Application. When an internal class is used, it is still held by the static instance and cannot be released.
Workaround: Make each class static or separate the inner class into a single class referenced in singleton mode
3.Handler Memory leaks
public class MainActivity extends AppCompatActivity { private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //... }}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loadData(); } private void loadData(){ //... request Message message = Message.obtain(); mHandler.sendMessage(message); }}Copy the code
Handler is a non-static internal class that holds a reference to an external class by default. When an Activity ends, Message holds a reference to the mHandler instance, which holds a reference to the Activity.
Workaround: Create Handler static inner classes that hold objects using weak references
public class MainActivity extends AppCompatActivity { private MyHandler mHandler = new MyHandler(this); private TextView mTextView ; private static class MyHandler extends Handler { private WeakReference 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); }}Copy the code
4. Thread memory leaks
Asynchronous tasks and Runnable are both non-static inner classes that hold external class references by default, and cannot free memory when an Activity ends without the asynchronous task ending.
Solution: Static inner classes
static class MyAsyncTask extends AsyncTask { private WeakReference 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); }} / / -- -- -- the new Thread (new MyRunnable ()). The start (); new MyAsyncTask(this).execute();Copy the code
5. The resource is not closed
Resources such as Cursor that are not closed, Bitmap that is not reclaimed, BraodcastReceiver, ContentObserver, File, Stream, etc., should be closed or unregistered when the Activity is destroyed; otherwise, these resources will not be reclaimed, causing memory leaks.