2. Contents
Why Automated Historical Performance Testing?
kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics
12th Kandroid Conference - www.kandroid.org
2
3. If you can’t measure it,
you can’t manage it.
Peter F. Drucker
(1909~2005)
12th Kandroid Conference - www.kandroid.org
3
4. If you can’t measure it,
you can’t manage it.
Peter F. Drucker
(1909~2005)
If you can’t automate
the measurement of it,
it is difficult to improve it.
12th Kandroid Conference - www.kandroid.org
4
8. Historical Performance Analysis
Why Historical Analysis?
Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org
8
9. Historical Performance Analysis
Why Historical Analysis?
Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org
9
10. Historical Performance Analysis
Why Historical Analysis?
Activity
Navigation
& Lifecycle
Source: Memory and Performance at the 11th Korea Android Conference
12th Kandroid Conference - www.kandroid.org
10
11. How to Track Activity Navigation & Lifecycle?
12th Kandroid Conference - www.kandroid.org
11
12. How to Track Activity Navigation & Lifecycle?
Override onCreate, onStart, …
of your Activity classes
12th Kandroid Conference - www.kandroid.org
12
13. How to Track Activity Navigation & Lifecycle?
Modify android.app.Activity
in the framework
12th Kandroid Conference - www.kandroid.org
13
14. How to Track Activity Navigation & Lifecycle?
Is there a way that does not
require the modification of
an application or framework?
12th Kandroid Conference - www.kandroid.org
14
15. How to Track Activity Navigation & Lifecycle?
Is there a way that does not
require the modification of
an application or framework?
Instrumentation
12th Kandroid Conference - www.kandroid.org
15
17. Android instrumentation is a set of control methods
or "hooks" in the Android system.
These hooks control an Android component
independently of its normal lifecycle.
They also control how Android loads applications.
(http://developer.android.com/tools/testing/testing_android.html)
12th Kandroid Conference - www.kandroid.org
17
18. Contents
Why Automated Historical Performance Testing?
kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics
12th Kandroid Conference - www.kandroid.org
18
19. Historical Analysis w/ kmemtracer
Application
Package
Control
android.test.
Instrumentation
TestRunner
Test
Package
12th Kandroid Conference - www.kandroid.org
19
34. MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...
public MemoryTraceCsvWriter(String[] metricKeys) {
mMetricKeys = metricKeys;
}
...
private void openTraceFile(String filename) {
...
mTraceOut = new PrintStream(new FileOutputStream(traceFile));
...
}
...
Create an instance
with metrics to print
Open a trace file in
the sdcard at init
12th Kandroid Conference - www.kandroid.org
34
35. MemoryTracerCsvWriter$writeTraceSnapshot
public class MemoryTraceCsvWriter implements MemoryTracer.ResultsWriter {
...
public MemoryTraceCsvWriter(String[] metricKeys) {
mMetricKeys = metricKeys;
}
...
private void openTraceFile(String filename) {
...
mTraceOut = new PrintStream(new FileOutputStream(traceFile));
...
}
...
@Override
public void writeTraceSnapshot(Bundle snapshot) {
PrintStream out = mTraceOut;
for (String key : mMetricKeys) {
out.print(snapshot.get(key));
out.print(',');
}
out.println();
out.flush();
}
...
}
12 Kandroid Conference - www.kandroid.org
Create an instance
with metrics to print
Open a trace file in
the sdcard at init
Write snapshot to
a line of the file
th
35
36. How to Use kmemtracer?
12th Kandroid Conference - www.kandroid.org
36
37. How to Use kmemtracer?
1. Create an Android Test Project for the trace package.
12th Kandroid Conference - www.kandroid.org
37
38. How to Use kmemtracer?
1. Create an Android Test Project for the trace package.
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
12th Kandroid Conference - www.kandroid.org
38
39. How to Use kmemtracer?
1. Create an Android Test Project for the trace package.
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the Manifest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.apis.test"
android:versionCode="1"
android:versionName="1.0">
<instrumentation
android:name="org.kandroid.memtracer.MemoryInstrumentation"
android:targetPackage="com.example.android.apis" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher“>
<uses-library android:theme="android.text.runner“>
</application>
</manifest>
12th Kandroid Conference - www.kandroid.org
39
40. How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk
12th Kandroid Conference - www.kandroid.org
40
41. How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk
5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>
adb shell am instrument -e class
com.example.android.apis.ApiDemos
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation
12th Kandroid Conference - www.kandroid.org
41
42. How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk
5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>
adb shell am instrument -e class
com.example.android.apis.ApiDemos
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation
6. Do interact with the application.
12th Kandroid Conference - www.kandroid.org
42
43. How to Use kmemtracer?
4. Install the trace package as well as the application package.
$ adb install –r ApiDemos.apk
$ adb install –r ApiDemosTest.apk
5. Start the instrumentation with ‘am instrument’ in the shell.
$
>
>
>
adb shell am instrument -e class
com.example.android.apis.ApiDemos
com.example.android.apis.tests/
org.kandroid.memtracer.MemoryInstrumentation
6. Do interact with the application.
7. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer.
$ adb pull /sdcard/kmemtracer/kmemtrace.csv .
12th Kandroid Conference - www.kandroid.org
43
44. How to Use kmemtracer?
8. Open the trace file with Excel and create charts.
12th Kandroid Conference - www.kandroid.org
44
45. Contents
Why Automated Historical Performance Testing?
kmemtracer: What and How?
Enhancement I : Automating UI Interaction
Enhancement II: Adding More Performance Metrics
12th Kandroid Conference - www.kandroid.org
45
63. Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest
12th Kandroid Conference - www.kandroid.org
63
64. Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest
2. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosInstrumentTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosInstrumentTest() {
super(ApiDemos.class);
}
12th Kandroid Conference - www.kandroid.org
64
65. Controlling UI Using Instrumentation
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosInstrumentTest --path ApiDemosInstrumentTest
2. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosInstrumentTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosInstrumentTest() {
super(ApiDemos.class);
}
3. Add a test method and launch the activity.
public void testNavigate() {
final ApiDemos apiDemos = getActivity();
...
}
12th Kandroid Conference - www.kandroid.org
65
66. Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate() {
...
12th Kandroid Conference - www.kandroid.org
66
67. Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics
{
Find a view
to control
= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);
12th Kandroid Conference - www.kandroid.org
67
68. Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics
{
Find a view
to control
= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);
apiDemos.runOnUiThread(new Runnable() {
public void run() {
int pos = demoList.getPositionForView(graphicsDemo);
demoList.smoothScrollToPosition(pos);
demoList.setSelection(pos);
demoList.performItemClick(graphicsDemo, pos,
graphicsDemo.getId());
}
});
...
Act on
the view
12th Kandroid Conference - www.kandroid.org
68
69. Controlling UI Using Instrumentation
4. Find and act on a control.
public void testNavigate()
...
final ListView demoList
final View graphicsDemo
assertNotNull("Graphics
{
Find a view
to control
= apiDemos.getListView();
= getChildViewByText(demoList, "Graphics");
demo should exist", graphicsDemo);
apiDemos.runOnUiThread(new Runnable() {
public void run() {
int pos = demoList.getPositionForView(graphicsDemo);
demoList.smoothScrollToPosition(pos);
demoList.setSelection(pos);
demoList.performItemClick(graphicsDemo, pos,
graphicsDemo.getId());
}
});
...
Act on
the view
12th Kandroid Conference - www.kandroid.org
69
70. Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
12th Kandroid Conference - www.kandroid.org
70
71. Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
Iterate through
child views
12th Kandroid Conference - www.kandroid.org
71
72. Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
Log.e(TAG, i + "-th text view is " + textView);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
}
return view;
}
Iterate through
child views
Compare
texts
12th Kandroid Conference - www.kandroid.org
72
73. Controlling UI Using Instrumentation
4. Find and act on a control: getChildViewByText.
private View getChildViewByText(ListView listView, String text) {
View view = null;
int count = listView.getCount();
Log.e(TAG, “no. children = " + count);
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
Log.e(TAG, i + "-th text view is " + textView);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
}
return view;
}
com.example.android.apis.instrument.test.ApiDemosInstrumentTest:
INSTRUMENTATION_RESULT: shortMsg=junit.framework.AssertionFailedError
INSTRUMENTATION_RESULT: longMsg=
junit.framework.AssertionFailedError: OpenGL ES demo should exist
INSTRUMENTATION_CODE: 0
Iterate through
child views
Compare
texts
12th Kandroid Conference - www.kandroid.org
73
74. Controlling UI Using Instrumentation
4. Find and act on a control: Revised getChildViewByText.
private View getChildViewByText(final ListView listView, String text) {
...
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
if (textView == null) {
final int lastPos = listView.getLastVisiblePosition();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
listView.smoothScrollToPosition(lastPos + 5, lastPos);
}
});
getInstrumentation().waitForIdleSync();
i = listView.getFirstVisiblePosition();
}
}
return view;
}
12th Kandroid Conference - www.kandroid.org
74
75. Controlling UI Using Instrumentation
4. Find and act on a control: Revised getChildViewByText.
private View getChildViewByText(final ListView listView, String text) {
...
for (int i = 0; i < count; i++) {
TextView textView = (TextView) listView.getChildAt(i);
if (textView != null && textView.getText().equals(text)) {
view = textView;
break;
}
if (textView == null) {
final int lastPos = listView.getLastVisiblePosition();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
listView.smoothScrollToPosition(lastPos + 5, lastPos);
}
});
getInstrumentation().waitForIdleSync();
i = listView.getFirstVisiblePosition();
}
}
return view;
}
Scroll down
12th Kandroid Conference - www.kandroid.org
75
76. Controlling UI Using Instrumentation
4. Find and act on a control: getPositionForChildViewByText.
private int getPositionForChildViewByText(ListView listView, String text) {
ListAdapter listAdapter = listView.getAdapter();
int count = listAdapter.getCount();
Log.e(TAG, "children: " + count);
for (int i = 0; i < count; i++) {
String itemText = (String) ((Map)listAdapter.getItem(i)).get("title");
Log.e(TAG, i + "-th text item " + itemText);
if (itemText != null && itemText.equals(text)) {
return i;
}
}
return -1;
}
...
final ListView graphicsDemoList = graphicsDemoActivity.getListView();
int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES");
assertTrue("Cannot find OpenGL ES", pos != -1);
...
12th Kandroid Conference - www.kandroid.org
76
77. Controlling UI Using Instrumentation
4. Find and act on a control: getPositionForChildViewByText.
private int getPositionForChildViewByText(ListView listView, String text) {
ListAdapter listAdapter = listView.getAdapter();
int count = listAdapter.getCount();
Log.e(TAG, "children: " + count);
for (int i = 0; i < count; i++) {
String itemText = (String) ((Map)listAdapter.getItem(i)).get("title");
Log.e(TAG, i + "-th text item " + itemText);
if (itemText != null && itemText.equals(text)) {
return i;
}
}
return -1;
}
...
final ListView graphicsDemoList = graphicsDemoActivity.getListView();
int pos = getPositionForChildViewByText(graphicsDemoList, "OpenGL ES");
assertTrue("Cannot find OpenGL ES", pos != -1);
...
12th Kandroid Conference - www.kandroid.org
77
78. Controlling UI Using Instrumentation
5. Monitor a new Activity to launch.
public void testNavigate() {
...
Instrumentation.ActivityMonitor graphicsDemoActivityMonitor =
getInstrumentation().addMonitor(
ApiDemos.class.getName(), null, false);
final ApiDemos graphicsDemoActivity =
(ApiDemos) graphicsDemoActivityMonitor.waitForActivity();
assertNotNull("Graphics Demo (ApiDemos) activity should not be null",
graphicsDemoActivity);
...
12th Kandroid Conference - www.kandroid.org
78
79. Controlling UI Using Instrumentation
5. Monitor a new Activity to launch.
public void testNavigate() {
...
Instrumentation.ActivityMonitor graphicsDemoActivityMonitor =
getInstrumentation().addMonitor(
ApiDemos.class.getName(), null, false);
final ApiDemos graphicsDemoActivity =
(ApiDemos) graphicsDemoActivityMonitor.waitForActivity();
assertNotNull("Graphics Demo (ApiDemos) activity should not be null",
graphicsDemoActivity);
...
6. Iterate step 4 & 5.
12th Kandroid Conference - www.kandroid.org
79
80. Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
12th Kandroid Conference - www.kandroid.org
80
81. Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
8. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.instrument.test/
> android.test.InstrumentationTestRunner
12th Kandroid Conference - www.kandroid.org
81
82. Controlling UI Using Instrumentation
7. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
8. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.instrument.test/
> android.test.InstrumentationTestRunner
$ ant test
12th Kandroid Conference - www.kandroid.org
82
84. Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest
12th Kandroid Conference - www.kandroid.org
84
85. Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest
2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory.
12th Kandroid Conference - www.kandroid.org
85
86. Controlling UI Using Robotium
1. Create an Android Test Project for the test package.
$ android create test-project --main ../ApiDemos
> –-name ApiDemosRobotiumTest --path ApiDemosRobotiumTest
2. Add ‘robotium-solo-<ver>.jar’ in the ‘libs’ directory.
3. Add a test class inheriting ActivityInstrumentationTestCase2.
public class ApiDemosRobotiumTest extends
ActivityInstrumentationTestCase2<ApiDemos> {
...
public ApiDemosRobotiumTest() {
super(ApiDemos.class);
}
...
12th Kandroid Conference - www.kandroid.org
86
87. Controlling UI Using Robotium
4. Create an instance of Solo in the setUp method and
close open activities in the tearDown method.
...
private Solo solo;
...
@Override
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
...
12th Kandroid Conference - www.kandroid.org
87
88. Controlling UI Using Robotium
4. Find and act on a control.
public void testNavigate() {
solo.assertCurrentActivity("Should be on ApiDemos",
ApiDemos.class);
solo.clickOnText("^Graphics$", 1, true);
solo.assertCurrentActivity("Should be on a new ApiDemos",
ApiDemos.class, true);
solo.clickOnText("^OpenGL ES$", 1, true);
solo.assertCurrentActivity("Should be on a new ApiDemos",
ApiDemos.class, true);
solo.clickOnText("^Kube$", 1, true);
solo.assertCurrentActivity("Should be on a Kube",
Kube.class, true);
solo.sleep(3000);
}
12th Kandroid Conference - www.kandroid.org
88
89. Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk
12th Kandroid Conference - www.kandroid.org
89
90. Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk
7. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.robotium.test/
> android.test.InstrumentationTestRunner
12th Kandroid Conference - www.kandroid.org
90
91. Controlling UI Using Robotium
6. Build and Install the test package.
$ cd ApiDemosRobotiumTest
$ ant debug
$ adb install –r bin/ApiDemosRobotiumTest-debug.apk
7. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.robotium.test/
> android.test.InstrumentationTestRunner
$ ant test
12th Kandroid Conference - www.kandroid.org
91
92. Controlling UI Using uiautomator
1. Create an Java Project for the test jar.
12th Kandroid Conference - www.kandroid.org
92
93. Controlling UI Using uiautomator
1. Create an Java Project for the test jar.
2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path.
12th Kandroid Conference - www.kandroid.org
93
94. Controlling UI Using uiautomator
1. Create an Java Project for the test jar.
2. Add ‘android.jar’ and ‘uiautomator.jar’ in the build path.
3. Add a test class inheriting UiAutomatorTestCase.
public class ApiDemosUiAutoTest extends UiAutomatorTestCase {
...
}
12th Kandroid Conference - www.kandroid.org
94
95. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
12th Kandroid Conference - www.kandroid.org
95
96. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
Press home button
12th Kandroid Conference - www.kandroid.org
96
97. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();
12th Kandroid Conference - www.kandroid.org
Press home button
Click ‘All Apps’
button
97
98. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();
Press home button
Click ‘All Apps’
button
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();
Click ‘Apps’ tab
12th Kandroid Conference - www.kandroid.org
98
99. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();
Press home button
Click ‘All Apps’
button
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();
Click ‘Apps’ tab
UiScrollable appList = new UiScrollable(
new UiSelector().scrollable(true));
appList.setAsHorizontalList();
UiObject apiDemos = appList.getChildByText(
new UiSelector().className(TextView.class.getName()), "API Demos");
apiDemos.clickAndWaitForNewWindow();
Click ‘ApiDemos’
icon
12th Kandroid Conference - www.kandroid.org
99
100. Controlling UI Using uiautomator
4. Launch ApiDemos.
public void testNavigate() throws UiObjectNotFoundException {
getUiDevice().pressHome();
UiObject allAppsButton = new UiObject(
new UiSelector().description("Apps"));
allAppsButton.clickAndWaitForNewWindow();
Press home button
Click ‘All Apps’
button
UiObject appsTab = new UiObject(new UiSelector().text("Apps"));
appsTab.click();
Click ‘Apps’ tab
UiScrollable appList = new UiScrollable(
new UiSelector().scrollable(true));
appList.setAsHorizontalList();
UiObject apiDemos = appList.getChildByText(
new UiSelector().className(TextView.class.getName()), "API Demos");
apiDemos.clickAndWaitForNewWindow();
Click ‘ApiDemos’
icon
Validate the launch
of ‘ApiDemos’
UiObject apiDemosPackage = new UiObject(
new UiSelector().packageName("com.example.android.apis"));
assertTrue("Should be on ApiDemos", apiDemosPackage.exists());
...
12th Kandroid Conference - www.kandroid.org
100
101. Controlling UI Using uiautomator
5. Find and act on a control.
...
UiScrollable demoList = new UiScrollable(
new UiSelector().className("android.widget.ListView"));
UiObject graphicsDemo = demoList.getChildByText(
new UiSelector().className(TextView.class.getName()), “Graphics");
graphicsDemo.clickAndWaitForNewWindow();
UiObject alphaBitmapDemo = new UiObject(
new UiSelector().text(“AlphaBitmap"));
assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists());
...
12th Kandroid Conference - www.kandroid.org
101
102. Controlling UI Using uiautomator
5. Find and act on a control.
...
UiScrollable demoList = new UiScrollable(
new UiSelector().className("android.widget.ListView"));
UiObject graphicsDemo = demoList.getChildByText(
new UiSelector().className(TextView.class.getName()), “Graphics");
graphicsDemo.clickAndWaitForNewWindow();
UiObject alphaBitmapDemo = new UiObject(
new UiSelector().text(“AlphaBitmap"));
assertTrue(“AlphaBitmap should be visible", alpahBitmapDemo.exists());
...
6. Iterate step 5.
12th Kandroid Conference - www.kandroid.org
102
103. Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$
android create uitest-project --name ApiDemosUiAutoTest
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build
12th Kandroid Conference - www.kandroid.org
103
104. Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$
android create uitest-project --name ApiDemosUiAutoTest
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build
8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/
12th Kandroid Conference - www.kandroid.org
104
105. Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$
android create uitest-project --name ApiDemosUiAutoTest
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build
8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/
9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest
12th Kandroid Conference - www.kandroid.org
105
106. Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$
android create uitest-project --name ApiDemosUiAutoTest
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build
8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/
9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest
$ ant test
12th Kandroid Conference - www.kandroid.org
106
107. Controlling UI Using uiautomator
7. Compile your test case into a JAR file.
$
>
$
$
android create uitest-project --name ApiDemosUiAutoTest
--target 1 --path ApiDemosUiAutoTest
cd ApiDemosUiAutoTest
ant build
8. Install the jar on your test device.
$ adb push bin/ApiDemosUiAutoTest.jar /data/local/tmp/
9. Run the test and view the test result.
$ adb shell uiautomator runtest ApiDemosUiAutoTest.jar
> –c com.example.android.apis.uiauto.test.ApiDemosUiAutoTest
$ ant test
12th Kandroid Conference - www.kandroid.org
107
109. Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org
109
110. Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org
110
111. Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org
111
112. Doing both Controlling and Tracking
1. Modify org.kandroid.memtracer.MemoryInstrumentation.
public class MemoryInstrumentation extends InstrumentationTestRunner {
...
@Override
public void onCreate(Bundle arguments) {
...
start();
super.onCreate(arguments);
}
@Override
public void onStart() {
String mainActivityName = getMainActivityName();
if (mainActivityName != null && mainActivityName.length() > 0) {
launchMainActivity(getTargetContext().getPackageName(),
getMainActivityName());
} else {
super.onStart();
}
}
...
12th Kandroid Conference - www.kandroid.org
112
113. Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
12th Kandroid Conference - www.kandroid.org
113
114. Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
12th Kandroid Conference - www.kandroid.org
114
115. Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
12th Kandroid Conference - www.kandroid.org
115
116. Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
5. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.instrument.test/
> org.kandroid.memtracer.MemoryInstrumentation
12th Kandroid Conference - www.kandroid.org
116
117. Doing both Controlling and Tracking
2. Add ‘kmemtracer-libs.jar’ in the ‘libs’ directory.
3. Edit the <instrumentation> element in the manifest file.
4. Build and Install the test package.
$ cd ApiDemosInstrumentTest
$ ant debug
$ adb install –r bin/ApiDemosInstrumentTest-debug.apk
5. Run the test and see the result.
$ adb shell am instrument -w
> com.example.android.apis.instrument.test/
> org.kandroid.memtracer.MemoryInstrumentation
6. Pull the trace file ‘kmemtrace.csv’ from /sdcard/kmemtracer.
$ adb pull /sdcard/kmemtracer/kmemtrace.csv .
12th Kandroid Conference - www.kandroid.org
117
142. How ‘dumpsys meminfo’ works?
android.app.ActivityThread.ApplicationThread.dumpMemInfo()
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;
12th Kandroid Conference - www.kandroid.org
142
143. How ‘dumpsys meminfo’ works?
android.app.ActivityThread.ApplicationThread.dumpMemInfo()
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.totalMemory() / 1024;
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;
android.os.Debug.getNativeHeap*()
struct mallinfo info = mallinfo();
(jlong) info.usmblks; // Debug.getNativeHeapSize()
(jlong) info.uordblks; // Debug.getNativeHeapAllocatedSize()
(jlong) info.fordblks; // Debug.getNativeHeapFreeSize()
12th Kandroid Conference - www.kandroid.org
143
144. How ‘dumpsys meminfo’ works?
struct mallinfo {
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
MALLINFO_FIELD_TYPE
};
arena;
ordblks;
smblks;
hblks;
hblkhd;
usmblks;
fsmblks;
uordblks;
fordblks;
keepcost;
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
non-mmapped space allocated from system */
number of free chunks */
always 0 */
always 0 */
space in mmapped regions */
maximum total allocated space */
always 0 */
total allocated space */
total free space */
releasable (via malloc_trim) space */
bioniclibcupstream-dlmallocmalloc.c
2
4
3
1
① Total allocated = uordblks
② Total free = fordblks
③ Footprint = uordblks + fordblks
④ Max footprint = usmblks
12th Kandroid Conference - www.kandroid.org
144
156. How ‘dumpsys cpuinfo’ works?
procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes
and other system information in a hierarchical file-like structure,
providing a more convenient and standardized method for
dynamically accessing process data held in the kernel than
traditional tracing methods or direct access to kernel memory.
http://en.wikipedia.org/wiki/Procfs
12th Kandroid Conference - www.kandroid.org
156
157. How ‘dumpsys cpuinfo’ works?
procfs (or the proc filesystem) is a special filesystem in UNIXlike operating systems that presents information about processes
and other system information in a hierarchical file-like structure,
providing a more convenient and standardized method for
dynamically accessing process data held in the kernel than
traditional tracing methods or direct access to kernel memory.
http://en.wikipedia.org/wiki/Procfs
http://manpages.courier-mta.org/htmlman5/proc.5.html
12th Kandroid Conference - www.kandroid.org
157
182. If you can’t automate
the measurement of it,
it is difficult to improve it.
12th Kandroid Conference - www.kandroid.org
182
183. If you can’t automate
the measurement of it,
it is difficult to improve it.
If you can’t understand
the measurement results,
it is impossible to improve it.
12th Kandroid Conference - www.kandroid.org
183