• Share
  • Email
  • Embed
  • Like
  • Private Content
Webinar - Developing with Couchbase Lite on Android
 

Webinar - Developing with Couchbase Lite on Android

on

  • 1,290 views

Learn how to develop with Couchbase Lite for Android in this technical lecture led by Traun Leyden, lead Couchbase Lite Android developer. The session will include a look into the Native API and a ...

Learn how to develop with Couchbase Lite for Android in this technical lecture led by Traun Leyden, lead Couchbase Lite Android developer. The session will include a look into the Native API and a walkthrough of a demo app.

In this webinar you will see:

A 5-minute recap of the Couchbase Lite architecture
An overview of the Couchbase Lite iOS API
Demo - Grocery Sync Demo App with new Android Native API
Code walkthrough of Grocery Sync Demo App

Statistics

Views

Total Views
1,290
Views on SlideShare
1,152
Embed Views
138

Actions

Likes
2
Downloads
19
Comments
0

2 Embeds 138

http://www.couchbase.com 137
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

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

    Webinar - Developing with Couchbase Lite on Android Webinar - Developing with Couchbase Lite on Android Presentation Transcript

    • Developing  With   Couchbase  Lite  on  Android   Traun  Leyden   tleyden@couchbase.com!   10/29/13
    • Webinar  Overview   •  Understand  the  overall  problem   •  Overview  of  the  JSON  Anywhere  soluDon   •  Couchbase  Lite  for  Android   ­  This  will  assume  some  familiarity  with  Android,  but  hopefully  not  too   much   •  Where  to  go  from  here!
    • Bird’s  eye  view  of  the  Problem   •  A  typical  app  today  is  extremely  data  rich   •  This  data  is  largely  unstructured     •  RepresenDng  this  in  JSON  is  a  natural  fit,  but  ..   •  How  do  you  build  a  mobile  app  using  tools  like  SQLite  or   Core  Data  while  the  data  is  stored  in  JSON?!
    • Couchbase  Lite  on  Android   •  InstallaDon  and  setup  walk-­‐through   •  Demo  of  Grocery  Sync  sample  app   •  Tour  of  Grocery  Sync  code   ­  with  digressions  about  the  API   ­  and  the  document  model   ­  and  querying   •  Beyond  Grocery  Sync!
    • InstallaDon  setup  and  walk-­‐through   •  Clone  the  GrocerySync-­‐Android  repository   •  Import  into  Android  Studio   •  Build  &  Run!
    • 1.  Clone  the  GrocerySync-­‐Android  repository   T w aftehisur ill be easier r o next release!     $  git  clone  -­‐-­‐recursive  git@github.com:couchbaselabs/ GrocerySync-­‐Android.git   $  cd  GrocerySync-­‐Android   $  git  checkout  native_api   $  git  submodule  init  &&  git  submodule  update  
    • Import  into  Android  Studio   Choose  Import   Project  ..  
    • Import  into  Android  Studio   Choose  the  folder   you  did  the  git  clone   into  
    • Import  into  Android  Studio   Check  auto-­‐import  and   use  default  gradle   wrapper  
    • Build  and  Run   Hit  the  Run   buTon  to  launch   the  app  
    • Build  and  Run   The  emulator  will     launch  running   Grocery  Sync  
    • Live  Demo  
    • Demo  Recap   •  We  were  able  to  create,  update,  and  delete  records     •  Verified  that  documents  were  Sync’d  to  Couchbase  Server   by  inspecDng  the  Sync  Gateway  via  curl  
    • A  Tour  of  the  Code   and  the  API  
    • IniDalizaDon   MainAc=vity#startCBLite()!        //  Initialize  Couchbase  Lite  and  find/create  my  database:          protected  void  startCBLite()  throws  CBLiteException  {                                  manager  =  new  CBLManager(getApplicationContext().getFilesDir());  
    • Manager,  Databases,  Documents   ! CBLManager   CBLDocument  “doc1”   {! }   “text”: “Shaving Cream”,! “created”: “2013-10-08”,! “check”: false!   CBLDatabase Database     “db”   “otherdb” Document   “doc1” CBLDocumen   t   “doc2” CBLDocumen   t  “doc3”     thumb.jpg
    • Manager   •  CollecDon  of  named  databases   •  No  known  use  cases  for  mulDple  Managers  on  Android   ­  Essen=ally  an  ar=fact  of  the  iOS  port   •  Manages  database  storage  (local  directory)  
    • Database   •  A  Couchbase  Lite  database  is  a  “real”  database  on  not   simply  a  wrapper  for  a  cloud  service   •  Namespace  for  documents   •  Contains  views  and  their  indexes     •  Contains  validaDon  funcDons   •  Source  and  target  of  replicaDon!
    • Document   •  Has  unique  ID  within  its  database   •  Contains  arbitrary*  JSON  object   ­  *except  keys  that  start  with  “_”  are  reserved   ­  There  is  no  explicit,  enforced  schema   ­  Denormaliza=on  is  OK  —  use  arrays  or  dic=onaries   •  May  contain  binary  aTachments   ­  Data  blobs,  can  be  large,  tagged  with  MIME  type   •  Versioned   ­  ­  ­  ­  ­  Mul=-­‐Version  Concurrency  Control  (MVCC)   Every  update  creates  a  revision  ID  (based  on  digest  of  contents)   Revision  ID  history  is  stored   Enables  conflict  resolu=on  in  sync’ing   Very  painful  if  you  try  to  build  this  yourself!
    • Views  &  Queries   CBLDatabase   “db”   function(doc) {! emit(doc.created,! doc.title);! }   map func tion     CBLView View     “completed” “byDate”   key! value! docID! “2013-­‐03-­‐12”! “taxes”! “doc17”! “2013-­‐09-­‐30”! “call  mom”! “doc62”! “2013-­‐10-­‐17”! “cat  food”! “doc82”! “2013-­‐10-­‐17”! “tea  bags”! “doc83”! “2013-­‐10-­‐22”! “upgrade”! “doc90”! view index   }   CBLQuery  
    • Views   •  Map/Reduce  mechanism   ­  A  standard  method  of  indexing  in  NoSQL     ­  A  view  is  similar  to  index  in  rela=onal  database.   •  App-­‐defined  map  funcDon   ­  Called  on  every  document   ­  Can  emit  arbitrary  key/value  pairs  into  the  index   •  OpDonal  reduce  funcDon   ­  Data  aggrega=on  /  grouping   •  FuncDons  are  registered  as  naDve  callbacks   ­  Na=ve  callbacks  make  sense  for  performance  and  to  match  the  rest  of  the   app  codebase!
    • CreaDng  a  Database  View   MainAc=vity#startCBLite()! No a dat a Us iew — tab IV “ is like a nein view” a dex.        //  Define  a  view  with  a  map  function  that  indexes  to-­‐do  items  by  creation  date:          db  =  manager.getDatabase(DATABASE_NAME);          CBLView  view  =  db.getView(String.format("%s/%s",  dDocName,  byDateViewName));          view.setMap(new  CBLMapFunction()  {                  @Override                  public  void  map(Map<String,  Object>  document,  CBLMapEmitFunction  emitter)  {                          Object  createdAt  =  document.get("created_at");                          if(createdAt  !=  null)  {                                  emitter.emit(createdAt.toString(),  document);                          }                  }          },  "1.0");    
    • Queries  and  LiveQueries  
    • Queries   •  Basic  feature  set   ­  Key  ranges,  offset/limit,  reverse,  group  by  key…   ­  No  joins  or  fancy  sor=ng   ­  but  compound  keys  (and  clever  emits)  allow  for  some  tricks   •  LiveQuery  subclass   ­  Monitors  a  view  for  changes   ­  Can  think  of  it  as  a  “pub-­‐sub”  approach   ­  Register  a  callback  that  is  triggered  when  the  query  changes  !
    • Live  Queries  &  UI   key! value! docID! “2013-­‐09-­‐30”! “Pencil   shavings”! “doc62”! “2013-­‐10-­‐17”! “Mangos”! “doc82”! “2013-­‐10-­‐17”! view index   “doc83”! “second”! }   CBLQuery   CBLLiveQuery   Refresh   ListViewAda pter     data source
    • Driving  the  Table  from  a  View  Query   MainAc=vity#startLiveQuery()!           liveQuery  =  view.createQuery().toLiveQuery();   liveQuery.addChangeListener(new  CBLLiveQueryChangedFunction()  {          @Override          public  void  onLiveQueryChanged(CBLQueryEnumerator  queryEnumerator)  {                  final  List<CBLQueryRow>  rows  =  getRowsFromQueryEnumerator(queryEnumerator);                  runOnUiThread(new  Runnable()  {                          @Override                          public  void  run()  {                                    ..  update  itemListView  with  new  itemListViewAdapter                            }                  });          }   });   liveQuery.start();  
    • ListAdapter  View  objects   GrocerySyncListAdapter#getView()! TextView  label  =  ((ViewHolder)itemView.getTag()).label;   CBLQueryRow  row  =  list.get(position);   CBLDocument  document  =  row.getDocument();     label.setText((String)document.getCurrentRevision().getProperty("text"));     boolean  checked  =  false;   checked  =  ((Boolean)   document.getCurrentRevision().getProperty(“check")).booleanValue();     ImageView  icon  =  ((ViewHolder)itemView.getTag()).icon;   if(checked)  {          icon.setImageResource(R.drawable.list_area___checkbox___checked);   }   else  {          icon.setImageResource(R.drawable.list_area___checkbox___unchecked);   }   return  itemView;  
    • Responding  To  Taps   MainAc=vity#onItemClick()!                CBLQueryRow  row  =  (CBLQueryRow)  adapterView.getItemAtPosition(position);                  CBLDocument  document  =  row.getDocument();                  Map<String,  Object>  curProperties  =  document.getProperties();                  Map<String,  Object>  newProperties  =  new  HashMap<String,  Object>();                  newProperties.putAll(curProperties);                    boolean  checked  =  ((Boolean)  newProperties.get("check")).booleanValue();                  newProperties.put("check",  !checked);                    document.putProperties(newProperties);  
    • Adding  New  Items   MainAc=vity#createGroceryItem()! SimpleDateFormat  dateFormatter  =  new  SimpleDateFormat("yyyy-­‐MM-­‐ dd'T'HH:mm:ss.SSS'Z'");     UUID  uuid  =  UUID.randomUUID();   Calendar  calendar  =  GregorianCalendar.getInstance();   long  currentTime  =  calendar.getTimeInMillis();   String  currentTimeString  =  dateFormatter.format(calendar.getTime());     String  id  =  currentTime  +  "-­‐"  +  uuid.toString();     CBLDocument  document  =  database.createDocument();     Map<String,  Object>  properties  =  new  HashMap<String,  Object>();   properties.put("_id",  id);   properties.put("text",  text);   properties.put("check",  Boolean.FALSE);   properties.put("created_at",  currentTimeString);   document.putProperties(properties);     return  document;  
    • DeleDng  Items   MainAc=vity#onItemLongClick()! CBLQueryRow  row  =  (CBLQueryRow)  adapterView.getItemAtPosition(position);   final  CBLDocument  clickedDocument  =  row.getDocument();   clickedDocument.delete();  
    • OK,  But  how  does  Sync  work?  
    • ReplicaDon   Database   “db”   Dir:  push   Remote:  hep://server/db   Auth:  <token>   ReplicaDon   Dir:  pull   Remote:  hep://server/db   ReplicaDon   Auth:  <token>  
    • CreaDng  ReplicaDons   MainAc=vity#startSync()!                URL  syncUrl;                  try  {                          syncUrl  =  new  URL(SYNC_URL);                  }  catch  (MalformedURLException  e)  {                          throw  new  RuntimeException(e);                  }                    CBLReplicator  pullReplication  =  database.getPullReplication(syncUrl);                  pullReplication.setContinuous(true);                    CBLReplicator  pushReplication  =  database.getPushReplication(syncUrl);                  pushReplication.setContinuous(true);                    pullReplication.addObserver(this);                  pushReplication.addObserver(this);                    pullReplication.start();                  pushReplication.start();  
    • ReplicaDon   •  Each  ReplicaDon  is  one-­‐direcDonal  (push  or  pull)   •  ReplicaDons  can  be  one-­‐shot,  conDnuous  or  persistent   ­  One-­‐shot:  Stops  when  complete.   ­  Con=nuous:  Keeps  monitoring  changes  =ll  app  quits   ­  Persistent:  Automa=cally  starts  again  on  next  relaunch   •  Replicator  runs  in  a  background  thread   ­  It  detects  online/offline,  handles  connec=on  errors,  retries…   ­  You  just  see  document-­‐changed  or  query-­‐changed  no=fica=ons.   •  Progress  is  observable  through  Observer/Observable  (to  be   changed)!
    • Monitoring  ReplicaDons   MainAc=vity#update()!          public  void  update(Observable  observable,  Object  o)  {                  CBLReplicator  replicator  =  (CBLReplicator)  observable;                    if  (!replicator.isRunning())  {                          String  msg  =  String.format("Replicator  %s  not  running",  replicator);                          Log.d(TAG,  msg);                  }                  else  {                          int  processed  =  replicator.getChangesProcessed();                          int  total  =  replicator.getChangesTotal();                          String  msg  =  String.format("Replicator  processed  %d  /  %d",  processed,   total);                          Log.d(TAG,  msg);                  }          }  
    • Beyond  Grocery  Sync  
    • Models   •  Currently  missing  from  the  Android  NaDve  API   •  The  plan  is  that  models  will  be  inspired  by  ORMLite   ­  Will  use  annota=on  based  approach  rather  than  subclassing  
    • RepresenDng  Document  Types   •  There  are  no  tables  to  separate  different  record  types!   ­  Conven=on  is  to  use  a  “type”  property   •  Map  funcDons  can  pick  out  docs  with  the  right  type   ­  if  (doc.type  ==  “item”)  emit(doc.created,  doc.text);!
    • Slicing  up  hierarchical  data   From  ToDoLite  project! Chores! TODO  Lists! Do  Laundry! Chores! Shave  Yak! Errands! ..! ..! ..! ..! …! …! Errands! Pickup  GTA5  at  best  buy! Wash  car! ..! ..! …!
    • Slicing  up  hierarchical  data   From  ToDoLite  project! view.setMap(new  CBLMapFunction()  {          public  void  map(Map<String,  Object>  document,  CBLMapEmitFunction  emitter)  {                  if  (document.get("type").equals("todo_list"))  {                          Object  createdAt  =  document.get("created_at");                          String  listId  =  (String)  document.get("list_id");                          Object[]  key  =  new  Object[]  {  createdAt,  listId  }                          emitter.emit(key,  document);                  }          }   },  "1.0");   key! docID! [“errands”,  “2013-­‐09-­‐30”]! “doc82”! [“errands,  “2013-­‐06-­‐02”]! “doc62”! [“chores”,  “2013-­‐10-­‐17”]! “doc83”! [“chores”,  “2013-­‐10-­‐28”]! “doc90”! …! …!
    • Slicing  up  hierarchical  data:  Querying   From  ToDoLite  project!        CBLQuery  query  =  view.createQuery();          query.setDescending(true);          String  myListId  =  “chores”;          query.setStartKey(new  Object[]  {  myListId,  new  HashMap()  });          query.setEndKey(new  Object[]  {  myListId  });   key! [“errands”,  “2013-­‐09-­‐30”]! {   docID! “doc82”! [“errands,  “2013-­‐06-­‐02”]! “doc62”! [“chores”,  “2013-­‐10-­‐17”]! “doc83”! [“chores”,  “2013-­‐10-­‐28”]! “doc90”! …! …!
    • Where  to  go  from  here  
    • Couchbase  Cloud   •  To  create  a  connected  Mobile  App,  you  will  need  a   backend   •  For  producDon  deployment,  you  will  want  to  use   Sync  Gateway  +  Couchbase  Server   •  But  for  development,  Couchbase  Cloud  is  the   quickest  path   Couchbase  Cloud  gives   you  this  in  a  few  clicks  
    • How  to  get  up  and  running  in  5  mins   •  Signup  for  Couchbase  Cloud   ­  The  fastest  way  to  experiment  with  Couchbase  Lite   ­  Signup  at  hep://console.couchbasecloud.com   •  Download  the  GrocerySync  example  from  github   •  Follow  the  instrucDons  in  this  webinar  
    • Join  the  Couchbase  Lite  community   •  Official  homepage   ­  mobile.couchbase.com   •  Google  Group   ­  heps://groups.google.com/forum/?fromgroups#!forum/mobile-­‐ couchbase   •  Github  Repository   ­  heps://github.com/couchbase/couchbase-­‐lite-­‐android  
    • Thanks  for  watching!