SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
HOWTOFAIL
GOING
OFFLINE
@droidpl
javier.pedro@mobgen.com
javierdepedrolopez@gmail.com
JavierdePedroLópez
StrengthsExperience
SeniorAndroidDeveloper
3Yearsprofessionally
2Differentcompanies
Freetime
architecture
DesignPatterns
Gradle
Codequality
@droidpl
javier.pedro@mobgen.com
javierdepedrolopez@gmail.com
Thistalk
Try & try & fail
Architecture
proposal
Use case
Show me the
code
TRY&TRY&FAIL
Section 1
Try&try&fail
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
• I work on an SDK similar to
firebase
• Should work offline
• Should have a simple API
• Should be reliable and user
friendly
WhyThismatters?
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
• Offline improves user experience
• No loading times (most of the cases)
• App always accesible
• Just like magic

• Makes your app less error prone

• Forces the developer to think more mobile

• Say no to: “you always have a good internet
connection”
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Views/MVP/
Interactors
Using POJOS
Database
Callback
Network
Callback
Pojo
Callback
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Using POJOS
• Action cancellation
• Lifecycle management
• Single responsibility principle broken
• Messy thread management
• Hard to read code

• Fast to implement
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Views/MVP/
Interactors
Using Services
Service
ResultReceiver/Binder
Threading
Database
Sync
Network
Sync
Pojo
Callback
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Problems using Services
• Action cancellation is still a pain
• Easy to leak memory

• Easy to split in many services
• Export to other apps
• Easier to handle threading
• Possibility to have many processes
• Simplified callback system
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Views/
MVP/
Interactors
Using Sync Adapters
Network
Sync
Sync
adapter
Sync
trigger
Database
(content
provider)
Sync
Content
observer
Try&try&fail
WhyThismatters?
Pojos
Services
SyncAdapters
WhyIdidinvestigate?
Problems using Services
• Hard disconnection errors
• Sync adapter documentation
• Sync adapter configuration (many files)
• Too linked to accounts

• Uses system tools
• Content change notifications
• All the benefits from services
ARCHITECTUREPROPOSAL
Section 2
ARCHITECTUREPROPOSAL
ACTLOCALLY
SYNCGLOBALLY
LoadersArchitecture
proposal
Jobschedulers
Alltogether
Read
Write
Loaders
Repositories Views/
MVP/
Interactors
Loader
inits
provides
data
gets notified
android
lifecycle
asks for
data
Data
source
Loader statesArchitecture
proposal
Jobschedulers
Alltogether
Read
Write
Loaders
Repositories
Started Stopped Reset
Can load
Can observe
Can deliver
Can load
Can observe
Can deliver
Can load
Can observe
Can deliver
Stop/Reset Start/Reset Start
Job schedulersArchitecture
proposal
Jobschedulers
Loaders
Alltogether
Read
Write
Repositories
Pojo
notifies
notifies
System
Scheduler
schedule
job
Preconditions
check
Sync
Service
trigger
met
Sync task
run task
RepositoriesArchitecture
proposal
Jobschedulers
Loaders
Alltogether
Read
Write
Repositories
Data
Repositorynotifies
Database
Repository
Read
Write
Other sources
Network
repository
Read
Write
Architecture
proposal
Jobschedulers
Loaders
Overall diagram
Alltogether
Read
Write
Repositories
Data
Repository
Notifies
Asks for
data
Loader
Inits
Provides
data
System
Scheduler
Schedule sync
Sync
Service
Sync task
Conditions
metRun task
Changes data
Read
Write
Read
Write
Views/
MVP/
Interactors
Start
App SDK
write
Architecture
proposal
Jobschedulers
Loaders
Alltogether
Read
Write
Repositories
SDKLoader
Loader
Loader
Overall diagram
App Layer
Android
SDK
Entry
Entry
Entry
Entry
Architecture
proposal
Jobschedulers
Loaders
Read diagram
Alltogether
Read
Write
Repositories
Architecture
proposal
Jobschedulers
Loaders
Write diagram
Alltogether
Read
Write
Repositories
online
USECASE
Section 3
Usecase
Onlinesample
Models
offlineSample
Articles and comments
Usecase
Onlinesample
Models
offlineSample
Usecase
Onlinesample
Models
offlineSample
SHOWMETHECODE
Section 4
Classes
PostActivity PostLoader PostRepository
PostDAO
CommentDAO
PostService
SyncServiceSynchronizeTask
write
PostActivity:init
private PostRepository mRepository;
private Executor mExecutor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRepository = DemosApplication.instance()
.demoSdk()
.postRepository();
mExecutor = Executors.newSingleThreadExecutor();
startLoading();
PostLoader.init(getSupportLoaderManager(), this);
}
Views
PostActivity:loaddata
@Override
public Loader<List<Post>> onCreateLoader(int id, Bundle args) {
return new PostLoader(this, DemosApplication.instance().demoSdk());
}
@Override
public void onLoadFinished(Loader<List<Post>> loader, List<Post> data) {
stopLoading();
setAdapter(data);
}
@Override
public void onLoaderReset(@NonNull Loader<List<Post>> loader) {
//Do nothing
}
Views
PostActivity:Refresh
@Override
public void onRefresh() {
startLoading();
PostLoader.getLoader(getSupportLoaderManager()).forceLoad();
}
Views
PostActivity:Createpost
@Override
public void onPostCreated(@NonNull final Post post) {
startLoading();
mExecutor.execute(() -> {
try {
mRepository.localCreate(post);
} catch (RepositoryException e) {
showError();
}
});
}
Views
PostActivity:Deletepost
@Override
public void onDeleted(@NonNull final Post post) {
startLoading();
mExecutor.execute(() -> {
try {
mRepository.localDelete(post);
} catch (RepositoryException e) {
showError();
}
});
}
Views
postloader
@Override
public List<Post> loadInBackground() {
setData(mDemoSdk.postRepository().posts());
return getData();
}
@Override
public void registerListener() {
if (mObserver == null) {
mObserver = SyncService.listenForUpdates(this);
}
}
@Override
public void unregisterListener() {
if (mObserver != null) {
SyncService.removeUpdateListener(this, mObserver);
}
}
loader
Postrepository:allposts
@WorkerThread
public List<Post> posts() {
Response<List<Post>> postsResponse = mPostService.posts().execute();
if (postsResponse.isSuccessful()) {
List<Post> posts = postsResponse.body();
mPostDao.deleteAll();
mPostDao.save(posts);
}
return mPostDao.posts();
}
datasource
Postrepository:Save
@WorkerThread
public void localCreate(@NonNull Post post) {
mPostDao.save(post);
SyncService.triggerSync(mContext);
}
@WorkerThread
public void remoteCreate(@NonNull Post post) {
Response<Post> postResponse = mPostService.create(Post.builder(post)
.internalId(null)
.needsSync(false)
.build()).execute();
if (postResponse.isSuccessful()) {
mPostDao.save(Post.builder(postResponse.body())
.internalId(post.internalId())
.build());
}
}
datasource
Postrepository:DELETE
@WorkerThread
public void localDelete(@NonNull Post post) {
long now = new Date().getTime();
if (post.isNew() && post.isStoredLocally()) {
mPostDao.delete(post.internalId());
SyncService.notifyChange(mContext);
} else {
mPostDao.save(Post.builder(post)
.deletedAt(now)
.updatedAt(now)
.needsSync(true).build());
SyncService.triggerSync(mContext);
}
}
@WorkerThread
public void remoteDelete(@NonNull Post post) {
if (mPostService.deletePost(post.id()).execute().isSuccessful() && post.isStoredLocally()) {
for (Comment comment : mCommentDao.comments(post.internalId())) {
remoteDelete(comment);
}
mPostDao.delete(post.internalId());
}
}
datasource
Syncservice:trigger
public static void triggerSync(@NonNull Context context) {
SyncService.notifyChange(context);
ComponentName component = new ComponentName(context, SyncService.class);
JobInfo info = new JobInfo.Builder(SYNC_SERVICE_ID, component)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build();
getScheduler(context).schedule(info);
}
sync
Syncservice:Listenforupdates
public static BroadcastReceiver listenForUpdates(@NonNull Loader loader) {
IntentFilter filter = new IntentFilter(CHANGE_SYNC_INTENT_ACTION);
SyncServiceReceiver receiver = new SyncServiceReceiver(loader);
LocalBroadcastManager.getInstance(loader.getContext())
.registerReceiver(receiver, filter);
return receiver;
}
public static void removeUpdateListener(@NonNull Loader loader,
@NonNull BroadcastReceiver observer) {
LocalBroadcastManager.getInstance(loader.getContext())
.unregisterReceiver(observer);
}
public static void notifyChange(@NonNull Context context) {
LocalBroadcastManager.getInstance(context).sendBroadcast(getCompletionIntent());
}
sync
Syncservice:DotheJOB
@Override
public boolean onStartJob(JobParameters params) {
DemoSdk sdk = DemoSdk.Factory.instance();
boolean willExecute = true;
if (sdk != null) {
mRunningSyncTask = new SynchronizeTask(sdk, this);
mRunningSyncTask.execute(params);
} else {
willExecute = false;
}
return willExecute;
}
sync
@Override
public boolean onStopJob(JobParameters params) {
boolean reschedule = false;
if (mRunningSyncTask != null) {
mRunningSyncTask.cancel(true);
reschedule = true;
}
return reschedule;
}
Synctask:Sync
@Override
protected JobParameters doInBackground(JobParameters... params) {
syncPosts();
syncComments();
return params[0];
}
sync
private void syncPosts() {
List<Post> posts = mSdk.postRepository().localPendingPosts();
for (Post post : posts) {
if (post.isNew()) {
mSdk.postRepository().remoteCreate(post);
} else if (post.isDeleted()) {
mSdk.postRepository().remoteDelete(post);
}
}
}
Synctask:NOTIFY
@Override
protected void onPostExecute(JobParameters jobParameters) {
super.onPostExecute(jobParameters);
SyncService.notifyChange(mSyncService);
mSyncService.jobFinished(jobParameters, mNeedsResync);
}
sync
Andthereyougo!yourappworksoffline
SOURCECodeavailable
https://github.com/droidpl/offline-architecture
@droidpl
Conclusions
Offline matters
because
UX matters
It is part of the
architecture
Not so much
effort with the
right choice
Unique
dataflow
Don’t reinvent
the wheel
- Android has it -
……………………
Wearehiring!
Ask
……………………
Q&A
……………………
Thankyou!

Mais conteúdo relacionado

Mais procurados

WuKong - Framework for Integrated Test
WuKong - Framework for Integrated TestWuKong - Framework for Integrated Test
WuKong - Framework for Integrated Test
Summer Lu
 
Getting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in EclipseGetting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in Eclipse
Tom Arend
 

Mais procurados (20)

Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Bowtie: Interactive Dashboards
Bowtie: Interactive DashboardsBowtie: Interactive Dashboards
Bowtie: Interactive Dashboards
 
AngularJS Unit Test
AngularJS Unit TestAngularJS Unit Test
AngularJS Unit Test
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJS
 
Easy automation.py
Easy automation.pyEasy automation.py
Easy automation.py
 
It's a Kind of Magic: Under the Covers of Spring Boot
It's a Kind of Magic: Under the Covers of Spring BootIt's a Kind of Magic: Under the Covers of Spring Boot
It's a Kind of Magic: Under the Covers of Spring Boot
 
WuKong - Framework for Integrated Test
WuKong - Framework for Integrated TestWuKong - Framework for Integrated Test
WuKong - Framework for Integrated Test
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
 
Kiss PageObjects [01-2017]
Kiss PageObjects [01-2017]Kiss PageObjects [01-2017]
Kiss PageObjects [01-2017]
 
Codeception presentation
Codeception presentationCodeception presentation
Codeception presentation
 
Java Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to MissJava Libraries You Can't Afford to Miss
Java Libraries You Can't Afford to Miss
 
Jumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin ProgrammingJumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin Programming
 
learning react
learning reactlearning react
learning react
 
Your code are my tests
Your code are my testsYour code are my tests
Your code are my tests
 
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
 
Controller Testing: You're Doing It Wrong
Controller Testing: You're Doing It WrongController Testing: You're Doing It Wrong
Controller Testing: You're Doing It Wrong
 
SymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment PipelinesSymfonyCon Berlin 2016 Jenkins Deployment Pipelines
SymfonyCon Berlin 2016 Jenkins Deployment Pipelines
 
The Screenplay Pattern: Better Interactions for Better Automation
The Screenplay Pattern: Better Interactions for Better AutomationThe Screenplay Pattern: Better Interactions for Better Automation
The Screenplay Pattern: Better Interactions for Better Automation
 
Getting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in EclipseGetting Started with Maven and Cucumber in Eclipse
Getting Started with Maven and Cucumber in Eclipse
 

Destaque

Profile.e (yuki sato)0529
Profile.e (yuki sato)0529Profile.e (yuki sato)0529
Profile.e (yuki sato)0529
Sato Yuki
 
(Self) Publishing
(Self) Publishing(Self) Publishing
(Self) Publishing
Vlad Micu
 
2012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 12012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 1
Vivastream
 
Dios es mi Guía
Dios es mi GuíaDios es mi Guía
Dios es mi Guía
adeni11
 

Destaque (20)

World-Class Testing Development Pipeline for Android
 World-Class Testing Development Pipeline for Android World-Class Testing Development Pipeline for Android
World-Class Testing Development Pipeline for Android
 
Profile.e (yuki sato)0529
Profile.e (yuki sato)0529Profile.e (yuki sato)0529
Profile.e (yuki sato)0529
 
Tarea 1 e busines
Tarea 1 e businesTarea 1 e busines
Tarea 1 e busines
 
Curso de Alta Formación en Marketing para Empresas de Servicios
Curso de Alta Formación en Marketing para Empresas de ServiciosCurso de Alta Formación en Marketing para Empresas de Servicios
Curso de Alta Formación en Marketing para Empresas de Servicios
 
Brand boost by wildtangent
Brand boost by wildtangentBrand boost by wildtangent
Brand boost by wildtangent
 
Update on the ELIXIR UK node by Chris Ponting
Update on the ELIXIR UK node by Chris PontingUpdate on the ELIXIR UK node by Chris Ponting
Update on the ELIXIR UK node by Chris Ponting
 
S&B Parking Operators
S&B Parking OperatorsS&B Parking Operators
S&B Parking Operators
 
fluke presentation voicemail on email – cisco
fluke presentation voicemail on email – ciscofluke presentation voicemail on email – cisco
fluke presentation voicemail on email – cisco
 
(Self) Publishing
(Self) Publishing(Self) Publishing
(Self) Publishing
 
CompuSystems Dashboards
CompuSystems DashboardsCompuSystems Dashboards
CompuSystems Dashboards
 
Examen trimestra diego reyes
Examen trimestra  diego reyesExamen trimestra  diego reyes
Examen trimestra diego reyes
 
2012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 12012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 1
 
Servicio Eiden : Opinan nuestros clientes
Servicio Eiden : Opinan nuestros clientesServicio Eiden : Opinan nuestros clientes
Servicio Eiden : Opinan nuestros clientes
 
Status Www Undersøgelse Udenpix
Status Www Undersøgelse UdenpixStatus Www Undersøgelse Udenpix
Status Www Undersøgelse Udenpix
 
Da schau her! Augenfreundliche Gestaltung von e-Learning Kursen
Da schau her! Augenfreundliche Gestaltung von e-Learning KursenDa schau her! Augenfreundliche Gestaltung von e-Learning Kursen
Da schau her! Augenfreundliche Gestaltung von e-Learning Kursen
 
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
 
Estudio earcas
Estudio earcasEstudio earcas
Estudio earcas
 
Dios es mi Guía
Dios es mi GuíaDios es mi Guía
Dios es mi Guía
 
Ejercicio de dinamica
Ejercicio de dinamicaEjercicio de dinamica
Ejercicio de dinamica
 
1 year with ROM on production
1 year with ROM on production1 year with ROM on production
1 year with ROM on production
 

Semelhante a Droidcon ES '16 - How to fail going offline

Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Victor Rentea
 

Semelhante a Droidcon ES '16 - How to fail going offline (20)

My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
My way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca editionMy way to clean android (EN) - Android day salamanca edition
My way to clean android (EN) - Android day salamanca edition
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
All a flutter about Flutter.io
All a flutter about Flutter.ioAll a flutter about Flutter.io
All a flutter about Flutter.io
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Net conf BG xamarin lecture
Net conf BG xamarin lectureNet conf BG xamarin lecture
Net conf BG xamarin lecture
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Cleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsCleaning your architecture with android architecture components
Cleaning your architecture with android architecture components
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code less
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
Testing in android
Testing in androidTesting in android
Testing in android
 
softshake 2014 - Java EE
softshake 2014 - Java EEsoftshake 2014 - Java EE
softshake 2014 - Java EE
 
Mobile Developers Talks: Delve Mobile
Mobile Developers Talks: Delve MobileMobile Developers Talks: Delve Mobile
Mobile Developers Talks: Delve Mobile
 
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
2008 - TechDays PT: WCF, JSON and AJAX for performance and manageability
 
Why you should be using the shiny new C# 6.0 features now!
Why you should be using the shiny new C# 6.0 features now!Why you should be using the shiny new C# 6.0 features now!
Why you should be using the shiny new C# 6.0 features now!
 
JS Class 2016
JS Class 2016JS Class 2016
JS Class 2016
 

Último

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 

Último (20)

WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 

Droidcon ES '16 - How to fail going offline