Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 53

Advanced Android

By: Gilad Garon


Techniques

TheEdge 2010 Android App

Before we begin!
This presentation is based on
TheEdge 2010 Android
Application:
Download it from the Market
Download the source code:
http://code.google.com/p/theedge20
10
/
2

Agenda

UI Design Patterns
I/O Access
Optimizations

UI Design Patterns

UI Design Patterns

A little reminder about:


Activity
Layouts
Intent

UI Design Patterns

Applications are ahead of the


framework
Dashboard
Action Bar
Search Bar
Quick Actions
Flingable List Item

UI Design Patterns

Dashboard
You know what they say about First Impressions...

Dashboard

UI Design Patterns

Dashboard
Introduce your application
Reveal its functionality
Update the user
Just a layout, nothing fancy

UI Design Patterns

Dashboard Components
Action Bar

Functionality Panel

Updates Panel
9

UI Design Patterns

Implementation
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/ap
k/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/background">
<LinearLayout
xmlns:android="http://schemas.android.com/ap
k/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:background="@color/action_bar_backg
round">
<!-- Action Bar Code -->
</LinearLayout>

<LinearLayout
xmlns:android="http://schemas.android.com/apk/
res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<!-- Functionality Panel -->
</LinearLayout>

<LinearLayout
xmlns:android="http://schemas.android.com/apk/
res/android"
android:id="@+id/now_playing"
android:layout_width="fill_parent"
android:layout_height="90dip"
android:orientation="horizontal">
<!-- Update Panel -->
</LinearLayout>
</LinearLayout>

10

UI Design Patterns

Action Bar
Action Bar

11

UI Design Patterns

Action Bar
Improved Title Bar
Persistent across the application
Includes common actions
Navigation Control

12

UI Design Patterns

Implementation
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:background="@color/action_bar_background">
<ImageButton style="@style/action_bar_button"
android:src="@drawable/home_btn_default"
android:onClick="onHomeClick"/>

<ImageView style="@style/action_bar_separator"/>
<TextView style="@style/action_bar_text"
android:text="Sessions"/>

<ImageView style="@style/action_bar_separator"/>
<ImageButton android:id="@+id/search_button"
style="@style/action_bar_button"
android:src="@drawable/search_button"
android:onClick="onSearchClick"/>
</LinearLayout>

13

UI Design Patterns

Search Bar
Search Bar

14

UI Design Patterns

Search Bar
Implement search in your app
Persistent across the application
Can be used with the Action Bar
Multiple search modes
A clearer way to filter results
15

UI Design Patterns

Implementation
Declare your application as
searchable
Declare an activity that handles
the search
Handle the search itself
16

UI Design Patterns

Searchable Configuration
Declare in
<?xml
version="1.0" encoding="utf-8"?>
/res/xml/searchable.xml
<searchable
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="Hint" >
</searchable>

17

UI Design Patterns

Searchable Activity
Declare as Searchable in the AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alphacsp.theedge"
android:versionCode="4"
android:versionName="1.03"
android:installLocation="preferExternal">

<application android:label="TheEdge 2010" android:icon="@drawable/ic_launcher">

<activity android:name=".ui.activities.SearchActivity" android:label="Search"


android:theme="@style/Theme.TheEdge">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
<activity android:name=".ui.activities.AboutActivity" android:label="About
android:theme="@style/Theme.TheEdge"/>

<meta-data android:name="android.app.default_searchable"
android:value=".ui.activities.SearchActivity"/>
</manifest>

18

UI Design Patterns

Searchable Activity
Handle the Query:

public class SearchActivity extends TabActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);

Intent intent = getIntent();


String query = intent.getStringExtra(SearchManager.QUERY);

final TabHost host = getTabHost();

Intent speakersIntent = new Intent(SearchActivity.this, SpeakersActivity.class);


speakersIntent.putExtra(SearchManager.QUERY, query);
host.addTab(host.newTabSpec("Speakers").setIndicator(buildIndicator("Speakers")).setContent(speaker
sIntent));

Intent sessionsIntent = new Intent(SearchActivity.this, SessionsActivity.class);


sessionsIntent.putExtra(SearchManager.QUERY, query);
host.addTab(host.newTabSpec("Sessions").setIndicator(buildIndicator("Sessions")).setContent(sessionsI
ntent));
}

19

UI Design Patterns

Quick Actions
Quick context menu

20

UI Design Patterns

Quick Actions
Contextual actions driven popup
menu
Natural flow to the screen context
Simple and effective
Wow effect
21

UI Design Patterns

Implementation

Not in the SDK


Custom Views
Implementation taken from:
Lorenzs Blog
http://www.londatiga.net/it/how-to
-create-quickaction-dialog-in-andr
oid/
22

UI Design Patterns

Flingable List Item


Flingable context menu

23

UI Design Patterns

Flingable List Item


Contextual actions driven flinged
menu
Natural flow to the screen context
Wow effect

24

UI Design Patterns

Implementation

Major players:
ViewFlipper Layout
GestureDetector
ListAdaptor
ListActivity
25

UI Design Patterns

A few words about ListView


Vertical scrollable view that allows
multiple rows views (List Item)
Uses ListAdapter to populate each List
Item
Recycles Views (So dont cache them!)
Supports different view types
26

UI Design Patterns

ListView Recycler
ListView should not hold N Views.
Use ConvertView in getView method:
@Override
public View getView(int position, View convertView, ViewGroup
parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.speakers_list, parent,
false);
}
//Get your components from the view
final TextView speakerName = (TextView)
convertView.findViewById(R.id.speaker_name);

//Get your item


Speaker speaker = getItem(position);
return convertView;
}

27

UI Design Patterns

ListView Recycler in action

28

UI Design Patterns

ViewFlipper

Allows transition between layouts


Supports animations
<ViewFlipper
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include android:id="@+id/first"
layout="@layout/sessions_list"/>
<include android:id="@+id/second"
layout="@layout/sessions_list_flinged"/>
</ViewFlipper>

29

UI Design Patterns

GestureDetector

Detects various gestures and


events using the supplied
MotionEvents

GestureDetector gestureDetector = new GestureDetector(new


GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
}

@Override
public boolean onDown(MotionEvent e) {
}

@Override
public boolean onSingleTapUp(MotionEvent e) {
}
});

30

UI Design Patterns

Implementation
Read the Source Code
Handles layouts switches
ViewFlipp Handles animations
er

Controls ViewFlipper

ListAdapt Handles gestures detection for the List Item


Handle Buttons presses from View Flipper
or

Handles scrolling detection


ListActivit Handles buttons presses
y

31

I/O Access

32

I/O Access

Types of I/O:
File System
Database
Network

33

I/O Access

Flash I/O
Reading is fast
Writing is slow
Disk space affects performance
Make sure you support External
Storage (Both in installation and
in caches/data)
34

I/O Access

SQLite FTS
Virtual Table that allows Full Text
Search
Produces results significantly
faster than LIKE
Comprehensive syntax

35

I/O Access

Creating FTS table


Similar to creating a regular table:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TheEdge";
public static final String SPEAKERS_TABLE = "speakers";
@Language("SQLite")
private static final String CREATE_SPEAKERS_TABLE = "CREATE VIRTUAL TABLE " + SPEAKERS_TABLE + "
USING fts3 (speaker_name TEXT , bio TEXT, company TEXT, image_uri TEXT)";
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
Log.i(this.getClass().getSimpleName(), "Creating DB");
sqLiteDatabase.execSQL(CREATE_SPEAKERS_TABLE);
}

36

I/O Access

Using:

Use the MATCH keyword:


public List<Session> searchSessions(String query) {
final List<Session> sessionList = new ArrayList<Session>();
final SQLiteDatabase readableDatabase = getReadableDatabase();
final Cursor cursor = readableDatabase.rawQuery("select * from " + SESSIONS_TABLE + " where " +
SESSIONS_TABLE + " match '" + query + "'", null);
if (cursor.moveToFirst()) {
do {
final Session session = new Session();
session.setTopic(cursor.getString(cursor.getColumnIndex("topic")));
session.setPresenter(cursor.getString(cursor.getColumnIndex("presenter")));
session.setSessionAbstract(cursor.getString(cursor.getColumnIndex("abstract")));
sessionList.add(session);
} while (cursor.moveToNext());
}
if (!cursor.isClosed()) {
cursor.close();
}
return sessionList;
}

37

I/O Access

Network
Use a Service
Use Apache HTTPClient not
URLConnection
Dont do it on the UI thread
Parsing can be costly, design your
data structure carefully
38

I/O Access
When using network, remember the following:
Availability:
Always check connectivity with ConnectivityManager.
Performance:
Dont run on the UI Thread, use AsyncTask or Service.
Bandwidth:
Use as little as you can.
Battery drain:
Only use the network when you have to.

39

I/O Access

Activity with separate thread for


Network
Activity.onCreat
e

UI
Threa
d

Fetch data from


Database / Files

UI
Threa
d

Populate
Activity with
persistent data
New
Threa
d

Update UI
Thread with
.updated data

UI
Threa
d

Fetch new data


from network
and persist it

New
Threa
d

Check network
for updates
(MD5 hash / last
modified
header)
40

Optimization

41

Optimization

AsyncTask
Allows you to execute a task without having to manage
thread pools.
Defined by three generic types: Parameters, Progress
and Result.
Has a lifecycle:
onPreExecute Called before running the task.
doInBackground Actual work
onProgressUpdate Callback to update the UI on task
progress
onPostExecute Called after task has ended,
receives the response object
Very smart and easy.

42

Optimization

Lazy Loading your ListView


In order to implment lazy loading, well need
to do the following:
1. Load the ListView an you would normally
do.
2. Create a task to fetch the data, use
AsyncTask or a Service.
3. Change the data on the UI thread.
4. Use notifyDataSetChanged() to let ListView
to update itself.
43

Optimization

Example
public class SpeakersActivity extends ListActivity implements
ServiceListener {

private void fetchImages() {


for (Speaker speaker : speakers) {
SpeakerImageFetcher speakerImageFetcher = new
SpeakerImageFetcher();
speakerImageFetcher.execute(speaker);
}
}

private class SpeakerImageFetcher extends


AsyncTask<Speaker, Void, Void> {

@Override
protected Void doInBackground(Speaker... speakers) {
final Speaker speaker = speakers[0];
final Bitmap bitmap =
dataAccessor.fetchImage(speaker.getImageUrl());
speaker.setSpeakerImage(bitmap);
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
speakersAdapter.notifyDataSetChanged();
}
}
}

44

Optimization

Services
Runs in the background
Is not killed when the application
ends
Running a service is easy
Getting callbacks is a bit awkward
Declare it in your
AndroidManifest.xml
45

Optimization

Services oriented application:


SQLite

HttpClient

Data Accessor

Service

Service Helper

Activity
46

Optimization

Service Example:
public class NetworkService extends IntentService {

@Override
protected void onHandleIntent(Intent intent) {
final DataAccessor dataAccessor = DataAccessor.getSingleton(this);

final ResultReceiver receiver = intent.getParcelableExtra(STATUS_LISTENER);


final int requestAction = intent.getIntExtra(REFRESH_ACTION, -1);
boolean result = false;

if (requestAction == REFRESH_SPEAKERS) {
result = dataAccessor.syncAllSpeakers();
} else if (requestAction == REFRESH_SESSIONS) {
result = dataAccessor.syncAllSessions();
} else if (requestAction == REFRESH_SCHEDULE) {
result = dataAccessor.syncAllEvents();
} else if (requestAction == REFRESH_ALL) {
dataAccessor.syncAllSpeakers();
dataAccessor.syncAllSessions();
dataAccessor.syncAllEvents();
}
if (result) {
receiver.send(STATUS_REFRESHED, Bundle.EMPTY);
}
receiver.send(STATUS_NOT_REFRESHED, Bundle.EMPTY);
}
}

47

Optimization

Getting a Callback from a Service:


ResultReceiver:
Implements Parcelable, so can be
passed in the Intent object
Good for Here and now results
per intent

48

Optimization

ResultReceiver Example
Accepts the Activity as the Listener using a
custom interface
public class NetworkServiceHelper extends
ResultReceiver {

private final ServiceListener listener;

public NetworkServiceHelper(ServiceListener listener)


{
super(new Handler());
this.listener = listener;
}
@Override
protected void onReceiveResult(int resultCode,
Bundle resultData) {
if (listener != null) {
listener.onReceiveResult(resultCode, resultData);
}
}

49

Optimization

Using the service:


public class ScheduleActivity extends Activity implements ServiceListener {
private NetworkServiceHelper networkServiceHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.schedule_activity);
dataAccessor = DataAccessor.getSingleton(this);
initCalendar();
networkServiceHelper = new NetworkServiceHelper(this);
final Intent serviceIntent = new Intent(Intent.ACTION_SYNC, null, this,
NetworkService.class);
serviceIntent.putExtra(NetworkService.STATUS_LISTENER, networkServiceHelper);
serviceIntent.putExtra(NetworkService.REFRESH_ACTION,
NetworkService.REFRESH_SCHEDULE);
startService(serviceIntent);
}
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
if (resultCode == NetworkService.STATUS_REFRESHED) {
calendarLayout.removeAllViews();
initCalendar();
}
}
}

50

Reference

51

Reference
http://developer.android.com/guide/index.html
http://www.londatiga.net/it/how-to-create-quickacti
on-dialog-in-android
/
http://code.google.com/p/theedge2010/
http://android-developers.blogspot.com/?hl=en
http://
www.google.com/events/io/2010/sessions.html#And
roid
http://www.sqlite.org/fts3.html
http://www.sqlite.org/cvstrac/wiki/wiki?p=FtsUsage

52

Thank You!
We appreciate your feedback

53

You might also like