I know that the UI elements (View hierarchy) may only be manipulated from the UI thread. For a background operation, the AsyncTask can be used, which offers event handlers to reach the UI thread.
To be brief, is it allowed to instantiate a View (tied to getApplicationContext()) in a non-UI thread? This custom View descendant — once instantiated — is added to the view hierarchy from the UI thread. So only the constructor call is done inside an Asynctask.doInBackground(); it’s attaching (addView(...)) to the Activity’s root layout hierarchy is still done in the UI thread.
In details:
public MyView extends View {
public MyView(Context context) {
...
}
...
}
-
I made a custom View, with overriden
onDraw(...)etc. -
When the user clicks a certain MenuItem in my main Activity, another Activity (MyOtherActivity) is created and displayed which screen is exactly MyView
-
Since the screen of MyOtherActivity must be displayed instantly, I pre-instantiate MyView in an AsyncTask while the user is somewhere else in the main Activity (i.e. he hasn’t clicked that MenuItem yet). The MyView reference is stored in a static data member.
-
When
MyOtherActivity.onCreate()is called, its constructor code takes MyView from the static, and adds it to its layout root hierarchy viaaddView(...). -
(I’m aware that the static variable may introduce memory leaks, so I set it to
nullonce it’s not needed.)
Isn’t it a problem (and might it introduce unexpected issues) that MyView is instantiated in a different thread (and takes the return value of getApplicationContext() in its constructor)?
The definitive answer appears in the documentation for View, under the heading “Event Handling and Threading”:
So it’s not just things that obviously affect the appearance of the UI, like
addView(), but “any method on any View”.The discussion on android-developers that @CommonsWare linked to has more than one high-level engineer from the Android framework team confirming that this is to be taken seriously.