Android Handler Memory Continues to Grow
You have seen many articles related to android interview Q&A but they all not give you proper android interview Q&A, so in this article, I going to share my experience which I gained from giving and taking lots of the interviews of Android Engineer.
Here in this article, I am going to focus on AsyncTask because there is a 90% chance to ask the questions related to AsyncTask in every Interview of an Android Engineer and I try to cover all the possible questions related to AsyncTask, so stay with me.
What is AsyncTask?
It is an android framework API that uses for short background operations and IPC(inter-process communication) which means we can communicate between the main thread and background thread provided by Asynctask API.
Under the hood of any multithreading API, uses the Thread class is as per the requirement and if any of these API also provides background thread and main thread IPC they used the combination of thread class and handler in android.
Let's see, how to use AsyncTask
import android.os.AsyncTask import android.os.Bundle import android.os.SystemClock import android.widget.Button import android.widget.ProgressBar import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { lateinit var mProgressBar: ProgressBar lateinit var button: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mProgressBar = findViewById(R.id.progress_horizontal) button = findViewById(R.id.btn) button.setOnClickListener { MAsyncTask().execute(10); } } private inner class MAsyncTask : AsyncTask<Int, Int, Void>() { override fun doInBackground(vararg values: Int?): Void? { for (i in 0..values[0]!!) { publishProgress(i) SystemClock.sleep(500) } return null } override fun onProgressUpdate(vararg values: Int?) { mProgressBar.progress = values[0]!! } }
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#C8C7C4" android:gravity="center" android:orientation="vertical" android:padding="16dp" tools:context=".MainActivity"> <ProgressBar android:id="@+id/progress_horizontal" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" /> <com.google.android.material.button.MaterialButton android:id="@+id/btn" android:layout_width="160dp" android:layout_height="wrap_content" android:layout_marginTop="100dp" android:background="#1E1C1C" app:elevation="20dp" android:backgroundTint="#1E1C1C" android:text="Start" android:textColor="@android:color/white" app:cornerRadius="20dp" /> </LinearLayout>
As you can see in the aboveMainActivity.xml, doInBackground () method run the task on the background thread and we are passing the data from the background thread to the main thread ("UI Thread") with help of publishProgress() method and this method invoke the onProgressUpdate() where we get the result from the background the thread.
I know, you are thinking that why I am showing you the basic things about AsyncTask basically I am just trying you to go through the basics of AsyncTask, it helps if some newbies come here and you also.
Let's jump to questions related to AsyncTask one by one.
1. Which method runs in the background thread and which on the main thread?
Ans: Only doInBackground () method is run on the background thread and all other methods of the AsyncTask run on the main thread.
2. What if we call AsyncTask's execute method multiple times?
Ans: So here are two scenarios:-
a)- if we call the asynctask.execute() method multiple times on the same instance then we got runtime-exception as it is due to when AsyncTasks introduced first starting fromDONUTwere executed serially on a single background thread but onwardsHONEY_COMB they introduced a new method executeOnExecutor() where you can use a thread pool to perform multiple tasks parallelly, we will see it later in this article, don't worry.
b)- In the second scenario, if we call execute method multiple times but every time we are creating a new object of the async task such as MyAsynctask().execute() then we won't get any exception but all tasks perform serially.
3. When we call execute method multiple times then how do all tasks perform synchronously or asynchronously?
Ans: When we call execute method multiple times (but remember we have to create a new instance of AsyncTasks every time we call execute method as discussed in the previous question) then all tasks perform one-by-one means synchronously.
4. Can we perform multiple tasks asynchronously in AsyncTask, if yes then how?
Ans: Yes, by default the async task uses a single thread but we can do this using multiple threads with the help ofTHREAD_POOL_EXECUTOR. In AsyncTasks we have two methods to execute AsyncTasks one is execute () and the other is executeOnExecutor ().
So with this second method, we can perform multiple tasks asynchronously and it takes two params one is AsyncTasks input and the other is a thread pool object where we define no of thread, so it is better to learn by doing.
Let's do some code
button.setOnClickListener { MAsyncTask(10).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
5. What is memory leaks, when it happened in the AsyncTask and how you can handle this?
Ans: a) Memory leaks:- To understand memory leaks we have to understand what is the garbage collector first.
Garbage Collector : Every time when you create an object its reference is stored in the stack or we can say object created in the stack and stored in heap. This reference in the stack pointing to its' heap object we called it a pointer.
When we run the program all referencing objects releases from the stack memory as they execute one-by-one and free up the stack memory.
But what about the objects in the heap memory so here is our man the garbage collector comes into the picture, it looks up in the heap memory if any object which has not any reference pointing to it then the garbage collector releases it and free-up the heap memory.
Now you have a clear picture of the duty of the garbage collector to release the unused object from the heap memory.
What is memory leaks : when garbage collector failed to release the unused object that means when some objects in the memory are unused in the application but they have their references pointing to them so the garbage collector feels that they are still using somewhere in the application but in reality, they are not using any more and garbage collector does not release them and these objects are still occupying the memory at the end of the application this lead to memory leaks.
Ans: b) Memory leaks in AsyncTask : As you can see in the above code snippet, we are calling AsyncTask from a button, so we click the button task start and updates our progress bar but if the user rotates the screen or press back button then activity gets destroyed and AsyncTask continues running in the background and AsyncTask holds the reference of our activity context which means object does not get garbage collected and leads to a memory leak.
As you can see in the above screenshot that we are getting memory leaks. There is a library which helps us to easily detect memory leak where you'll see the exact same kind of screen when you get any memory leak in your application and you just need to put the leak canary dependency in the build.gradle and you will automatically notify if any memory leaks happened in the application.
dependencies { // debugImplementation because LeakCanary should only run in debug builds. debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
}
LeakCanary: https://square.github.io/leakcanary/getting_started/ for the full documentation.
Ans: c) Here is the good news for you developers that AsyncTask is deprecated in Android API level 30, but there are lots of different question has been asked recently on AsyncTask.
Check this official link: https://developer.android.com/reference/android/os/AsyncTask.
Let's come to the point that how we can avoid memory leaks in Asynctask so there are multiple approaches to avoid memory leaks but all depends on which purpose you are going to use AsyncTask. Two simple and best approaches I am going to show you which are mostly used to handling memory leaks.
-> Using WeakReference: The weak reference does not protect the object from Garbage collection and the activity object easily garbage collected, let's jump to the code.
override fun doInBackground(vararg p0: Void?): Void? { for (i in 0..10) { if (isCancelled()) { break; } SystemClock.sleep(1000) onProgressUpdate(i) } return null } override onStop(){ if(mAsyncTask!=null) mAsyncTask.canel(true)
}
As you have seen I have shown you two types of approaches but there more types of approaches and I suggest checking this article to learn more types of approaches to handle memory leaks in Android not only in AsyncTaskclick here
Happy Coding
As I already told you that AsyncTask has been deprecated since Android API level 30, but in the case of the interview lots of questions asked by the interviewer to check the candidate's understanding of the multi-threading concepts, so please read all the questions properly they'll definitely help you in your Android interviews. And if someone has more questions related to AsyncTask please comment below we will consider them in our coming article based on Android Interview Questions.
Hope you enjoyed this article please share your love by commenting below and subscribe our newsletter for future article's notification.
Follow us on:
Youtube: https://lnkd.in/eMgCMG3
Instagram: https://lnkd.in/eBqf_pi
Facebook: https://lnkd.in/eu5Uisr...
Twitter: https://lnkd.in/ei8NSRn
Telegram: https://t.me/coder_lane
Source: https://www.linkedin.com/pulse/android-deep-dive-garbage-collector-memory-leaks-nitin-prakash
0 Response to "Android Handler Memory Continues to Grow"
Post a Comment