How can i optimize my stopwatch in my app to use less cpu?
I am running a stopwatch using an asynctask class in the mainActivity. The doInBackground() method increments the values for the hours, minutes, seconds and centiseconds(10th of a second). The onProgressUpdate() method is responsible for updating 4 imageViews that display the hrs, mins, sec, centisec.
The problem i have is that the stopwatch uses about on average 50%+ cpu usage according to android studio(50% user and 30% kernel usage) and a cpu monitoring app that i installed on the device (2013 HTC one m7). The default android operating system stopwatch uses only about 10% cpu usage. If i use textViews instead of image views the cpu usage drop to half (less than 25%). But it is still more than 10% and i also i want to keep the style of digits im using.
Would caching the images help in anyway? source
I have also considered using XML drawables for the digits instead of bitmaps, but i don't know how effective this will be or if its even possible to create xml drawables of the digits
Lend me your knowledge stackoverflow
main XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#763768"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.example.aroboius.stopwatch.MainActivity"
tools:showIn="@layout/activity_main">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/hoursImage"
android:layout_marginRight="20dp"
android:src="@drawable/digit00" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/minutesImage"
android:layout_marginRight="20dp"
android:src="@drawable/digit00" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/secondsImage"
android:layout_marginRight="20dp"
android:src="@drawable/digit00" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/centiSecondsImage"
android:src="@drawable/digit00" />
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
ImageView hoursIMG, minutesIMG, secondsIMG, centiSecondsIMG;
TextView hoursText, minutesText, secondsText, centicsecondsText;
int centiseconds, seconds, minutes, hours ;
long startMS , endMS , elapsed ;
boolean timerRunning;
String [] digit = {"digit00","digit01","digit02","digit03","digit04","digit05","digit06","digit07","digit08","digit09", "digit10", "digit11","digit12","digit13","digit14","digit15","digit16","digit17","digit18","digit19","digit20", "digit21","digit22","digit23","digit24","digit25","digit26","digit27","digit28","digit29","digit30","digit31",
"digit32","digit33","digit34","digit35","digit36","digit37","digit38","digit39","digit40","digit41","digit42","digit43","digit44","digit45","digit46","digit47","digit48","digit49","digit50","digit51","digit52","digit53",
"digit54","digit55","digit56","digit57","digit58","digit59","digit60","digit61","digit62","digit63","digit64","digit65","digit66","digit67","digit68","digit69","digit70","digit71","digit72","digit73","digit74","digit75",
"digit76","digit77","digit78","digit79","digit80","digit81","digit82","digit83","digit84","digit85","digit86","digit87","digit88","digit89", "digit90","digit91","digit92","digit93","digit94","digit95","digit96","digit97","digit98","digit99"} ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//initializing values
centiseconds = 0; seconds = 0; minutes = 0; hours = 0;
startMS = 0; endMS = 0; elapsed = 0;
hoursIMG = (ImageView) findViewById(R.id.hoursImage);
minutesIMG = (ImageView) findViewById(R.id.minutesImage);
secondsIMG = (ImageView) findViewById(R.id.secondsImage);
centiSecondsIMG = (ImageView) findViewById(R.id.centiSecondsImage);
//start asynctask/stopwatch
timerRunning = true; new asyncTask().execute();
}
class asyncTask extends AsyncTask<Void, Void, Void> {
//initialize a variable to the current system time
@Override
protected void onPreExecute() {
startMS = System.currentTimeMillis();
}
@Override
protected Void doInBackground(Void... params) {
//timerRunning a varible to stop/start the timer
while (timerRunning) {
//initialize a 2nd variable to the current system time
endMS = System.currentTimeMillis();
//get the difference between the 2 time variables
elapsed = endMS - startMS;
//once it is greater than or equal to 100ms increment the centis, mins, secs, hrs
if (elapsed >= 100) {
//reset the starting variable to repeat the process. it also compensating if elapses is greater than 100ms
startMS = endMS - (elapsed - 100);
centiseconds++;
if (centiseconds > 9) {
centiseconds = 0;
seconds++;
if (seconds > 59) {
seconds = 0;
minutes++;
if (minutes > 59) {
minutes = 0;
hours++;
}
}
}
//call method to update the images
publishProgress();
}
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
//get resource IDs for images that represent the values of hrs, mins, secs using the string array created earlier
int hourResID = getResources().getIdentifier(digit[hours], "drawable", getPackageName());
int minResID= getResources().getIdentifier(digit[minutes], "drawable", getPackageName());
int secResID= getResources().getIdentifier(digit [seconds], "drawable", getPackageName());
int csecResID= getResources().getIdentifier(digit[centiseconds], "drawable", getPackageName());
//set images of imageViews
centiSecondsIMG.setImageResource(csecResID);
secondsIMG.setImageResource(secResID);
minutesIMG.setImageResource(minResID);
hoursIMG.setImageResource(hourResID);
}
}
}
1: