TextureView survival guide
Hello. Straight to the point.
You are here because you are either bored or want to finally get your project done. Either way, this article is not a how-to, but a collection of tips and rules related to TextureView. That will fix your problems though.
You can find formal documentation HERE.
No use? Not surprised.
TextureView is a SurfaceView wrapper that gets shit done. If you ask me “Do I need SurfaceView or TextureView for my pro…”, I will stop you right there and tell you to use TextureView.
Why not SurfaceView?
Because it sucks. No, seriously:
- It flashes with black when you redraw it.
- You can not control it (you can not control TextureView either, but it’s got much more versatility)
- You can’t make it too big
- You can not scale it, animate or transform
- You can not use a SurfaceView on top of another one
- You can not stream anything on it
The list is not full and I don’t feel like making it 40-points long because my experience is from making a Metro application.
The first thing we needed to create is a huge GL-like surface to draw on its canvas. Being quite inexperienced in this low-level mechanisms, we’ve decided to use TextureView. Two weeks into the project and I’m smashing my head into the table because TextureView flashes with black when you try to drag it, scale it, etc. What do all Android developers do in such cases? They go and break someone else’s .apk to find references in application, protected by ProGuard, or to borrow a whole class from someone who does not use ProGuard.
TextureView in a nutshell:
- Hardware accelerated, fast as fuck
- Easily manipulated
- Has weird issues on specific CPUs
- Crashes without any logs if you go out of GPU memory
We’ve stumbled upon SurfaceView class in Yandex.Metro and at this point we’ve already found TextureView, but we needed more confidence in what we’re doing because we were 2 weeks late on schedule.
You must use hardware acceleration if you want to use TextureView to avoid issues on some devices and make it draw much faster.
Do not attempt to use default TextureView, extend it into your View class. Or you will not be able to change onMeasure and it will make your code hard to read. Are you doing a heavy view with its own drawing thread? Then make it in a special class.
At that point we’ve understood that we can easily manipulate its size in onMeasure. Unfortunatelly, you must find a middle ground for all phones because GPU OOM crashes give no logs, no stacktrace, no weird debug lines, nothing. The application just stops. If you encounter it, make the TextureView less in size.
Then we’ve encountered weird problems on some devices. The first one to encounter it was Nokia 2 DS powered by 7-ish Android. TextureView just didn’t want to be drawn, and we fixed that by making its size less. At the moment we only have one problem on this device – TextureView does not redraw it after onResume after we explicitly ask it to. Why? Nobody fucking knows, all we get is Qualcomm BoostFramework logs that lead to nowhere. I’ve found the topic about this issue dating back to 2016 with no response from devs.
You will need to look for your drawing threads. You can only make one drawing thread at the time and you must look for managing your threads or you will get SEGV fault, which is essentially a NullPointer in Native methods.
You must know that TextureView works differently on different devices. Thanks to Android fragmentation, we’ve got no solid ground to make our applications. You can find your TextureView work amazingly on Huawei Honor 6X, but suffer to work on Nokia 7.
At this point you already prepare yourself for a week of eternal suffering implementing scale and drag systems, but don’t fear (The Reaper) because TextureView amazingly works with a default Android SDK Matrix. It will be a pain to make drag and scale systems like Google Maps’s one, that continues to move after you drag it, feels very responsive. But it is the case to the whole Android ecosystem because we can’t have good SDK because of fragmentation. We don’t have this tedious time-wasting things in Flutter, but we can’t afford to use Flutter for huge projects in company environment because it’s not even released yet to be completely sure in it.
The best example to using TextureView is Yandex.Metro. Their map is little enough to make a full of use its advantages and doesn’t fall to the drawbacks of undefinable Native-level issues. It still looks kinda crappy because they don’t want it to crash on uncle George’s HTC Dream.
TextureView is fast as fuck. We’ve made our custom TextureView to scale its size to the size of the screen. That means, we’ve got about 5000×5000 on Huawei Honor 6X and about 2400 on Sony Xperia E1 D2005. That seems fine (ATM). It draws in about 0.2-0.3 seconds.
TBA, I guess.