SlideShare ist ein Scribd-Unternehmen logo
1 von 124
Downloaden Sie, um offline zu lesen
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
Andrei Diaconu
• Cofounder of Android Iași
• 5 years of Android
• Trainer & Speaker
Why is my app dropping below 60fps?
Why is my app dropping below 60fps?
Why is my app draining the battery?
Why is my app dropping below 60fps?
Why is my app dropping below 60fps?
Why is my app dropping below 60fps?
• Simple list
Why is my app dropping below 60fps?
• Simple list
• Items have some text
Why is my app dropping below 60fps?
• Simple list
• Items have some text
Why is my app dropping below 60fps?
• Simple list
• Items have some text
• Scroll is not smooth
• Scroll is not smooth
• Scroll is not smooth
Why?
• Scroll is not smooth
Why?
Can we make sure?
• Scroll is not smooth
Why?
Can we make sure?
Can we make sure?
Can we make sure?
Can we make sure?
Can we make sure?
Frames
Frames
Time
Frames
16ms line
Time
Frames
16ms line
Time
Choreographer: Skipped 34 frames! The application
may be doing too much work on its main thread.
Traceview
Traceview
• Measure how long each method takes to execute
Traceview
• Measure how long each method takes to execute
• Analyse measurements using Traceview
Traceview
• Measure how long each method takes to execute
Traceview
//Start in OnResume

Debug.startMethodTracing("bad_list");
• Measure how long each method takes to execute
Traceview
//Start in OnResume

Debug.startMethodTracing("bad_list");
//Stop in OnPause

Debug.stopMethodTracing();
• Measure how long each method takes to execute
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
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
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
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
Traceview
• Measure how long each method takes to execute
Traceview
• Measure how long each method takes to execute
Traceview
• Measure how long each method takes to execute
• Analyse measurements using Traceview• Analyse measurements using Traceview
Traceview
• Measure how long each method takes to execute
• Analyse measurements using Traceview
• Analyse measurements using Traceview
Traceview
• Measure how long each method takes to execute
• Analyse measurements using Traceview
• Analyse measurements using Traceview
Traceview
• Measure how long each method takes to execute
• Analyse measurements using Traceview
• Analyse measurements using Traceview
~ 2 seconds
~ 200 ms
Adaptor -> getView()
~ 200 ms
inflate()
inflate() 4 x Html.fromHtml()
@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;

}
@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;

}
@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;

}
@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;

}
@Override

public View getView(int position, View convertView, ViewGroup parent) {


No recycling



No View Holder





Html.fromHtml is slow


return view;

}
But 200ms?
Isn't this a bit much?
But 200ms?
Isn't this a bit much?
Method tracking has a big impact itself
Systrace
measure at kernel level
Systrace
Systrace
Systrace
Systrace
Systrace
It will run for 5 seconds
Hit Ok and scroll the list
Alert: Inflation during ListView recycling
Time spent: 103.545 ms
ListView items inflated: 20
@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;

}
@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;

}
inflating
inflating noViewHolder
inflating noViewHolder
fromHtml
• obtainView = ~5ms
• obtainView = ~5ms
• doFrame = ~20 * obtainView
• obtainView = ~5ms
• doFrame = ~20 * obtainView
• each frame = ~100ms
• obtainView = ~5ms
• doFrame = ~20 * obtainView
• each frame = ~100ms
Alert: Inflation during ListView recycling
Time spent: 103.545 ms
ListView items inflated: 20
Why is my app dropping below 60fps?
Why is my app dropping below 60fps?
Why is my app draining the battery?
Why is my app draining the battery?
Why is my app draining the battery?
What is a wake lock?
Why is my app draining the battery?
Why is my app draining the battery?
Battery Historian 2.0
Why is my app draining the battery?
Battery Historian 2.0
Why is my app draining the battery?
Battery Historian 2.0
adb bugreport > bugreport.txt
Why is my app draining the battery?
Battery Historian 2.0
adb bugreport > bugreport.txt
go run battery-historian.go
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
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();

}

}
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();

}

}
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();

}

}
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();

}

}
?
?
Questions
http://j.mp/fps60
http://j.mp/androidiasi

Weitere ähnliche Inhalte

Ähnlich wie 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
 

Ähnlich wie 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
 
Easy R
Easy REasy R
Easy R
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Niamh verma
 
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...wyqazy
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceanilsa9823
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceDelhi Call girls
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Pooja Nehwal
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceanilsa9823
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPsychicRuben LoveSpells
 
9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7Pooja Nehwal
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRnishacall1
 

Kürzlich hochgeladen (9)

Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
 
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
 
9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
 

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
  • 8.
  • 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?
  • 25.
  • 29. Frames 16ms line Time Choreographer: Skipped 34 frames! The application may be doing too much work on its main thread.
  • 30.
  • 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
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 56.
  • 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;
 }
  • 64.
  • 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
  • 67.
  • 73. Systrace It will run for 5 seconds Hit Ok and scroll the list
  • 74.
  • 75. Alert: Inflation during ListView recycling Time spent: 103.545 ms ListView items inflated: 20
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 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;
 }
  • 83.
  • 84.
  • 88.
  • 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
  • 93.
  • 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
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 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();
 }
 }