Android fixing memory leaks in legacy code


There are a lot of memory leaks in android applications that were written several years ago without using modern libraries. Fortunately, most of them can be easily fixed without additional dependencies.

Inner AsyncTask leak

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private View someOtherView;
    ...

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        ...
    }

    ...

    private void someMethod() {
        ...
        new MyAsyncTask().execute();
    }

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            ...
            some code
            ...
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            textView.setText("done");
            someOtherView.setVisibility(View.GONE);
        }
    }
}

There is a MainActivity memory leak here, because MyAsyncTask class has implicit reference to it, and therefore, MyAsyncTask may prevent MainActivity to be garbage collected (in case if it will outlive activity).
To fix this kind of memory leak, we need to declare MyAsyncTask class with a static keyword. It will help to remove implicit reference to MainActivity. Secondly, to deal with missing references in MyAsyncTask, we should use WeakReference on MainActivity to get them if activity exist:

Android new Throwable().printStackTrace()


Sometimes it’s very hard to navigate through code that you didn’t write. Especially if that code was written a long time ago, and has thousands of lines, and a complex architecture. „Find Usages” option in Android Studio may not help you, and understanding what is going on can be difficult and frustrating. It would be very nice to have a simple mechanism which can show you a stack trace at desired code location. Like while printing exceptions:


Fortunately, we can easily show stack trace at any code location by calling:

Android ripple drawable

Ripple drawable - a drawable that shows a ripple effect in response to state changes.

Rounded corners rectangle


Layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:background="@drawable/my_ripple"
        android:clickable="true" />

</FrameLayout>

my_ripple:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#e53935">
    <item>
        <shape>
            <solid android:color="#777" />
            <corners android:radius="20dp" />
        </shape>
    </item>
</ripple>

Rounded corners rectangle 2