SlideShare a Scribd company logo

Performance tools Droidcon Eastern Europe

Diaconu Andrei-Tudor
Diaconu Andrei-Tudor
Diaconu Andrei-TudorAndroid Ninja at MiOS, Ltd.

Slides for the "Performance Tools" presentation for Droidcon Bucharest. It is a talk about Traceview, Systrace and Battery Historian, with some practical, or better yet impractical examples. Description: The Android ecosystem has a lot of tools to help us out when it comes to development. We all use Android Studio, gradle and adb, for instance. We need to, as these are essential tools for building our products. But what about the tools that help us diagnose problems in our apps? This session is all about asking 2 very common questions: Why is my app stuttering or dropping below 60fps? Why are my users telling me that my app drains their batteries? Most of the times solving a problem means asking the right questions in order to find the right answers. So starting from these 2 questions, with concrete problem-code examples we will be using tools from Google to find our answers. I don't want it to be a secret, so I'm telling you that the tools we will be using the most will be Traceview and Battery Historian. We will also be looking at Profiling GPU Rendering and Debugging Overdraw. I know that these tools might look a bit scary or dull but I promise to keep it simple so that you walk away with information you can use at work the next day.

Performance tools Droidcon Eastern Europe

1 of 124
Download to read offline
Performance Tools
Andrei Diaconu
Andrei Diaconu
Andrei Diaconu
Andrei Diaconu
Andrei Diaconu
• Cofounder of Android Iași
Andrei Diaconu
• Cofounder of Android Iași
• 5 years of Android

Recommended

Analyzing Display and Performance with Systrace
Analyzing Display and Performance with SystraceAnalyzing Display and Performance with Systrace
Analyzing Display and Performance with SystraceRouyun Pan
 
LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)LLVM Register Allocation (2nd Version)
LLVM Register Allocation (2nd Version)Wang Hsiangkai
 
Trace kernel code tips
Trace kernel code tipsTrace kernel code tips
Trace kernel code tipsViller Hsiao
 
Yet another introduction to Linux RCU
Yet another introduction to Linux RCUYet another introduction to Linux RCU
Yet another introduction to Linux RCUViller Hsiao
 
Linux kernel tracing
Linux kernel tracingLinux kernel tracing
Linux kernel tracingViller Hsiao
 
Linux BPF Superpowers
Linux BPF SuperpowersLinux BPF Superpowers
Linux BPF SuperpowersBrendan Gregg
 

More Related Content

Similar to Performance tools Droidcon Eastern Europe

Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)James Titcumb
 
Schema design short
Schema design shortSchema design short
Schema design shortMongoDB
 
Cool bonsai cool - an introduction to ElasticSearch
Cool bonsai cool - an introduction to ElasticSearchCool bonsai cool - an introduction to ElasticSearch
Cool bonsai cool - an introduction to ElasticSearchclintongormley
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Damien Seguy
 
Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Wongnai
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Servicevvatikiotis
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Brian Sam-Bodden
 
Introduction to R Short course Fall 2016
Introduction to R Short course Fall 2016Introduction to R Short course Fall 2016
Introduction to R Short course Fall 2016Spencer Fox
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R MapperIan Lewis
 
DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsKyungmin Lee
 
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with RailsSolving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Railsfreelancing_god
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainKen Collins
 
Effective codereview | Dave Liddament | CODEiD
Effective codereview | Dave Liddament | CODEiDEffective codereview | Dave Liddament | CODEiD
Effective codereview | Dave Liddament | CODEiDCODEiD PHP Community
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceshipsSabin Marcu
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...DroidConTLV
 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!Jason Feinstein
 
Android Automated Testing
Android Automated TestingAndroid Automated Testing
Android Automated Testingroisagiv
 
Don't Repeat Yourself, Repeat Others
Don't Repeat Yourself, Repeat OthersDon't Repeat Yourself, Repeat Others
Don't Repeat Yourself, Repeat OthersJohn Nunemaker
 

Similar to Performance tools Droidcon Eastern Europe (20)

Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
 
Schema design short
Schema design shortSchema design short
Schema design short
 
Cool bonsai cool - an introduction to ElasticSearch
Cool bonsai cool - an introduction to ElasticSearchCool bonsai cool - an introduction to ElasticSearch
Cool bonsai cool - an introduction to ElasticSearch
 
Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)Php Code Audits (PHP UK 2010)
Php Code Audits (PHP UK 2010)
 
Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)Solr's Search Relevancy (Understand Solr's query debug)
Solr's Search Relevancy (Understand Solr's query debug)
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Service
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013
 
Sphinx on Rails
Sphinx on RailsSphinx on Rails
Sphinx on Rails
 
Introduction to R Short course Fall 2016
Introduction to R Short course Fall 2016Introduction to R Short course Fall 2016
Introduction to R Short course Fall 2016
 
Django O/R Mapper
Django O/R MapperDjango O/R Mapper
Django O/R Mapper
 
DEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android ApplicationsDEVIEW2013: Automating Performance Tests for Android Applications
DEVIEW2013: Automating Performance Tests for Android Applications
 
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with RailsSolving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own Domain
 
Effective codereview | Dave Liddament | CODEiD
Effective codereview | Dave Liddament | CODEiDEffective codereview | Dave Liddament | CODEiD
Effective codereview | Dave Liddament | CODEiD
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceships
 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!
 
Android Automated Testing
Android Automated TestingAndroid Automated Testing
Android Automated Testing
 
Don't Repeat Yourself, Repeat Others
Don't Repeat Yourself, Repeat OthersDon't Repeat Yourself, Repeat Others
Don't Repeat Yourself, Repeat Others
 

More from Diaconu Andrei-Tudor

FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up Day
FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up DayFiiPractic 2015 - Adroid Pro - Day 7 - Follow-up Day
FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up DayDiaconu Andrei-Tudor
 
FiiPractic 2015 - Adroid Pro - Day 5 - SQL Day
FiiPractic 2015 - Adroid Pro - Day 5 - SQL DayFiiPractic 2015 - Adroid Pro - Day 5 - SQL Day
FiiPractic 2015 - Adroid Pro - Day 5 - SQL DayDiaconu Andrei-Tudor
 
FiiPractic 2015 - Adroid Pro - Day 3 - API Day
FiiPractic 2015 - Adroid Pro - Day 3 - API DayFiiPractic 2015 - Adroid Pro - Day 3 - API Day
FiiPractic 2015 - Adroid Pro - Day 3 - API DayDiaconu Andrei-Tudor
 
FiiPractic 2015 - Adroid Pro - Day 1 - UI Day
FiiPractic 2015 - Adroid Pro - Day 1 - UI DayFiiPractic 2015 - Adroid Pro - Day 1 - UI Day
FiiPractic 2015 - Adroid Pro - Day 1 - UI DayDiaconu Andrei-Tudor
 

More from Diaconu Andrei-Tudor (7)

ListView vs RecyclerView
ListView vs RecyclerViewListView vs RecyclerView
ListView vs RecyclerView
 
Mobile testing in the cloud
Mobile testing in the cloudMobile testing in the cloud
Mobile testing in the cloud
 
Prezentarea ta mai buna
Prezentarea ta mai bunaPrezentarea ta mai buna
Prezentarea ta mai buna
 
FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up Day
FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up DayFiiPractic 2015 - Adroid Pro - Day 7 - Follow-up Day
FiiPractic 2015 - Adroid Pro - Day 7 - Follow-up Day
 
FiiPractic 2015 - Adroid Pro - Day 5 - SQL Day
FiiPractic 2015 - Adroid Pro - Day 5 - SQL DayFiiPractic 2015 - Adroid Pro - Day 5 - SQL Day
FiiPractic 2015 - Adroid Pro - Day 5 - SQL Day
 
FiiPractic 2015 - Adroid Pro - Day 3 - API Day
FiiPractic 2015 - Adroid Pro - Day 3 - API DayFiiPractic 2015 - Adroid Pro - Day 3 - API Day
FiiPractic 2015 - Adroid Pro - Day 3 - API Day
 
FiiPractic 2015 - Adroid Pro - Day 1 - UI Day
FiiPractic 2015 - Adroid Pro - Day 1 - UI DayFiiPractic 2015 - Adroid Pro - Day 1 - UI Day
FiiPractic 2015 - Adroid Pro - Day 1 - UI Day
 

Performance tools Droidcon Eastern Europe

  • 5. Andrei Diaconu • Cofounder of Android Iași
  • 6. Andrei Diaconu • Cofounder of Android Iași • 5 years of Android
  • 7. Andrei Diaconu • Cofounder of Android Iași • 5 years of Android • Trainer & Speaker
  • 9. Why is my app dropping below 60fps?
  • 10. Why is my app dropping below 60fps? Why is my app draining the battery?
  • 11. Why is my app dropping below 60fps?
  • 12. Why is my app dropping below 60fps?
  • 13. Why is my app dropping below 60fps? • Simple list
  • 14. Why is my app dropping below 60fps? • Simple list • Items have some text
  • 15. Why is my app dropping below 60fps? • Simple list • Items have some text
  • 16. Why is my app dropping below 60fps? • Simple list • Items have some text • Scroll is not smooth
  • 17. • Scroll is not smooth
  • 18. • Scroll is not smooth Why?
  • 19. • Scroll is not smooth Why? Can we make sure?
  • 20. • Scroll is not smooth Why? Can we make sure?
  • 21. Can we make sure?
  • 22. Can we make sure?
  • 23. Can we make sure?
  • 24. Can we make sure?
  • 29. Frames 16ms line Time Choreographer: Skipped 34 frames! The application may be doing too much work on its main thread.
  • 32. Traceview • Measure how long each method takes to execute
  • 33. Traceview • Measure how long each method takes to execute • Analyse measurements using Traceview
  • 34. Traceview • Measure how long each method takes to execute
  • 35. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); • Measure how long each method takes to execute
  • 36. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); //Stop in OnPause
 Debug.stopMethodTracing(); • Measure how long each method takes to execute
  • 37. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); //Stop in OnPause
 Debug.stopMethodTracing(); //Grab using adb
 adb pull • Measure how long each method takes to execute
  • 38. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); //Stop in OnPause
 Debug.stopMethodTracing(); //Grab using adb
 adb pull • Measure how long each method takes to execute //Grab using adb
 adb pull /sdcard/bad_list.trace bad_list.trace
  • 39. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); //Stop in OnPause
 Debug.stopMethodTracing(); //Grab using adb
 adb pull • Measure how long each method takes to execute //Needs permission WRITE_EXTERNAL_STORAGE //Grab using adb
 adb pull /sdcard/bad_list.trace bad_list.trace
  • 40. Traceview //Start in OnResume
 Debug.startMethodTracing("bad_list"); //Stop in OnPause
 Debug.stopMethodTracing(); //Grab using adb
 adb pull • Measure how long each method takes to execute //Needs permission WRITE_EXTERNAL_STORAGE //Grab using adb
 adb pull /sdcard/bad_list.trace bad_list.trace
  • 41. Traceview • Measure how long each method takes to execute
  • 42. Traceview • Measure how long each method takes to execute
  • 43. Traceview • Measure how long each method takes to execute • Analyse measurements using Traceview• Analyse measurements using Traceview
  • 44. Traceview • Measure how long each method takes to execute • Analyse measurements using Traceview • Analyse measurements using Traceview
  • 45. Traceview • Measure how long each method takes to execute • Analyse measurements using Traceview • Analyse measurements using Traceview
  • 46. Traceview • Measure how long each method takes to execute • Analyse measurements using Traceview • Analyse measurements using Traceview
  • 58. inflate() 4 x Html.fromHtml()
  • 59. @Override
 public View getView(int position, View convertView, ViewGroup parent) { 
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4)); 
 return view;
 }
  • 60. @Override
 public View getView(int position, View convertView, ViewGroup parent) { 
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4)); 
 return view;
 }
  • 61. @Override
 public View getView(int position, View convertView, ViewGroup parent) { 
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4)); 
 return view;
 }
  • 62. @Override
 public View getView(int position, View convertView, ViewGroup parent) { 
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4)); 
 return view;
 }
  • 63. @Override
 public View getView(int position, View convertView, ViewGroup parent) { 
 No recycling
 
 No View Holder
 
 
 Html.fromHtml is slow 
 return view;
 }
  • 65. But 200ms? Isn't this a bit much?
  • 66. But 200ms? Isn't this a bit much? Method tracking has a big impact itself
  • 73. Systrace It will run for 5 seconds Hit Ok and scroll the list
  • 75. Alert: Inflation during ListView recycling Time spent: 103.545 ms ListView items inflated: 20
  • 81. @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 
 
 
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4));
 
 
 return view;
 }
  • 82. @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 Trace.beginSection("inflating");
 View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_jumpy_list, parent, false);
 Trace.endSection();
 
 Trace.beginSection("noViewHolder");
 TextView text1 = (TextView) view.findViewById(R.id.item_text1);
 TextView text2 = (TextView) view.findViewById(R.id.item_text2);
 TextView text3 = (TextView) view.findViewById(R.id.item_text3);
 TextView text4 = (TextView) view.findViewById(R.id.item_text4);
 Trace.endSection();
 
 String string1 = parent.getContext().getString(R.string.item_number_x, position);
 String string2 = parent.getContext().getString(R.string.item_description);
 String string3 = parent.getContext().getString(R.string.item_details);
 String string4 = parent.getContext().getString(R.string.item_related);
 
 Trace.beginSection("fromHtml");
 text1.setText(Html.fromHtml(string1));
 text2.setText(Html.fromHtml(string2));
 text3.setText(Html.fromHtml(string3));
 text4.setText(Html.fromHtml(string4));
 Trace.endSection();
 
 return view;
 }
  • 90. • obtainView = ~5ms • doFrame = ~20 * obtainView
  • 91. • obtainView = ~5ms • doFrame = ~20 * obtainView • each frame = ~100ms
  • 92. • obtainView = ~5ms • doFrame = ~20 * obtainView • each frame = ~100ms Alert: Inflation during ListView recycling Time spent: 103.545 ms ListView items inflated: 20
  • 94. Why is my app dropping below 60fps?
  • 95. Why is my app dropping below 60fps? Why is my app draining the battery?
  • 96. Why is my app draining the battery?
  • 97. Why is my app draining the battery? What is a wake lock?
  • 98. Why is my app draining the battery?
  • 99. Why is my app draining the battery? Battery Historian 2.0
  • 100. Why is my app draining the battery? Battery Historian 2.0
  • 101. Why is my app draining the battery? Battery Historian 2.0 adb bugreport > bugreport.txt
  • 102. Why is my app draining the battery? Battery Historian 2.0 adb bugreport > bugreport.txt go run battery-historian.go
  • 103. Why is my app draining the battery? Battery Historian 2.0 adb bugreport > bugreport.txt go run battery-historian.go open http://127.0.0.1:9999
  • 120. public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 } public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 }
  • 121. public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 } public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 }
  • 122. public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 } public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 }
  • 123. public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 } public static class UselessWorker {
 Runnable uselessWorker = new Runnable() {
 @Override
 public void run() {
 PowerManager pm = (PowerManager) BadApplication.instance
 .getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = 
 pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "cool wakelock tag");
 wakeLock.acquire();
 
 //Some useless, but hard work
 
 wakeLock.release();
 try {
 Thread.sleep(45 * 1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 } finally {
 work();
 }
 }
 };
 
 private void work() {
 new Thread(uselessWorker, "cool thread name").start();
 }
 }