theedge 2010: android advanced techniques

53
Advanced Android Techniques By: Gilad Garon

Upload: gilad-garon

Post on 17-May-2015

3.589 views

Category:

Technology


0 download

DESCRIPTION

TheEdge 2010:The Android platform has matured rapidly during the last two years.We're going to bring you up to speed in the latest cutting edge Android development techniques including: New UI Patterns, supporting multiple screen resolutions, REST clients, Push applications and optimizing your applications.

TRANSCRIPT

Page 1: TheEdge 2010: Android Advanced Techniques

Advanced Android TechniquesBy: Gilad Garon

Page 2: TheEdge 2010: Android Advanced Techniques

2

» This presentation is based onTheEdge 2010 Android Application: Download it from the Market Download the source code:

http://code.google.com/p/theedge2010/for all the examples in this presentation

Before we begin!

TheEdge 2010 Android App

Page 3: TheEdge 2010: Android Advanced Techniques

3

» UI Design Patterns» I/O Access» Optimizations

Agenda

Page 4: TheEdge 2010: Android Advanced Techniques

UI Design Patterns

Page 5: TheEdge 2010: Android Advanced Techniques

5

» Activity» Layouts» Intent

A little reminder about:

UI Design Patterns

Page 6: TheEdge 2010: Android Advanced Techniques

6

» Dashboard» Action Bar» Search Bar» Quick Actions» Flingable List Item

“Applications are ahead of the framework”

UI Design Patterns

Page 7: TheEdge 2010: Android Advanced Techniques

7

DashboardYou know what they say about First Impressions...

UI Design Patterns

Dashboard

Page 8: TheEdge 2010: Android Advanced Techniques

8

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

Dashboard

UI Design Patterns

Page 9: TheEdge 2010: Android Advanced Techniques

9

Dashboard Components

UI Design Patterns

Action Bar

Updates Panel

Functionality Panel

Page 10: TheEdge 2010: Android Advanced Techniques

10

Implementation

UI Design Patterns

<?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" android:background="@color/background">

<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"> <!-- 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>

Page 11: TheEdge 2010: Android Advanced Techniques

11

Action Bar

UI Design Patterns

Action Bar

Page 12: TheEdge 2010: Android Advanced Techniques

12

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

Action Bar

UI Design Patterns

Page 13: TheEdge 2010: Android Advanced Techniques

13

Implementation

UI Design Patterns

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

Page 14: TheEdge 2010: Android Advanced Techniques

14

Search Bar

UI Design Patterns

Search Bar

Page 15: TheEdge 2010: Android Advanced Techniques

15

» 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

Search Bar

UI Design Patterns

Page 16: TheEdge 2010: Android Advanced Techniques

16

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

Implementation

UI Design Patterns

Page 17: TheEdge 2010: Android Advanced Techniques

17

» Declare in /res/xml/searchable.xml

Searchable Configuration

UI Design Patterns

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

Page 18: TheEdge 2010: Android Advanced Techniques

18

» Declare as Searchable in the AndroidManifest.xml:Searchable Activity

UI Design Patterns

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

Page 19: TheEdge 2010: Android Advanced Techniques

19

» Handle the Query:Searchable Activity

UI Design Patterns

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(speakersIntent)); Intent sessionsIntent = new Intent(SearchActivity.this, SessionsActivity.class); sessionsIntent.putExtra(SearchManager.QUERY, query); host.addTab(host.newTabSpec("Sessions").setIndicator(buildIndicator("Sessions")).setContent(sessionsIntent)); }

Page 20: TheEdge 2010: Android Advanced Techniques

20

Quick ActionsQuick context menu

UI Design Patterns

Page 21: TheEdge 2010: Android Advanced Techniques

21

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

Quick Actions

UI Design Patterns

Page 22: TheEdge 2010: Android Advanced Techniques

22

» Not in the SDK» Custom Views» Implementation taken from: Lorenz’s Blog

http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/

Implementation

UI Design Patterns

Page 23: TheEdge 2010: Android Advanced Techniques

23

Flingable List ItemFlingable context menu

UI Design Patterns

Page 24: TheEdge 2010: Android Advanced Techniques

24

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

Flingable List Item

UI Design Patterns

Page 25: TheEdge 2010: Android Advanced Techniques

25

» Major players: ViewFlipper Layout GestureDetector ListAdaptor ListActivity

Implementation

UI Design Patterns

Page 26: TheEdge 2010: Android Advanced Techniques

26

» Vertical scrollable view that allows multiple rows views (List Item)

» Uses ListAdapter to populate each List Item» Recycles Views (So don’t cache them!)» Supports different view types

A few words about ListView

UI Design Patterns

Page 27: TheEdge 2010: Android Advanced Techniques

27

» ListView should not hold N Views.» Use ConvertView in getView method:

ListView Recycler

UI Design Patterns

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

Page 28: TheEdge 2010: Android Advanced Techniques

28

ListView Recycler in action

UI Design Patterns

Page 29: TheEdge 2010: Android Advanced Techniques

29

ViewFlipper

UI Design Patterns

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

» Allows transition between layouts» Supports animations

Page 30: TheEdge 2010: Android Advanced Techniques

30

GestureDetector

UI Design Patterns

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

» Detects various gestures and events using the supplied MotionEvents

Page 31: TheEdge 2010: Android Advanced Techniques

31

ViewFlipp

er

• Handles layouts switches• Handles animations

ListAdapt

or

• Controls ViewFlipper• Handles gestures detection for the List Item• Handle Buttons presses from View Flipper

ListActivit

y

• Handles scrolling detection• Handles buttons presses

Implementation

UI Design Patterns

Read the Source Code…

Page 32: TheEdge 2010: Android Advanced Techniques

32

I/O Access

Page 33: TheEdge 2010: Android Advanced Techniques

33

» File System» Database» Network

Types of I/O:

I/O Access

Page 34: TheEdge 2010: Android Advanced Techniques

34

» Reading is fast» Writing is slow » Disk space affects performance» Make sure you support External Storage

(Both in installation and in caches/data)

Flash I/O

I/O Access

Page 35: TheEdge 2010: Android Advanced Techniques

35

» Virtual Table that allows Full Text Search» Produces results significantly faster than

LIKE» Comprehensive syntax

SQLite FTS

I/O Access

Page 36: TheEdge 2010: Android Advanced Techniques

36

» Similar to creating a regular table:Creating FTS table

I/O Access

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

}

Page 37: TheEdge 2010: Android Advanced Techniques

37

» Use the MATCH keyword:Using:

I/O Access

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

 

Page 38: TheEdge 2010: Android Advanced Techniques

38

» Use a Service» Use Apache HTTPClient not URLConnection» Don’t do it on the UI thread» Parsing can be costly, design your data

structure carefully

Network

I/O Access

Page 39: TheEdge 2010: Android Advanced Techniques

39

» Availability:Always check connectivity with ConnectivityManager.

» Performance:Don’t 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.

When using network, remember the following:

I/O Access

Page 40: TheEdge 2010: Android Advanced Techniques

40

I/O Access

Activity.onCreate UI Thread

Fetch data from Database / Files

UI Thread

Populate Activity with persistent data

New Thread

Check network for updates (MD5

hash / last modified header)

New Thread

Fetch new data from network and

persist itUI

ThreadUpdate UI Thread with updated data.

Activity with separate thread for Network

Page 41: TheEdge 2010: Android Advanced Techniques

41

Optimization

Page 42: TheEdge 2010: Android Advanced Techniques

42

» 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.

AsyncTask

Optimization

Page 43: TheEdge 2010: Android Advanced Techniques

43

» In order to implment lazy loading, we’ll 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.

Lazy Loading your ListView

Optimization

Page 44: TheEdge 2010: Android Advanced Techniques

44

Example

Optimization

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

Page 45: TheEdge 2010: Android Advanced Techniques

45

» 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

Services

Optimization

Page 46: TheEdge 2010: Android Advanced Techniques

46

Services oriented application:

Optimization

Activity

Service Helper

Service

Data Accessor

SQLite HttpClient

Page 47: TheEdge 2010: Android Advanced Techniques

47

Service Example:

Optimization

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

Page 48: TheEdge 2010: Android Advanced Techniques

48

» ResultReceiver: Implements Parcelable, so can be passed

in the Intent object Good for “Here and now” results per

intent

Getting a Callback from a Service:

Optimization

Page 49: TheEdge 2010: Android Advanced Techniques

49

» Accepts the Activity as the Listener using a custom interface

ResultReceiver Example

Optimization

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

Page 50: TheEdge 2010: Android Advanced Techniques

50

Optimization

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

Using the service:

Page 51: TheEdge 2010: Android Advanced Techniques

51

Reference

Page 53: TheEdge 2010: Android Advanced Techniques

53

Thank You!We appreciate your feedback