• Like
  • Save
TheEdge 2010: Android Advanced Techniques
Upcoming SlideShare
Loading in...5
×
 

TheEdge 2010: Android Advanced Techniques

on

  • 3,766 views

TheEdge 2010:...

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.

Statistics

Views

Total Views
3,766
Views on SlideShare
3,763
Embed Views
3

Actions

Likes
3
Downloads
200
Comments
0

1 Embed 3

http://www.linkedin.com 3

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Present as a story:Designing smart and cool UIThe work behind to UI – I/OAnd how to make it all work fast
  • What is an activity: each screen is an activityA screen is defined by a layout, a layout could be an XML or Code. Explain why XML is better than code, and some Layout types.Intent is a way of describing of you want the android OS to do.
  • When mentioninggoogle IO mention what is it
  • Your application Home Screen
  • The first screen the user sees
  • Explain in short what’s a LinearLayout
  • Voice search, suggestion, global search
  • (Don’t believe the emulator!)
  • Why rawQuery? Query method has too many parameters, they should use a builder…

TheEdge 2010: Android Advanced Techniques TheEdge 2010: Android Advanced Techniques Presentation Transcript

  • Advanced Android Techniques
    By: GiladGaron
  • 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
  • UI Design Patterns
    I/O Access
    Optimizations
    Agenda
  • UI Design Patterns
  • Activity
    Layouts
    Intent
    A little reminder about:
    UI Design Patterns
  • Dashboard
    Action Bar
    Search Bar
    Quick Actions
    Flingable List Item
    “Applications are ahead of the framework”
    UI Design Patterns
  • Dashboard
    You know what they say about First Impressions...
    UI Design Patterns
    Dashboard
  • Introduce your application
    Reveal its functionality
    Update the user
    Just a layout, nothing fancy
    Dashboard
    UI Design Patterns
  • Dashboard Components
    UI Design Patterns
    Action Bar
    Updates Panel
    Functionality Panel
  • Implementation
    UI Design Patterns
    <?xmlversion="1.0"encoding="utf-8"?>
    <LinearLayoutxmlns: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">
    <LinearLayoutxmlns: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>
     
    <LinearLayoutxmlns: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>
     
    <LinearLayoutxmlns: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>
  • Action Bar
    UI Design Patterns
    Action Bar
  • Improved Title Bar
    Persistent across the application
    Includes common actions
    Navigation Control
    Action Bar
    UI Design Patterns
  • Implementation
    UI Design Patterns
    <LinearLayoutxmlns: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">
    <ImageButtonstyle="@style/action_bar_button"
    android:src="@drawable/home_btn_default"
    android:onClick="onHomeClick"/>
     
    <ImageViewstyle="@style/action_bar_separator"/>
    <TextViewstyle="@style/action_bar_text"
    android:text="Sessions"/>
     
    <ImageViewstyle="@style/action_bar_separator"/>
    <ImageButtonandroid:id="@+id/search_button"
    style="@style/action_bar_button"
    android:src="@drawable/search_button"
    android:onClick="onSearchClick"/>
    </LinearLayout>
  • Search Bar
    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
    Search Bar
    UI Design Patterns
  • Declare your application as searchable
    Declare an activity that handles the search
    Handle the search itself
    Implementation
    UI Design Patterns
  • Declare in /res/xml/searchable.xml
    Searchable Configuration
    UI Design Patterns
    <?xmlversion="1.0"encoding="utf-8"?>
    <searchablexmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="Hint" >
    </searchable>
  • Searchable Activity
    Declare as Searchable in the AndroidManifest.xml:
    UI Design Patterns
    <manifestxmlns:android="http://schemas.android.com/apk/res/android"
    package="com.alphacsp.theedge"
    android:versionCode="4"
    android:versionName="1.03"
    android:installLocation="preferExternal">
     
    <applicationandroid:label="TheEdge 2010"android:icon="@drawable/ic_launcher">
     
    <activityandroid:name=".ui.activities.SearchActivity"android:label="Search"android:theme="@style/Theme.TheEdge">
    <intent-filter>
    <actionandroid:name="android.intent.action.SEARCH"/>
    </intent-filter>
    <meta-dataandroid:name="android.app.searchable"android:resource="@xml/searchable"/>
    </activity>
    <activityandroid:name=".ui.activities.AboutActivity"android:label="About“ android:theme="@style/Theme.TheEdge"/>
     
    <meta-dataandroid:name="android.app.default_searchable"android:value=".ui.activities.SearchActivity"/> 
    </manifest>
  • Searchable Activity
    Handle the Query:
    UI Design Patterns
    publicclassSearchActivityextendsTabActivity {
    @Override
    publicvoidonCreate(BundlesavedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.search_activity);
     
    Intentintent = getIntent();
    String query = intent.getStringExtra(SearchManager.QUERY);
     
    finalTabHost host = getTabHost();
     
    IntentspeakersIntent = new Intent(SearchActivity.this, SpeakersActivity.class);
    speakersIntent.putExtra(SearchManager.QUERY, query);
    host.addTab(host.newTabSpec("Speakers").setIndicator(buildIndicator("Speakers")).setContent(speakersIntent));
     
    IntentsessionsIntent = new Intent(SearchActivity.this, SessionsActivity.class);
    sessionsIntent.putExtra(SearchManager.QUERY, query);
    host.addTab(host.newTabSpec("Sessions").setIndicator(buildIndicator("Sessions")).setContent(sessionsIntent));
    }
  • Quick Actions
    Quick context menu
    UI Design Patterns
  • Contextual actions driven popup menu
    Natural flow to the screen context
    Simple and effective
    Wow effect
    Quick Actions
    UI Design Patterns
  • Not in the SDK
    Custom Views
    Implementation taken from: Lorenz’s Bloghttp://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/
    Implementation
    UI Design Patterns
  • Flingable List Item
    Flingable context menu
    UI Design Patterns
  • Contextual actions driven flinged menu
    Natural flow to the screen context
    Wow effect
    Flingable List Item
    UI Design Patterns
  • Major players:
    ViewFlipper Layout
    GestureDetector
    ListAdaptor
    ListActivity
    Implementation
    UI Design Patterns
  • 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
  • ListView should not hold N Views.
    Use ConvertView in getView method:
    ListView Recycler
    UI Design Patterns
    @Override
    publicViewgetView(int position, ViewconvertView, ViewGroup parent) {
    if (convertView == null) {
    convertView = inflater.inflate(R.layout.speakers_list, parent, false);
    }
    //Get your components from the view
    finalTextViewspeakerName = (TextView) convertView.findViewById(R.id.speaker_name);
     
    //Get your item
    Speakerspeaker = getItem(position);
    returnconvertView;
    }
  • ListView Recycler in action
    UI Design Patterns
  • ViewFlipper
    UI Design Patterns
    Allows transition between layouts
    Supports animations
    <ViewFlipperxmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/flipper"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <includeandroid:id="@+id/first"layout="@layout/sessions_list"/>
    <includeandroid:id="@+id/second"layout="@layout/sessions_list_flinged"/>
    </ViewFlipper>
  • GestureDetector
    UI Design Patterns
    Detects various gestures and events using the supplied MotionEvents
    GestureDetectorgestureDetector= newGestureDetector(newGestureDetector.SimpleOnGestureListener() {
    @Override
    publicbooleanonFling(MotionEvent e1, MotionEvent e2, floatvelocityX, floatvelocityY) {
    }
     
    @Override
    publicbooleanonDown(MotionEvent e) {
    }
     
    @Override
    publicbooleanonSingleTapUp(MotionEvent e) {
    }
    });
  • Implementation
    UI Design Patterns
    Read the Source Code…
  • I/O Access
  • File System
    Database
    Network
    Types of I/O:
    I/O Access
  • 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
  • Virtual Table that allows Full Text Search
    Produces results significantly faster than LIKE
    Comprehensive syntax
    SQLite FTS
    I/O Access
  • Creating FTS table
    Similar to creating a regular table:
    I/O Access
    publicclassDatabaseHelperextendsSQLiteOpenHelper { 
    privatestaticfinalStringDATABASE_NAME = "TheEdge";
    publicstaticfinalStringSPEAKERS_TABLE = "speakers";
     
    @Language("SQLite")
    privatestaticfinalStringCREATE_SPEAKERS_TABLE = "CREATE VIRTUAL TABLE " + SPEAKERS_TABLE + " USING fts3 (speaker_name TEXT , bio TEXT, company TEXT, image_uri TEXT)";
     
    publicDatabaseHelper(Contextcontext, String name, SQLiteDatabase.CursorFactory factory, int version) {
    super(context, name, factory, version);
    }
     
    @Override
    publicvoidonCreate(SQLiteDatabasesqLiteDatabase) {
    Log.i(this.getClass().getSimpleName(), "Creating DB");
    sqLiteDatabase.execSQL(CREATE_SPEAKERS_TABLE);
    }
     
  • Using:
    Use the MATCH keyword:
    I/O Access
    publicList<Session> searchSessions(String query) {
    finalList<Session> sessionList = newArrayList<Session>();
    finalSQLiteDatabasereadableDatabase = getReadableDatabase();
    finalCursorcursor = readableDatabase.rawQuery("select * from " + SESSIONS_TABLE + " where " + SESSIONS_TABLE + " match '" + query + "'", null);
    if (cursor.moveToFirst()) {
    do {
    finalSessionsession = newSession();
    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();
    }
    returnsessionList;
    }
     
  • 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
  • When using network, remember the following:
    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.
    I/O Access
  • I/O Access
    Activity with separate thread for Network
  • Optimization
  • 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
  • In order to implment lazy loading, we’ll need to do the following:
    Load the ListView an you would normally do.
    Create a task to fetch the data, use AsyncTask or a Service.
    Change the data on the UI thread.
    Use notifyDataSetChanged() to let ListView to update itself.
    Lazy Loading your ListView
    Optimization
  • Example
    Optimization
    publicclassSpeakersActivityextendsListActivityimplementsServiceListener {
     
    privatevoidfetchImages() {
    for (Speakerspeaker : speakers) {
    SpeakerImageFetcherspeakerImageFetcher = newSpeakerImageFetcher();
    speakerImageFetcher.execute(speaker);
    }
    }
     
    privateclassSpeakerImageFetcherextendsAsyncTask<Speaker, Void, Void> {
     
    @Override
    protectedVoiddoInBackground(Speaker... speakers) {
    finalSpeakerspeaker = speakers[0];
    finalBitmapbitmap = dataAccessor.fetchImage(speaker.getImageUrl());
    speaker.setSpeakerImage(bitmap);
    returnnull;
    }
     
    @Override
    protectedvoidonPostExecute(VoidaVoid) {
    speakersAdapter.notifyDataSetChanged();
    }
    }
    }
  • 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
  • Services oriented application:
    Optimization
    SQLite
    HttpClient
    Data Accessor
    Service
    Service Helper
    Activity
  • Service Example:
    Optimization
    publicclassNetworkServiceextendsIntentService {
     
    @Override
    protectedvoidonHandleIntent(Intent intent) {
    finalDataAccessordataAccessor = DataAccessor.getSingleton(this);
     
    finalResultReceiver receiver = intent.getParcelableExtra(STATUS_LISTENER);
    finalintrequestAction = intent.getIntExtra(REFRESH_ACTION, -1);
    boolean result = false;
     
    if (requestAction == REFRESH_SPEAKERS) {
    result = dataAccessor.syncAllSpeakers();
    } elseif (requestAction == REFRESH_SESSIONS) {
    result = dataAccessor.syncAllSessions();
    } elseif (requestAction == REFRESH_SCHEDULE) {
    result = dataAccessor.syncAllEvents();
    } elseif (requestAction == REFRESH_ALL) {
    dataAccessor.syncAllSpeakers();
    dataAccessor.syncAllSessions();
    dataAccessor.syncAllEvents();
    }
    if (result) {
    receiver.send(STATUS_REFRESHED, Bundle.EMPTY);
    }
    receiver.send(STATUS_NOT_REFRESHED, Bundle.EMPTY);
    }
    }
     
  • 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
  • ResultReceiver Example
    Accepts the Activity as the Listener using a custom interface
    Optimization
    publicclassNetworkServiceHelperextendsResultReceiver {
      privatefinalServiceListenerlistener;
      publicNetworkServiceHelper(ServiceListener listener) {
    super(new Handler()); this.listener = listener;
    }
      @Override
    protectedvoidonReceiveResult(intresultCode, BundleresultData) {
    if (listener != null) {
    listener.onReceiveResult(resultCode, resultData);
    }
    }
    }
  • Optimization
    Using the service:
    publicclassScheduleActivityextendsActivityimplementsServiceListener {
      privateNetworkServiceHelpernetworkServiceHelper;
      @Override
    publicvoidonCreate(BundlesavedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.schedule_activity);
    dataAccessor = DataAccessor.getSingleton(this);
    initCalendar();
    networkServiceHelper = newNetworkServiceHelper(this);
    finalIntentserviceIntent = 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
    publicvoidonReceiveResult(intresultCode, BundleresultData) {
    if (resultCode == NetworkService.STATUS_REFRESHED) {
    calendarLayout.removeAllViews();
    initCalendar();
    }
    }
    }
  • Reference
  • Reference
    http://developer.android.com/guide/index.html
    http://www.londatiga.net/it/how-to-create-quickaction-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#Android
    http://www.sqlite.org/fts3.html
    http://www.sqlite.org/cvstrac/wiki/wiki?p=FtsUsage
  • Thank You!
    We appreciate your feedback