Why your Android Apps Suck


Published on

When I learn more about Android's graphics system, and do more work about how to use CPU/GPU in more parallelized way to improve the graphics performance in Android,
I start to think that there are actually some big design mistakes in Android graphics system, especially the rendering architecture in the client side.Some mistakes have been solved after 3.x, especially above 4.1, but others can never be solved due to the compatible reason.
As developers, we need to know how the Android graphics system work, how to utilize the new features Android 3.x and 4.x provided, and how to do the optimization and overcome the shortage of Android.

Published in: Technology, Art & Photos
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Why your Android Apps Suck

  1. 1. Why your Android Apps Suck易旭昕 (Roger)roger2yi@gmail.comen.gravatar.com/roger2yi
  2. 2. 6/20/2013 Roger, UCAbout Mehttp://weibo.com/roger2yi
  3. 3. 6/20/2013 Roger, UCWhy I wrote this article?– When I learn more about Androids graphicssystem, and do more work about how to useCPU/GPU in more parallelized way toimprove the graphics performance in Android– I start to think that there are actually some bigdesign mistakes in Android graphics system,especially the rendering architecture in theclient side
  4. 4. 6/20/2013 Roger, UC• Some mistakes have been solved after 3.x,especially above 4.1, but others can never besolved due to the compatible reason• As developers, we need to know how theAndroid graphics system work, how to utilize thenew features Android 3.x and 4.x provided, andhow to do the optimization and overcome theshortage of Android
  5. 5. 6/20/2013 Roger, UCDirect Rendering• In the very beginning, Androids client/serverarchitecture of its graphics system choose thedirect rendering mode• Android team develop a lightweight WindowCompositor - SurfaceFlinger by themself, itresponse to create native windows, allocategraphics buffers and composite the windowsurface to display (via framebuffer)
  6. 6. 6/20/2013 Roger, UC• In client side, apps (through Android runtime)can use CPU to access the graphics buffer ofnative window directly (through Skia), or useGPU to manipulate it indirectly (through GLES)• This direct rendeing mode is more appropriatethan the traditional X in desktop Linux
  7. 7. 6/20/2013 Roger, UC
  8. 8. 6/20/2013 Roger, UCWindow Composite in ServerSide• SurfaceFlinger use GLES1 to do the windowcomposition (via texture operation) in the verybeginning, this cause two issues– Chip may have more efficient way (DisplayController) to do the window composition thanuse GLES– When the client side also use GLES to renderthe window surface, it may competes with theserver about the GPU resources• Just mention, when GPU do not support GLES1, Android has a built-inSW version GLES1 stack, and it can use copybit HAL module providedby chip vendor to accelerated the texture operation
  9. 9. 6/20/2013 Roger, UCiOS do not needWindow Composite!!!• It only has one visible window at one time, sothe app can render to framebuffer directly• Advantages– Save memory usage– Reduce GPU usage– Save memory bandwidth• Disadvantages– Only one visible app at screen– Do not support 3rd SIP or lanucher forsecurity
  10. 10. 6/20/2013 Roger, UC• So, after 3.0, Android introduce hwcomposerHAL module to solve these issues, also abandonthe old copybit module• Chip vendor can through the implementation ofhwcomposer module to declare they can do allof or part of windows composition bythemselves, usually with dedicated hardwareand always more efficient than use GLES
  11. 11. 6/20/2013 Roger, UC• When all windows composited by hwcomposer,and keep SurfaceFlinger idle– Reduce GPU usage– Save memory bandwidth– Improve performance and save energy• In theory, Android will has same performancewith iOS when it has only one visible window
  12. 12. 6/20/2013 Roger, UC• Also, after 4.1, hwcomposer can provide thevsync signal of the display, so that Android cansync three things together– the windows composition in server side– the rendering of window surface in client side– the refresh of display
  13. 13. 6/20/2013 Roger, UC
  14. 14. 6/20/2013 Roger, UCRendering Architecture in ClientSide• The most mistake Android team make is therendering architecture of its GUI framework– It do not has a layer rendering architecture (orcalled scene graph in some GUI fw)– It do not has a dedicated rendering thread torender the window surface– Its rendering only use CPU until 3.0• The first one is partially support after 3.0, thethird is support after 3.0, but the second problemcan never be solved...
  15. 15. 6/20/2013 Roger, UCCompare to iOS• Every View has a Layer as its backing store, appcan create more Layers for better performance• Views content will be drew into its Layer, aslong as the content do not changed, the View donot need to draw itself again• iOS do a lot of things to avoid change thecontent of a View, many many properties of aView can be changed without affect to itscontent, such as background, border, opacity,position, transformation, even the geometry!!!
  16. 16. 6/20/2013 Roger, UC• The composition of Layers done by anotherdedicated rendering thread, it always use GPUto draw each Layer to the window surface• The main thread only reponse to handle touchevent, relayout the Views, draw Views contentinto its Layer when necessary, etc...• So the main thread only use CPU and therendering thread use GPU mostly, and I thinkthere will be just a few synchronization betweenthese two threads, and they can run concurrentlyin most of time
  17. 17. 6/20/2013 Roger, UC• But in Android, the main thread need to doeverything, such as handle touch events,relayout views, dequeue/enqueue graphicsbuffer, draw views content to window surface,etc... And it only use CPU before 3.0!!!• Even the position of a View just change onepixel, Android need to redraw its content alongwith the contents of other Views overlapped, andthe content drawing is very expensive for CPU!!!
  18. 18. 6/20/2013 Roger, UCThe Improvements• A lot improvements have been made after 3.0 toovercome the shortage of previous version• Android 3.0 introduce a new hwui module, and itcan use GPU to accelerated the drawing ofViews content, it create a hw acceleratedCanvas to replace the old sw Canvas, the newCanvas use OpenGL ES as its backend insteadof use SkCanvas from Skia
  19. 19. 6/20/2013 Roger, UC• Android 3.0 also introduce the DisplayListmechanism, DisplayList can be considered as a2D drawing commands buffer, every View hasits own DisplayList , and when its onDrawmethod called, all drawing commands issuethrough the input Canvas actually store into itsown DisplayList
  20. 20. 6/20/2013 Roger, UC• When every DisplayList are ready, Android willdraw all the DisplayLists, it actually turn the 2Ddrawing commands into GLES commands touse GPU to render the window surface• So the rendering of View Hierarchy actuallyseparated into two steps, generate ViewsDisplayList, and then draw the DisplayLists, andthe second one use GPU mostly
  21. 21. 6/20/2013 Roger, UC• When app invalidate a View, Android need toregenerate its DisplayList, but the overlappedViews DisplayList can keep untouched• Also, Android 4.1 introduce DisplayListproperties, DisplayList now can has manyproperties such as opacity, transformation, etc...,and the changed of some properties of View willjust cause changed of corresponding propertiesof its DisplayList and need not to regenerate it• These two improvements can save some timesby avoid regenerate DisplayLists unnecessary
  22. 22. 6/20/2013 Roger, UC• Although Android can never has a layerrendering architecture, it actually introduce someLayer support after 3.0, a View can has a Layeras its backing store• The so called HW Layer actually back by a FBO,if the content of View is too complicated andunlikely to change in the future, use Layer mayhelp• Also, when a View is animating (but content donot change), cache itself and its parent withLayers may also help
  23. 23. 6/20/2013 Roger, UC• But use Layer with caution, because it increasethe memory usage, if your want to use Layersduring animation, your may need to releasethem when the animation is finish, Android 4.2provide new animation API to help you aboutthat• Also, because Android use GLES to draw thecontent of View, so most Views drawing will befast enough, and the use of Layer may beunnecessary
  24. 24. 6/20/2013 Roger, UC• Android 4.0 introduce a new type of native window -SurfaceTextureClient (back by a SurfaceTexture) and itsJava wrapper TextureView, app can create and own thiskind of native window and response to its composition• If the content of View is too complicated and continue tochange, TextureView will be very helpful, app can useanother thread to generate the content of TextureViewand notify the main thread to update, and main threadcan use the TextureView as a normal texture and draw itdirectly on the window of current Activity
  25. 25. 6/20/2013 Roger, UC• Android 4.1 make the touch event handling andui drawing sync with the vsync signal of display,it also use triple buffers to avoid block the mainthread too often because it need to wait theSurfaceFlinger to release the buffer, andSurfaceFlinger will always sync with vsync signalof display• The OpenGL Renderer for hw acceleratedCanvas is continue be improved and becomefaster, especially for complicated shape drawing
  26. 26. 6/20/2013 Roger, UCBut...• But Android can never has a dedicatedrendering thread...• Although the drawing is much faster than before,and keep the changed of everything as little aspossible during animating, it still need to sharethe 16ms interval with other jobs in main threadto achieve 60 fps
  27. 27. 6/20/2013 Roger, UCSo...• So, as developer, we need to utilize theimprovements in higher version Android asmuch as possible– Turn on the GPU acceleration switch aboveAndroid 3.0– Use the new Animation Framework for youranimation– Use Layer and TextureView when necessary– etc...
  28. 28. 6/20/2013 Roger, UC• And avoid to block the main thread as much as possible, that means– If your handle the touch events too long, do it in another thread– If your need to load a file from sdcard or read data fromdatabase, do it in another thread– If your need to decode a bitmap, do it in another thread– If your Views content is too complicated, use Layer, if it continueto change, use TextureView and render it in another thread– Even your can use another standalone window (such asSurfaceView) as a overlay and render it in another thread– etc...
  29. 29. 6/20/2013 Roger, UCGolden Rules for ButterGraphics• Whatever you can do in another thread, then doit in another thread• Whatever you must do in main thread, then do itfast• Always profiling, it is your most dear friend
  30. 30. 6/20/2013 Roger, UCAll you need to do is keep the loopof main thread under 16ms interval,and every frame will be perfect!
  31. 31. 6/20/2013 Roger, UCThe Last Word• When I finish this article, what make me thinkmost is, when you make a big design mistake inthe very beginning, and you can not change itdue to some reasons, no matter how hard youtry to patch it in future, it will never get perfectagain• Android team make huge effects to providefeatures like Strict Mode, AsyncTask,Concurrent & Background GC, hw acceleratedCanvas, hw Layer, TextureView, vsync, triplebuffers, etc...
  32. 32. 6/20/2013 Roger, UC• All they do just about two things, do everythingyou can in another thread, and make the mustthing in main thread faster, and these actuallyhelp a lot• But no matter how hard you try to use thesefeatures to improve your app, it is nearlyimpossible to get every frame perfect, because itis so hard to forecast everything the main threadwill do in every loop, it may suddenly jump intosomething totally uncontrollable by you app andmake you break the 16ms curse
  33. 33. 6/20/2013 Roger, UC• And the worse is, if you has a good design, youcan continue improve it (like utilize moreadvance hardware), but the developer need notto know anything about this and do not need tochange even one line of their code, if the apprun on higher version OS with faster device, itjust got the performance boost
  34. 34. 6/20/2013 Roger, UC• If you has a bad design, although you do a lot ofthings to patch it, but the developer need toknow why, they need to rewrite their code to usethese new features, they need to know how toavoid the trap, they need to know how to makecompatible with older version system, and manymany other things...• This is too hard for a developer just want to builda useful and beauty app...
  35. 35. The EndThank you for yourlisteningYours Sincerely, Roger