SlideShare a Scribd company logo
1/82
ANDROID DEVELOPMENT
2/82
ToC
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
3/82
Intro | quick start
• Android SDK (Software Development Kit)
• JDK
• ADT (Android Development Tools, Eclipse IDE plug-in)
4/82
Intro | platform overview
5/82
Intro | platform overview
6/82
Intro | platform overview
• Dalvik VM
– optimised to run on slow-cpu, low-ram, low-power devices
– runs .dex files (not .class/.jar)
– Multiple instances of DVM can run in parallel
7/82
Intro | dvm vs. jvm
• register-based vs. stack-based
– register-based VMs allow for faster execution times, but
– programs are larger when compiled.
• execution environment - multiple vs. single instance
8/82
Intro | java vs. android api
• Since it uses Java compiler, it implicitly supports a set of
Java commands
• Compatible with Java SE5 code
• A subset of Apache Harmony (open source, free Java
implementation)
• Multithreading as time-slicng.
• Dalvik implements the keyword synchronized and
java.util.concurrent.* package
• Supports reflexion and finalizers but these are not
recomended
• Does not support
– awt, swing, rmi, applet, ...
9/82
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
10/82
Apps | activity
• Base class mostly for visual components
– extends Activity
– override onCreate
11/82
Apps | activity
/* Example.java */
package uk.ac.ic.doc;
import android.app.Activity;
import android.os.Bundle;
public class Example extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.interface);
}
}
12/82
Apps | activity
/* interface.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<LinearLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
android:orientation=“vertical”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”>
<TextView
android:id=“@+id/componentName”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:text=“Text that will be displayed.”
/>
</LinearLayout>
13/82
Apps | activity
/* Example.java */
package uk.ac.ic.doc;
import android.app.Activity;
import android.os.Bundle;
public class Example extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.interface);
TextView text_view = (TextView)findViewById(R.id.componentName);
}
}
14/82
Apps | activity
/* strings.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<resources xmlns:android=“http://schemas.android.com/apk/res/android”>
<string name=“textRefName”>Text that will be displayed</strings>
</resources>
/* interface.xml */
[...]
<TextView
android:id=“@+id/componentName”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:text=“@string/textRefName”
/>
15/82
Apps | activity
16/82
Apps | activity
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(“key”, value);
outState.putFloatArray(“key2”, value2);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
value = savedInstanceState.getString(“key”);
value2 = savedInstanceState.getFloatArray(“key2”);
}
17/82
Apps | intent
• Allows communication between components
– Message passing
– Bundle
Intent intent = new Intent(CurrentActivity.this, OtherActivity.class);
startActivity(intent);
18/82
Apps | intent
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Button listener
Button btnStart = (Button) findViewById(R.id.btn_start);
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent =
new Intent(CurrentActivity.this, OtherActivity.class);
startActivity(intent);
}
});
}
19/82
Apps | thread
Button btnPlay = (Button) findViewById(R.id.btnPlay);
btnPlay.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
// Main Thread blocks
Thread backgroundMusicThread = new Thread(
new Runnable() {
public void run() {
playMusic();
}
}
);
backgroundMusicThread.start();
}
});
20/82
Apps | handler
• Communication between tasks running in parallel
21/82
Apps | handler
private Handler mHandler = new Handler();
private Color mColor = Color.BLACK;
private Runnable mRefresh = new Runnable() {
public void run() {
mTextViewOnUI.setBackgroundColor(mColor)
}};
private Thread mCompute = new Thread(Runnable() {
public void run() {
while(1){
mColor = cpuIntensiveColorComputation(...);
mHandler.post(mRefresh);
}
}});
public void onCreate(Bundle savedInstanceState) {
mCompute.start();
}
22/82
Apps | service
• Base class for background tasks
– extends Service
– override onCreate
• It’s not
– a separate process
– a separate thread
• It is
– part of the main thread
– a way to update an application when it’s not active
23/82
Apps | service
24/82
Apps | broadcast receiver
• extends BroadcastReceiver
• implements onReceive()
• Waits for a system broadcast to happen to trigger an
event
• OS-generated
– Battery empty
– Camera button pressed
– New app installed
– Wifi connection established
• User-generated
– Start of some calculation
– End of an operation
25/82
Apps | broadcast receiver
public class BRExample extends BroadcastReceiver {
@Override
public void onReceive(Context rcvCtx, Intent rcvIntent) {
if (rcvIntent.getAction().equals(Intent.ACTION_CAMERA_BUTTON)) {
rcvCtx.startService(new Intent(rcvCtx, SomeService.class));
}}}
public class SomeService extends Service {
@Override
public IBinder onBind(Intent arg0) { return null; }
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this,“Camera...”, Toast.LENGTH_LONG).show();}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, “Service done”, Toast.LENGTH_LONG).show();}
}
26/82
Apps | notifications
• Toast
• AlertDialog
• Notification
Toast.makeText(this, “Notification text”, Toast.LENGTH_SHORT).show();
27/82
Apps | manifest
<?xml version=“1.0” encoding=“utf-8”?>
<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“uk.ac.ic.doc” android:versionCode=“1”
android:versionName=“1.0”>
<application android:icon=“@drawable/icon”
android:label=“@string/app_name”>
<activity android:name=“.SampleActivity”
android:label=“@string/activity_title_text_ref”>
<intent-filter>
/* ... */
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion=“3” />
</manifest>
28/82
Apps | resources
• /res
– anim
– drawable
• hdpi
• mdpi
• ldpi
– layout
– values
• arrays.xml
• colors.xml
• strings.xml
– xml
– raw
29/82
Apps | R.java
• Autogenerated, best if not manually edited
• gen/
30/82
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
31/82
Elements and layouts
• dip vs. px
• Component dimesions
– wrap_content
– fill_parent
32/82
Elements and layouts
• Linear Layout
– Shows nested View elements
/* linear.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<LinearLayout android:orientation=“horizontal”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:layout_weight=“1”>
<TextView android:text=“red” />
<TextView android:text=“green” />
</LinearLayout>
<LinearLayout android:orientation=“vertical”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:layout_weight=“1”>
<TextView android:text=“row one” />
</LinearLayout>
33/82
Elements and layouts
• Relative Layout
34/82
Elements and layouts
• Table Layout
– Like the HTML div tag
/* table.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<TableLayout android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:stretchColumns=“1”>
<TableRow>
<TextView android:layout_column=“1”
android:text=“Open...”
android:padding=“3dip” />
<TextView android:text=“Ctrl-O”
android:gravity=“right”
android:padding=“3dip” />
</TableRow>
</TableLayout>
35/82
Elements and layouts
• Grid View
/* grid.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<GridView
android:id=“@+id/gridview”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:columnWidth=“90dp”
android:numColumns=“auto_fit”
android:verticalSpacing=“10dp”
android:horizontalSpacing=“10dp”
android:stretchMode=“columnWidth”
android:gravity=“center”
/>
36/82
Elements and layouts
• Grid View
/* GridExample.java */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new AdapterForGridView(this));
gridview.setOnItemClickListener(
new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int pos, long id) {
Toast.makeText(
GridPrimer.this, "" + pos, Toast.LENGTH_SHORT).show();
}});
}
37/82
Elements and layouts
• Grid View
/* AdapterForGridView.java */
public class AdapterForGridView extends BaseAdapter {
private Context mContext;
public AdapterForGridView(Context c) { mContext = c; }
public int getCount() { return mThumbIDs.length; }
public Object getItem(int position) { return null;}
public long getItemId(int position) { return 0; }
// bad getView implementation
public View getView(int pos, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView.setImageResource(mThumbIDs[pos]);
return imageView;
}
private Integer[] mThumbIDs =
{ R.drawable.img1, R.drawable.img2 /*...*/ };
}
38/82
Elements and layouts
• Tab Layout
/* tab.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<TabHost android:id=“@android:id/tabhost”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”>
<LinearLayout android:orientation=“vertical”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”>
<TabWidget android:id=“@android:id/tabs”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”/>
<FrameLayout
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”/>
</LinearLayout>
</TabHost>
39/82
Elements and layouts
• Tab Layout
/* selector1.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<selector xmlns:android=“http://schemas.android.com/apk/res/android”>
<!– Tab is selected -->
<item android:drawable=“@drawable/ic_tab_1_selected”
android:state_selected=“true” />
<!– Tab not selected -->
<item android:drawable=“@drawable/ic_tab_1_not_selected” />
</selector>
/* selector2.xml */
/* selector3.xml */
40/82
Elements and layouts
• Tab Layout
/* Tab1.java */
public class Tab1 extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText(“This is the Artists tab”);
setContentView(textview);
}
}
/* Tab2.java */
/* Tab3.java */
41/82
Elements and layouts
• Tab Layout
/* TabExample.java */
public class TabExample extends TabActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab);
TabHost tabHost = getTabHost();
//--- tab 1 ---
Intent intent = new Intent().setClass(this, Tab1.class);
TabHost.TabSpec spec = tabHost.newTabSpec(“tab1”).setIndicator(
“Artists”, getResources().getDrawable(R.drawable.selector1))
.setContent(intent);
tabHost.addTab(spec);
//--- tab 1 ---
tabHost.setCurrentTab(2);
}
42/82
Elements and layouts
• List View
/* list_item.xml */
<?xml version=“1.0” encoding=“utf-8”?>
<TextView
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:padding=“10dp”
android:textSize=“16sp” />
43/82
Elements and layouts
• List View
/* ListViewExample.java */
public class ListViewExample extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
R.layout.list_item, COUNTRIES));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}});
}
44/82
Elements and layouts
• Button
• ImageButton
• EditText
• CheckBox
• RadioButton
• ToggleButton
• RatingBar
45/82
Elements and layouts
• DatePicker
• TimePicker
• Spinner
• AutoComplete
• Gallery
• MapView
• WebView
46/82
Events
• Event Handler
– Hardware buttons
• Event Listener
– Touch screen
47/82
Events
• KeyEvent is sent to callback methods
– onKeyUp(), onKeyDown(), onKeyLongpress()
– onTrackballEvent(), onTouchEvent()
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_CAMERA) {
return true; // consumes the event
}
return super.onKeyDown(keyCode, event);
}
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { /* ... */ }
});
48/82
Events
public class TouchExample extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) { /*...*/ }
});
button.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
// ...
return true;
}
});
}
}
49/82
Menus
• Options Menu: MENU button, tied to an Activity
• Context Menu: View LongPress
• Submenu
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_ADD, 0, “Add”)
.setIcon(R.drawable.icon);
menu.add(0, MENU_WALLPAPER, 0, “Wallpaper”);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case MENU_ADD: //... ; return true;
case MENU_WALLPAPER: //... ; return true;
default: return false;
}
}
public void onCreate(Bundle savedInstanceState) {
registerForContextMenu((View)findViewById(/*...*/));
}
public void onCreateContextMenu(ContextMenu menu, View
v, ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, MENU_SMS, 0, “SMS”);
menu.add(0, MENU_EMAIL, 0, “Email”);
}
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) { case MENU_SMS: /*...*/ }
}
50/82
Widget
• XML Layout
• AppWidgetProvider gets notified
• Dimensions and refresh frequency
51/82
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
52/82
More on API | 2D
Bitmap image;
image = BitmapFactory.decodeResource(getResources(),R.drawable.image1);
// getPixel(), setPixel()
image = BitmapFactory.decodeFile(“path/to/image/on/SDcard”);
// Environment.getExternalStorageDirectory().getAbsolutePath()
53/82
More on API | 2D
public class MyGUIcomponent extends View {
private Paint paint;
public MyGUIcomponent(Context c){
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(25);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(“some text”, 5, 30, paint);
}
@Override
protected void onMeasure(int w, int h){
// w = ...; h = ...;
setMeasuredDimension(w, h);
}
}
54/82
More on API | 3D
• OpenGL library
• Camera, matrices, transformations, ...
• View animation
55/82
More on API | audio/video
<uses-permission android:name=“android.permission.RECORD_VIDEO” />
56/82
More on API | hardware
• Camera
• Phone
• Sensors
• WiFi
• Bluetooth
• GPS (Location services/Maps)
57/82
More on API | sensors
• Accelerometer
• Thermometer
• Compass
• Light sensor
• Barometer
• Proximity sensor
58/82
More on API | sensors
• A list of all sensors
– getSensorList()
• Control class
– SensorManager
• Callback methods
– onSensorChanged()
– onAccuracyChanged()
59/82
More on API | sensors
private void initAccel(){
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSens = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSens,
SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == SensorManager.SENSOR_ACCELEROMETER) {
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
}
}
60/82
More on API | wifi
<uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE”
/>
private BroadcastReceiver mNetworkReceiver = new BroadcastReceiver(){
public void onReceive(Context c, Intent i){
Bundle b = i.getExtras();
NetworkInfo info =
(NetworkInfo) b.get(ConnectivityManager.EXTRA_NETWORK_INFO);
if(info.isConnected()){
//...
}else{
// no connection
}
}
};
this.registerReceiver(mNetworkReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
61/82
More on API | internet
• Social network apps
• Cloud apps
• Sockets, Datagrams, Http, ...
62/82
More on API | sms
SmsManager mySMS = SmsManager.getDefault();
String to_whom = “+4475...”;
String message_text = “...”;
mojSMS.sendTextMessage(to_whom, null, message_text, null, null);
<uses-permission android:name=“android.permission.SEND_SMS” />
<uses-permission android:name=“android.permission.RECEIVE_SMS” />
ArrayList<String> multiSMS = mySMS.divideMessage(poruka);
mySMS.sendMultipartTextMessage(to_whom, null, multiSMS, null, null);
63/82
More on API | sms
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent in) {
if(in.getAction().equals(RECEIVED_ACTION)) {
Bundle bundle = in.getExtras();
if(bundle!=null) {
Object[] pdus = (Object[])bundle.get(“pdus”);
SmsMessage[] msgs = new SmsMessage[pdus.length];
for(int i = 0; i<pdus.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
}
// reply();
}
}
}};
64/82
More on API | sms
public class ResponderService extends Service {
private static final String RECEIVED_ACTION =
“android.provider.Telephony.SMS_RECEIVED”;
@Override
public void onCreate() {
super.onCreate();
registerReceiver(receiver, new IntentFilter(RECEIVED_ACTION));
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId); }
@Override
public void onDestroy() {
super.onDestroy(); unregisterReceiver(receiver); }
@Override
public IBinder onBind(Intent arg0) { return null; }
}
65/82
More on API | sharedPreferences
• Interface for easy storage of key-value pairs
• Mostly used for saving user settings (language, etc.)
– e.g. username/pass combination for auto-login
• Access to file
– MODE_PRIVATE
– MODE_WORLD_READABLE
– MODE_WORLD_WRITEABLE
66/82
More on API | sharedPreferences
SharedPreferences prefs = getSharedPreferences(“Name”, MODE_PRIVATE);
Editor mEditor = prefs.edit();
mEditor.putString(“username”, username);
mEditor.putString(“password”, password);
mEditor.commit();
SharedPreferences prefs = getSharedPreferences(“Name”, MODE_PRIVATE);
String username = prefs.getString(“username”, “”);
String password = prefs.getString(“password”, “”);
67/82
More on API | sqlite
• Each application has its own DB (can be shared)
• /data/data/<you_package>/databases
• Can
– Create a db
– Open a db
– Create tables
– Insert data into tables
– Fetch data from tables
– Close a db
• Basically, SQL syntax
68/82
More on API | contentProvider
• Since every application is sandboxed, this is Androids
mechanism which relates data across apps
• Required access privileges must be declared in Manifest
and approved by user during installation
69/82
More on API | java.io.File
FileInputStream fis = openFileInput(“some_file.txt”);
FileOutputStream fos = openFileOutput(“some_file.txt”,
Context.MODE_WORLD_WRITEABLE);
Bitmap slika;
FileOutputStream new_profile_image = openFileOutput(“new_image.png”,
Context.MODE_WORLD_WRITEABLE);
slika.compress(CompressFormat.PNG, 100, new_profile_image);
out.flush();
out.close();
InputStream is =
this.getResource().openRawResource(R.raw.some_raw_file);
70/82
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
71/82
Debugging
• gdb
– Since it’s based on Linux, similar command-set
• DDMS through ADT
– Dalvik Debug Monitoring Service
– Android Developer Tools plugin for Eclipse
– Using breakpoints
• Android SDK Debug tools
– ADB (Android Debug Bridge)
– LogCat
– HierarchyViewer
72/82
Debugging | gdb
> adb shell top
> adb shell ps
> gdb mojprogram
> adb logcat
73/82
Debugging | ddms
74/82
Debugging | android debug bridge
• Controlling an emulator instance
> adb start-server
> adb stop-server
75/82
Debugging | LogCat
• Logging app execution
• Real-time logging tool
• Works with tags, priorities and filters
76/82
Debugging | hierarchy viewer
• For “interface debugging”
77/82
4
INTRO1
USER INTERFACE
2
ADDITIONAL API FEATURES
3
DEBUGGING5
OPTIMISATIONS6
ANATOMY OF AN APPLICATION
78/82
Optimisations | in general
• Instancing objects is expensive, avoid if possible
– Overhead from creating, allocation and GC-ing
• Use native methods
– written in C/C++
– around 10-100x faster than user-written in Java by user
• Calls through interfaces are up to 2x slower than virtual
• Declare methods as static if they don’t need access to
object’s fields
• Caching field access results
– counters, etc.
Map myMapa = new HashMap();
HashMap myMapa = new HashMap();
79/82
Optimisations | getView()
• Implemented in Adapter
• Used for:
– Fetching elements from XML
– Their creation in memory (inflate)
– Filling them with valid data
– Returning a ready View element
private static class SomeAdapter extends BaseAdapter {
public SomeAdapter(Context context) {}
public int getCount() { /*...*/ }
public Object getItem(int position) { /*...*/ }
public long getItemId(int position) { /*...*/ }
public View getView(int p, View cv, ViewGroup p) {
// this implementation directly impacts performace
}
}
80/82
Optimisations | getView()
public View getView(int p, View cv, ViewGroup p) {
View element = //... make a new View
element.text = //... get element from XML
element.icon = //... get element from XML
return element;
}
• Creation of a new element gets called each time, and
that is the single most expensive operation when dealing
with UI
81/82
Optimisations | getView()
public View getView(int p, View cv, ViewGroup p) {
if (cv == null) {
cv = //... make a new View
}
cv.text = //... get element from XML
cv.icon = //... get element from XML
return cv;
}
• New element get created only a couple of times
• Performance is acceptable
82/82
Optimisations | getView()
static class ViewHolder {
TextView text;
ImageView icon;
}
public View getView(int p, View cv, ViewGroup p) {
ViewHolder holder;
if (cv == null) {
cv = //... make a new View
holder = new ViewHolder();
holder.text = //... get element from XML
holder.icon = //... get element from XML
cv.setTag(holder);
} else {
holder = (ViewHolder) cv.getTag();
}
return cv;
}

More Related Content

PPT
Android lifecycle
PPTX
Presentation on Android application life cycle and saved instancestate
PPT
android activity
PPTX
Android activity lifecycle
PPT
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
PPTX
The android activity lifecycle
PDF
Android life cycle
PPTX
04 activities and activity life cycle
Android lifecycle
Presentation on Android application life cycle and saved instancestate
android activity
Android activity lifecycle
Android | Android Activity Launch Modes and Tasks | Gonçalo Silva
The android activity lifecycle
Android life cycle
04 activities and activity life cycle

What's hot (18)

PPTX
Activity lifecycle
PDF
Android activity
PPT
Android Basics
PDF
Android development - Activities, Views & Intents
PPTX
Android Life Cycle
PPT
Android activity, service, and broadcast recievers
ODP
Android App Development - 02 Activity and intent
PPTX
Google android Activity lifecycle
ODP
Anatomy of android application
PDF
Android Basic Components
PPTX
Android development session 2 - intent and activity
PPTX
04 activities - Android
DOC
Day 4: Activity lifecycle
DOCX
Activity
PDF
Android Components
PDF
Android activities & views
PDF
Android UI Fundamentals part 1
PDF
[Android] Intent and Activity
Activity lifecycle
Android activity
Android Basics
Android development - Activities, Views & Intents
Android Life Cycle
Android activity, service, and broadcast recievers
Android App Development - 02 Activity and intent
Google android Activity lifecycle
Anatomy of android application
Android Basic Components
Android development session 2 - intent and activity
04 activities - Android
Day 4: Activity lifecycle
Activity
Android Components
Android activities & views
Android UI Fundamentals part 1
[Android] Intent and Activity
Ad

Viewers also liked (19)

PPTX
Applications
PDF
Chain Reactions
PPT
Informatica PowerAnalyzer 4.0 3 of 3
PPTX
Triggers
DOCX
Spm report
PPTX
Extracting data from xml
DOCX
Cloud Computing
PPTX
Android structure
PDF
Relational algebra1
PPT
Informatica PowerAnalyzer 4.0 2 of 3
PPTX
Leadership
DOCX
Job analysis of a reporter
PPT
Dataware housing
PDF
Mendelian Randomisation
PPT
Zackman frame work
PPTX
Introduction to XML
PPT
Data Warehouse
DOCX
Software Testing Tool Report
Applications
Chain Reactions
Informatica PowerAnalyzer 4.0 3 of 3
Triggers
Spm report
Extracting data from xml
Cloud Computing
Android structure
Relational algebra1
Informatica PowerAnalyzer 4.0 2 of 3
Leadership
Job analysis of a reporter
Dataware housing
Mendelian Randomisation
Zackman frame work
Introduction to XML
Data Warehouse
Software Testing Tool Report
Ad

Similar to Android tutorial (2) (20)

PPT
Android training in mumbai
PPT
Android - Anatomy of android elements & layouts
PPT
Android classes in mumbai
PPT
Part 2 android application development 101
PPTX
Technology and Android.pptx
PPTX
Android development beginners faq
PPTX
Android terminologies
PDF
Android internals
PDF
Androidoscon20080721 1216843094441821-9
PDF
Androidoscon20080721 1216843094441821-9
DOCX
Android Basic Tutorial
PDF
Android Jumpstart Jfokus
PPT
Android class provider in mumbai
PPTX
Android Applications Development: A Quick Start Guide
PPTX
Android101 - Intro and Basics
PDF
Android studio
PPT
Pertemuan 3 pm
PDF
Getting Started with Android - OSSPAC 2009
Android training in mumbai
Android - Anatomy of android elements & layouts
Android classes in mumbai
Part 2 android application development 101
Technology and Android.pptx
Android development beginners faq
Android terminologies
Android internals
Androidoscon20080721 1216843094441821-9
Androidoscon20080721 1216843094441821-9
Android Basic Tutorial
Android Jumpstart Jfokus
Android class provider in mumbai
Android Applications Development: A Quick Start Guide
Android101 - Intro and Basics
Android studio
Pertemuan 3 pm
Getting Started with Android - OSSPAC 2009

More from Kumar (20)

PPT
Graphics devices
PPT
Fill area algorithms
PDF
region-filling
PDF
Bresenham derivation
PPT
Bresenham circles and polygons derication
PPTX
Introductionto xslt
PPTX
Xml basics
PPTX
XML Schema
PPTX
Publishing xml
PPTX
DTD
PPTX
Applying xml
PDF
How to deploy a j2ee application
PDF
JNDI, JMS, JPA, XML
PDF
EJB Fundmentals
PDF
JSP and struts programming
PDF
java servlet and servlet programming
PDF
Introduction to JDBC and JDBC Drivers
PDF
Introduction to J2EE
PPT
Sqlite
PPTX
Android animations
Graphics devices
Fill area algorithms
region-filling
Bresenham derivation
Bresenham circles and polygons derication
Introductionto xslt
Xml basics
XML Schema
Publishing xml
DTD
Applying xml
How to deploy a j2ee application
JNDI, JMS, JPA, XML
EJB Fundmentals
JSP and struts programming
java servlet and servlet programming
Introduction to JDBC and JDBC Drivers
Introduction to J2EE
Sqlite
Android animations

Recently uploaded (20)

PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE
PDF
Classroom Observation Tools for Teachers
PDF
RMMM.pdf make it easy to upload and study
PPTX
UV-Visible spectroscopy..pptx UV-Visible Spectroscopy – Electronic Transition...
PDF
Complications of Minimal Access Surgery at WLH
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PPTX
UNIT III MENTAL HEALTH NURSING ASSESSMENT
PDF
2.FourierTransform-ShortQuestionswithAnswers.pdf
PPTX
History, Philosophy and sociology of education (1).pptx
PDF
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
PPTX
202450812 BayCHI UCSC-SV 20250812 v17.pptx
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
What if we spent less time fighting change, and more time building what’s rig...
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PDF
Yogi Goddess Pres Conference Studio Updates
PDF
A systematic review of self-coping strategies used by university students to ...
PDF
RTP_AR_KS1_Tutor's Guide_English [FOR REPRODUCTION].pdf
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
Final Presentation General Medicine 03-08-2024.pptx
LNK 2025 (2).pdf MWEHEHEHEHEHEHEHEHEHEHE
Classroom Observation Tools for Teachers
RMMM.pdf make it easy to upload and study
UV-Visible spectroscopy..pptx UV-Visible Spectroscopy – Electronic Transition...
Complications of Minimal Access Surgery at WLH
Final Presentation General Medicine 03-08-2024.pptx
UNIT III MENTAL HEALTH NURSING ASSESSMENT
2.FourierTransform-ShortQuestionswithAnswers.pdf
History, Philosophy and sociology of education (1).pptx
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
202450812 BayCHI UCSC-SV 20250812 v17.pptx
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
What if we spent less time fighting change, and more time building what’s rig...
Module 4: Burden of Disease Tutorial Slides S2 2025
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Yogi Goddess Pres Conference Studio Updates
A systematic review of self-coping strategies used by university students to ...
RTP_AR_KS1_Tutor's Guide_English [FOR REPRODUCTION].pdf
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student

Android tutorial (2)

  • 2. 2/82 ToC 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 3. 3/82 Intro | quick start • Android SDK (Software Development Kit) • JDK • ADT (Android Development Tools, Eclipse IDE plug-in)
  • 6. 6/82 Intro | platform overview • Dalvik VM – optimised to run on slow-cpu, low-ram, low-power devices – runs .dex files (not .class/.jar) – Multiple instances of DVM can run in parallel
  • 7. 7/82 Intro | dvm vs. jvm • register-based vs. stack-based – register-based VMs allow for faster execution times, but – programs are larger when compiled. • execution environment - multiple vs. single instance
  • 8. 8/82 Intro | java vs. android api • Since it uses Java compiler, it implicitly supports a set of Java commands • Compatible with Java SE5 code • A subset of Apache Harmony (open source, free Java implementation) • Multithreading as time-slicng. • Dalvik implements the keyword synchronized and java.util.concurrent.* package • Supports reflexion and finalizers but these are not recomended • Does not support – awt, swing, rmi, applet, ...
  • 9. 9/82 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 10. 10/82 Apps | activity • Base class mostly for visual components – extends Activity – override onCreate
  • 11. 11/82 Apps | activity /* Example.java */ package uk.ac.ic.doc; import android.app.Activity; import android.os.Bundle; public class Example extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.interface); } }
  • 12. 12/82 Apps | activity /* interface.xml */ <?xml version=“1.0” encoding=“utf-8”?> <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android” android:orientation=“vertical” android:layout_width=“fill_parent” android:layout_height=“fill_parent”> <TextView android:id=“@+id/componentName” android:layout_width=“fill_parent” android:layout_height=“wrap_content” android:text=“Text that will be displayed.” /> </LinearLayout>
  • 13. 13/82 Apps | activity /* Example.java */ package uk.ac.ic.doc; import android.app.Activity; import android.os.Bundle; public class Example extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.interface); TextView text_view = (TextView)findViewById(R.id.componentName); } }
  • 14. 14/82 Apps | activity /* strings.xml */ <?xml version=“1.0” encoding=“utf-8”?> <resources xmlns:android=“http://schemas.android.com/apk/res/android”> <string name=“textRefName”>Text that will be displayed</strings> </resources> /* interface.xml */ [...] <TextView android:id=“@+id/componentName” android:layout_width=“fill_parent” android:layout_height=“wrap_content” android:text=“@string/textRefName” />
  • 16. 16/82 Apps | activity @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(“key”, value); outState.putFloatArray(“key2”, value2); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); value = savedInstanceState.getString(“key”); value2 = savedInstanceState.getFloatArray(“key2”); }
  • 17. 17/82 Apps | intent • Allows communication between components – Message passing – Bundle Intent intent = new Intent(CurrentActivity.this, OtherActivity.class); startActivity(intent);
  • 18. 18/82 Apps | intent @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Button listener Button btnStart = (Button) findViewById(R.id.btn_start); btnStart.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Intent intent = new Intent(CurrentActivity.this, OtherActivity.class); startActivity(intent); } }); }
  • 19. 19/82 Apps | thread Button btnPlay = (Button) findViewById(R.id.btnPlay); btnPlay.setOnClickListener(new View.OnClickListener() { public void onClick(View view){ // Main Thread blocks Thread backgroundMusicThread = new Thread( new Runnable() { public void run() { playMusic(); } } ); backgroundMusicThread.start(); } });
  • 20. 20/82 Apps | handler • Communication between tasks running in parallel
  • 21. 21/82 Apps | handler private Handler mHandler = new Handler(); private Color mColor = Color.BLACK; private Runnable mRefresh = new Runnable() { public void run() { mTextViewOnUI.setBackgroundColor(mColor) }}; private Thread mCompute = new Thread(Runnable() { public void run() { while(1){ mColor = cpuIntensiveColorComputation(...); mHandler.post(mRefresh); } }}); public void onCreate(Bundle savedInstanceState) { mCompute.start(); }
  • 22. 22/82 Apps | service • Base class for background tasks – extends Service – override onCreate • It’s not – a separate process – a separate thread • It is – part of the main thread – a way to update an application when it’s not active
  • 24. 24/82 Apps | broadcast receiver • extends BroadcastReceiver • implements onReceive() • Waits for a system broadcast to happen to trigger an event • OS-generated – Battery empty – Camera button pressed – New app installed – Wifi connection established • User-generated – Start of some calculation – End of an operation
  • 25. 25/82 Apps | broadcast receiver public class BRExample extends BroadcastReceiver { @Override public void onReceive(Context rcvCtx, Intent rcvIntent) { if (rcvIntent.getAction().equals(Intent.ACTION_CAMERA_BUTTON)) { rcvCtx.startService(new Intent(rcvCtx, SomeService.class)); }}} public class SomeService extends Service { @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { super.onCreate(); Toast.makeText(this,“Camera...”, Toast.LENGTH_LONG).show();} @Override public void onDestroy() { super.onDestroy(); Toast.makeText(this, “Service done”, Toast.LENGTH_LONG).show();} }
  • 26. 26/82 Apps | notifications • Toast • AlertDialog • Notification Toast.makeText(this, “Notification text”, Toast.LENGTH_SHORT).show();
  • 27. 27/82 Apps | manifest <?xml version=“1.0” encoding=“utf-8”?> <manifest xmlns:android=“http://schemas.android.com/apk/res/android” package=“uk.ac.ic.doc” android:versionCode=“1” android:versionName=“1.0”> <application android:icon=“@drawable/icon” android:label=“@string/app_name”> <activity android:name=“.SampleActivity” android:label=“@string/activity_title_text_ref”> <intent-filter> /* ... */ </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion=“3” /> </manifest>
  • 28. 28/82 Apps | resources • /res – anim – drawable • hdpi • mdpi • ldpi – layout – values • arrays.xml • colors.xml • strings.xml – xml – raw
  • 29. 29/82 Apps | R.java • Autogenerated, best if not manually edited • gen/
  • 30. 30/82 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 31. 31/82 Elements and layouts • dip vs. px • Component dimesions – wrap_content – fill_parent
  • 32. 32/82 Elements and layouts • Linear Layout – Shows nested View elements /* linear.xml */ <?xml version=“1.0” encoding=“utf-8”?> <LinearLayout android:orientation=“horizontal” android:layout_width=“fill_parent” android:layout_height=“fill_parent” android:layout_weight=“1”> <TextView android:text=“red” /> <TextView android:text=“green” /> </LinearLayout> <LinearLayout android:orientation=“vertical” android:layout_width=“fill_parent” android:layout_height=“fill_parent” android:layout_weight=“1”> <TextView android:text=“row one” /> </LinearLayout>
  • 34. 34/82 Elements and layouts • Table Layout – Like the HTML div tag /* table.xml */ <?xml version=“1.0” encoding=“utf-8”?> <TableLayout android:layout_width=“fill_parent” android:layout_height=“fill_parent” android:stretchColumns=“1”> <TableRow> <TextView android:layout_column=“1” android:text=“Open...” android:padding=“3dip” /> <TextView android:text=“Ctrl-O” android:gravity=“right” android:padding=“3dip” /> </TableRow> </TableLayout>
  • 35. 35/82 Elements and layouts • Grid View /* grid.xml */ <?xml version=“1.0” encoding=“utf-8”?> <GridView android:id=“@+id/gridview” android:layout_width=“fill_parent” android:layout_height=“fill_parent” android:columnWidth=“90dp” android:numColumns=“auto_fit” android:verticalSpacing=“10dp” android:horizontalSpacing=“10dp” android:stretchMode=“columnWidth” android:gravity=“center” />
  • 36. 36/82 Elements and layouts • Grid View /* GridExample.java */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.grid); GridView gridview = (GridView) findViewById(R.id.gridview); gridview.setAdapter(new AdapterForGridView(this)); gridview.setOnItemClickListener( new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View v, int pos, long id) { Toast.makeText( GridPrimer.this, "" + pos, Toast.LENGTH_SHORT).show(); }}); }
  • 37. 37/82 Elements and layouts • Grid View /* AdapterForGridView.java */ public class AdapterForGridView extends BaseAdapter { private Context mContext; public AdapterForGridView(Context c) { mContext = c; } public int getCount() { return mThumbIDs.length; } public Object getItem(int position) { return null;} public long getItemId(int position) { return 0; } // bad getView implementation public View getView(int pos, View convertView, ViewGroup parent) { ImageView imageView = new ImageView(mContext); imageView.setImageResource(mThumbIDs[pos]); return imageView; } private Integer[] mThumbIDs = { R.drawable.img1, R.drawable.img2 /*...*/ }; }
  • 38. 38/82 Elements and layouts • Tab Layout /* tab.xml */ <?xml version=“1.0” encoding=“utf-8”?> <TabHost android:id=“@android:id/tabhost” android:layout_width=“fill_parent” android:layout_height=“fill_parent”> <LinearLayout android:orientation=“vertical” android:layout_width=“fill_parent” android:layout_height=“fill_parent”> <TabWidget android:id=“@android:id/tabs” android:layout_width=“fill_parent” android:layout_height=“wrap_content”/> <FrameLayout android:layout_width=“fill_parent” android:layout_height=“fill_parent”/> </LinearLayout> </TabHost>
  • 39. 39/82 Elements and layouts • Tab Layout /* selector1.xml */ <?xml version=“1.0” encoding=“utf-8”?> <selector xmlns:android=“http://schemas.android.com/apk/res/android”> <!– Tab is selected --> <item android:drawable=“@drawable/ic_tab_1_selected” android:state_selected=“true” /> <!– Tab not selected --> <item android:drawable=“@drawable/ic_tab_1_not_selected” /> </selector> /* selector2.xml */ /* selector3.xml */
  • 40. 40/82 Elements and layouts • Tab Layout /* Tab1.java */ public class Tab1 extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView textview = new TextView(this); textview.setText(“This is the Artists tab”); setContentView(textview); } } /* Tab2.java */ /* Tab3.java */
  • 41. 41/82 Elements and layouts • Tab Layout /* TabExample.java */ public class TabExample extends TabActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tab); TabHost tabHost = getTabHost(); //--- tab 1 --- Intent intent = new Intent().setClass(this, Tab1.class); TabHost.TabSpec spec = tabHost.newTabSpec(“tab1”).setIndicator( “Artists”, getResources().getDrawable(R.drawable.selector1)) .setContent(intent); tabHost.addTab(spec); //--- tab 1 --- tabHost.setCurrentTab(2); }
  • 42. 42/82 Elements and layouts • List View /* list_item.xml */ <?xml version=“1.0” encoding=“utf-8”?> <TextView android:layout_width=“fill_parent” android:layout_height=“fill_parent” android:padding=“10dp” android:textSize=“16sp” />
  • 43. 43/82 Elements and layouts • List View /* ListViewExample.java */ public class ListViewExample extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES)); ListView lv = getListView(); lv.setTextFilterEnabled(true); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); }}); }
  • 44. 44/82 Elements and layouts • Button • ImageButton • EditText • CheckBox • RadioButton • ToggleButton • RatingBar
  • 45. 45/82 Elements and layouts • DatePicker • TimePicker • Spinner • AutoComplete • Gallery • MapView • WebView
  • 46. 46/82 Events • Event Handler – Hardware buttons • Event Listener – Touch screen
  • 47. 47/82 Events • KeyEvent is sent to callback methods – onKeyUp(), onKeyDown(), onKeyLongpress() – onTrackballEvent(), onTouchEvent() public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_CAMERA) { return true; // consumes the event } return super.onKeyDown(keyCode, event); } Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { /* ... */ } });
  • 48. 48/82 Events public class TouchExample extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { /*...*/ } }); button.setOnLongClickListener(new OnLongClickListener() { public boolean onLongClick(View v) { // ... return true; } }); } }
  • 49. 49/82 Menus • Options Menu: MENU button, tied to an Activity • Context Menu: View LongPress • Submenu public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, MENU_ADD, 0, “Add”) .setIcon(R.drawable.icon); menu.add(0, MENU_WALLPAPER, 0, “Wallpaper”); return super.onCreateOptionsMenu(menu); } public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case MENU_ADD: //... ; return true; case MENU_WALLPAPER: //... ; return true; default: return false; } } public void onCreate(Bundle savedInstanceState) { registerForContextMenu((View)findViewById(/*...*/)); } public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, MENU_SMS, 0, “SMS”); menu.add(0, MENU_EMAIL, 0, “Email”); } public boolean onContextItemSelected(MenuItem item) { switch(item.getItemId()) { case MENU_SMS: /*...*/ } }
  • 50. 50/82 Widget • XML Layout • AppWidgetProvider gets notified • Dimensions and refresh frequency
  • 51. 51/82 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 52. 52/82 More on API | 2D Bitmap image; image = BitmapFactory.decodeResource(getResources(),R.drawable.image1); // getPixel(), setPixel() image = BitmapFactory.decodeFile(“path/to/image/on/SDcard”); // Environment.getExternalStorageDirectory().getAbsolutePath()
  • 53. 53/82 More on API | 2D public class MyGUIcomponent extends View { private Paint paint; public MyGUIcomponent(Context c){ paint = new Paint(); paint.setColor(Color.WHITE); paint.setTextSize(25); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText(“some text”, 5, 30, paint); } @Override protected void onMeasure(int w, int h){ // w = ...; h = ...; setMeasuredDimension(w, h); } }
  • 54. 54/82 More on API | 3D • OpenGL library • Camera, matrices, transformations, ... • View animation
  • 55. 55/82 More on API | audio/video <uses-permission android:name=“android.permission.RECORD_VIDEO” />
  • 56. 56/82 More on API | hardware • Camera • Phone • Sensors • WiFi • Bluetooth • GPS (Location services/Maps)
  • 57. 57/82 More on API | sensors • Accelerometer • Thermometer • Compass • Light sensor • Barometer • Proximity sensor
  • 58. 58/82 More on API | sensors • A list of all sensors – getSensorList() • Control class – SensorManager • Callback methods – onSensorChanged() – onAccuracyChanged()
  • 59. 59/82 More on API | sensors private void initAccel(){ mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mSens = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mSens, SensorManager.SENSOR_DELAY_GAME); } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == SensorManager.SENSOR_ACCELEROMETER) { float x = event.values[SensorManager.DATA_X]; float y = event.values[SensorManager.DATA_Y]; float z = event.values[SensorManager.DATA_Z]; } }
  • 60. 60/82 More on API | wifi <uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE” /> private BroadcastReceiver mNetworkReceiver = new BroadcastReceiver(){ public void onReceive(Context c, Intent i){ Bundle b = i.getExtras(); NetworkInfo info = (NetworkInfo) b.get(ConnectivityManager.EXTRA_NETWORK_INFO); if(info.isConnected()){ //... }else{ // no connection } } }; this.registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
  • 61. 61/82 More on API | internet • Social network apps • Cloud apps • Sockets, Datagrams, Http, ...
  • 62. 62/82 More on API | sms SmsManager mySMS = SmsManager.getDefault(); String to_whom = “+4475...”; String message_text = “...”; mojSMS.sendTextMessage(to_whom, null, message_text, null, null); <uses-permission android:name=“android.permission.SEND_SMS” /> <uses-permission android:name=“android.permission.RECEIVE_SMS” /> ArrayList<String> multiSMS = mySMS.divideMessage(poruka); mySMS.sendMultipartTextMessage(to_whom, null, multiSMS, null, null);
  • 63. 63/82 More on API | sms BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context c, Intent in) { if(in.getAction().equals(RECEIVED_ACTION)) { Bundle bundle = in.getExtras(); if(bundle!=null) { Object[] pdus = (Object[])bundle.get(“pdus”); SmsMessage[] msgs = new SmsMessage[pdus.length]; for(int i = 0; i<pdus.length; i++) { msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); } // reply(); } } }};
  • 64. 64/82 More on API | sms public class ResponderService extends Service { private static final String RECEIVED_ACTION = “android.provider.Telephony.SMS_RECEIVED”; @Override public void onCreate() { super.onCreate(); registerReceiver(receiver, new IntentFilter(RECEIVED_ACTION)); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); } @Override public IBinder onBind(Intent arg0) { return null; } }
  • 65. 65/82 More on API | sharedPreferences • Interface for easy storage of key-value pairs • Mostly used for saving user settings (language, etc.) – e.g. username/pass combination for auto-login • Access to file – MODE_PRIVATE – MODE_WORLD_READABLE – MODE_WORLD_WRITEABLE
  • 66. 66/82 More on API | sharedPreferences SharedPreferences prefs = getSharedPreferences(“Name”, MODE_PRIVATE); Editor mEditor = prefs.edit(); mEditor.putString(“username”, username); mEditor.putString(“password”, password); mEditor.commit(); SharedPreferences prefs = getSharedPreferences(“Name”, MODE_PRIVATE); String username = prefs.getString(“username”, “”); String password = prefs.getString(“password”, “”);
  • 67. 67/82 More on API | sqlite • Each application has its own DB (can be shared) • /data/data/<you_package>/databases • Can – Create a db – Open a db – Create tables – Insert data into tables – Fetch data from tables – Close a db • Basically, SQL syntax
  • 68. 68/82 More on API | contentProvider • Since every application is sandboxed, this is Androids mechanism which relates data across apps • Required access privileges must be declared in Manifest and approved by user during installation
  • 69. 69/82 More on API | java.io.File FileInputStream fis = openFileInput(“some_file.txt”); FileOutputStream fos = openFileOutput(“some_file.txt”, Context.MODE_WORLD_WRITEABLE); Bitmap slika; FileOutputStream new_profile_image = openFileOutput(“new_image.png”, Context.MODE_WORLD_WRITEABLE); slika.compress(CompressFormat.PNG, 100, new_profile_image); out.flush(); out.close(); InputStream is = this.getResource().openRawResource(R.raw.some_raw_file);
  • 70. 70/82 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 71. 71/82 Debugging • gdb – Since it’s based on Linux, similar command-set • DDMS through ADT – Dalvik Debug Monitoring Service – Android Developer Tools plugin for Eclipse – Using breakpoints • Android SDK Debug tools – ADB (Android Debug Bridge) – LogCat – HierarchyViewer
  • 72. 72/82 Debugging | gdb > adb shell top > adb shell ps > gdb mojprogram > adb logcat
  • 74. 74/82 Debugging | android debug bridge • Controlling an emulator instance > adb start-server > adb stop-server
  • 75. 75/82 Debugging | LogCat • Logging app execution • Real-time logging tool • Works with tags, priorities and filters
  • 76. 76/82 Debugging | hierarchy viewer • For “interface debugging”
  • 77. 77/82 4 INTRO1 USER INTERFACE 2 ADDITIONAL API FEATURES 3 DEBUGGING5 OPTIMISATIONS6 ANATOMY OF AN APPLICATION
  • 78. 78/82 Optimisations | in general • Instancing objects is expensive, avoid if possible – Overhead from creating, allocation and GC-ing • Use native methods – written in C/C++ – around 10-100x faster than user-written in Java by user • Calls through interfaces are up to 2x slower than virtual • Declare methods as static if they don’t need access to object’s fields • Caching field access results – counters, etc. Map myMapa = new HashMap(); HashMap myMapa = new HashMap();
  • 79. 79/82 Optimisations | getView() • Implemented in Adapter • Used for: – Fetching elements from XML – Their creation in memory (inflate) – Filling them with valid data – Returning a ready View element private static class SomeAdapter extends BaseAdapter { public SomeAdapter(Context context) {} public int getCount() { /*...*/ } public Object getItem(int position) { /*...*/ } public long getItemId(int position) { /*...*/ } public View getView(int p, View cv, ViewGroup p) { // this implementation directly impacts performace } }
  • 80. 80/82 Optimisations | getView() public View getView(int p, View cv, ViewGroup p) { View element = //... make a new View element.text = //... get element from XML element.icon = //... get element from XML return element; } • Creation of a new element gets called each time, and that is the single most expensive operation when dealing with UI
  • 81. 81/82 Optimisations | getView() public View getView(int p, View cv, ViewGroup p) { if (cv == null) { cv = //... make a new View } cv.text = //... get element from XML cv.icon = //... get element from XML return cv; } • New element get created only a couple of times • Performance is acceptable
  • 82. 82/82 Optimisations | getView() static class ViewHolder { TextView text; ImageView icon; } public View getView(int p, View cv, ViewGroup p) { ViewHolder holder; if (cv == null) { cv = //... make a new View holder = new ViewHolder(); holder.text = //... get element from XML holder.icon = //... get element from XML cv.setTag(holder); } else { holder = (ViewHolder) cv.getTag(); } return cv; }