Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Android Infrastructure Overview
Search
Alexey Buzdin
April 24, 2013
Programming
690
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Android Infrastructure Overview
Alexey Buzdin
April 24, 2013
More Decks by Alexey Buzdin
See All by Alexey Buzdin
Make you Gadget Talk: Google Assistant
larchaon
0
110
Writing A Plugin for Android Studio
larchaon
1
120
Marvel of Annotation Processing in Java Mobius 2017
larchaon
0
180
How to Become a Successful Programmer
larchaon
0
120
Kotlin JS: Is it a Thing?
larchaon
0
210
Marvel of Annotations in Java/Android
larchaon
0
130
Testing RESTful services: GoT JavaDay Kiev Edition
larchaon
0
130
Automate the Mobile
larchaon
0
230
Google I/O 2016 Retrospective
larchaon
0
89
Other Decks in Programming
See All in Programming
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
12
4.8k
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
120
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
360
1B+ /day規模のログを管理する技術
broadleaf
0
140
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
890
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
140
関数型プログラミングのメリットって何だろう?
wanko_it
0
170
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
250
Featured
See All Featured
WENDY [Excerpt]
tessaabrams
11
38k
Google's AI Overviews - The New Search
badams
0
1.1k
Everyday Curiosity
cassininazir
0
250
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
150
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
240
Being A Developer After 40
akosma
91
590k
Accessibility Awareness
sabderemane
1
150
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
760
Side Projects
sachag
455
43k
Music & Morning Musume
bryan
47
7.3k
Transcript
Overview of Android Infrastructure Alexey Buzdin March 2013
@AlexeyBuzdin! ! !
[email protected]
! ! ! LArchaon!
Everyone needs an app....
we need an app too!
Simple CRUD app
Requirement:! ! Support as many android devices as you can!
(phones + tablets)
4.0 4.1–4.2 3.0 2.3 2.2 2.1 Google data, March 2013
None
Ain't that good for a developer
None
None
None
Is there is someone who could solve this?
nope
Ease our pain?
maybe
None
None
Layers Presentation ! Application logic ! Domain Presentation ! Application
logic ! Domain
Presentation ! Application logic ! Domain Presentation ! Application logic
! Domain
Spot the problem
Missing in Android 2.2 • ActionBar! • Fragments (used for
both tablets and phone support)
Solution?
Compatibility libraries Android Support library! ActionBarSherlock! etc
Support Library http://developer.android.com/tools/extras/ support-library.html ! Fragments! Async Stuff! Experimental stuff
Fragments
Example
ActionBar
ActionBarSherlock http://actionbarsherlock.com/
Refreshing list
Pull to Refresh https://github.com/chrisbanes/ Android-PullToRefresh
Presentation ! Application logic ! Domain Presentation ! Application logic
! Domain
Android Runtime On Android you develop in Java ... but
Android does not run Java bytecode !
DalvikVM Dalvik Virtual Machine − Custom VM optimized for mobile
devices − Register-based JVM − More efficient and compact − Use memory efficiently − Dalvik Executable Code (.dex) • 30% fewer instructions • 35% fewer code units • 35% more bytes − Trace JIT compiler (since 2.2)
!35 Android Runtime Android Java = Java language + Dalvik
+ Apache Harmony Android Java API = Java SE – AWT/Swing + Android API Sun-Java = Java language + JVM + JDK
App lifecycle
Activity public class MyActivity extends Activity { ! @Override public
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
None
Activity public class MyActivity extends Activity { ! @Override public
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
Resources
Activity public class MyActivity extends Activity { ! @Override public
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } ! }
Context • Context of current state of the application/object
Context • Context of current state of the application/object! •
Context is a handle to the system it provides services like ! − resolving resources ! − obtaining access to databases and preferences
Important any resource taken from context will live as long
as Context does
Context problem public class MyActivity extends Activity { ! @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String appName = getString(R.string.appName); } ! }
Passing Context public class MyStringProvider { ! Context context; !
public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } ! }
Passing Context
Context problem public class MyActivity extends Activity { ! @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String appName = getString(R.string.appName); } ! } Presentation ! Application logic ! Domain Presentation ! Application logic ! Domain
Injection libraries Dependency Injection! • RoboGuice! • Dagger
RoboGuice • Based on Google Guice! • Lightweight! • Multifunctional
(has resource injection)
RoboGuice public class MyActivity extends RoboActivity { ! @Inject MyStringProvider
stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
RoboGuice public class MyStringProvider { ! Context context; ! @Inject
public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name); } }
Notable fact
Minimal context injection public class MyActivity extends RoboActivity { !
int i; ! @Inject MyStringProvider stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! i = 1; ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
RoboGuice public class MyStringProvider { ! Context context; ! @Inject
public MyStringProvider(Context context) { this.context = context; } ! public String getString(){ return context.getString(R.string.app_name) + ((MyActivity)context).i; } }
Dagger public class DaggerActivity extends DaggerBaseActivity { ! @Inject DaggerStringProvider
stringProvider; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! ((TextView) findViewById(R.id.textView)) .setText(stringProvider.getString()); } ! }
Dagger public class DaggerBaseActivity extends Activity { ! @Inject Bus
bus; ! @Override protected void onCreate(Bundle state) { super.onCreate(state); ! DaggerApplication.inject(this); } ! @Override protected void onResume() { super.onResume(); bus.register(this); } ! @Override protected void onPause() { super.onPause(); bus.unregister(this); } }
Dagger public class DaggerApplication extends Application { ! private static
ObjectGraph objectGraph; ! @Override public void onCreate() { super.onCreate(); ! objectGraph = ObjectGraph.create(new DaggerModule(this)); } ! public static <T> void inject(T instance) { if(objectGraph != null) objectGraph.inject(instance); } }
@Module( entryPoints = { DaggerApplication.class, DaggerActivity.class} ) public class DaggerModule
{ private final Context appContext; ! public DaggerModule(Context appContext) { this.appContext = appContext.getApplicationContext(); } ! @Provides @Singleton Bus provideBus() { return new Bus(); } ! @Provides Context provideContext() { return appContext; } ! }
Summary Dagger ! • More customizable! • Compile time injection!
• Easy to use with other libraries! • Requires more code! ! RoboGuice! • Simpler! • Runtime injection! • Out of Box functionality
Problem with views
None
None
Other “Injection” libraries Resource and View “Injection”! • RoboGuice! •
ButterKnife! • AndroidAnnotations
RoboGuice Views Injection public class RoboGuiceActivity extends RoboActivity { !
! @Inject RoboGuiceStringProvider stringProvider; @InjectView(R.id.textView) TextView textView; ! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ! textView.setText(stringProvider.getString()); } ! }
Butterknife public class DaggerActivity extends DaggerBaseActivity {! ! @Inject DaggerStringProvider
stringProvider;! @InjectView(R.id.textView) TextView textView;! ! @Override! public void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.main);! Views.inject(this);! ! textView.setText(stringProvider.getString());! }! ! }
AndroidAnnotations @EActivity(R.layout.translate) // Sets content view to R.layout.translate! public class
TranslateActivity extends Activity {! @ViewById // Injects R.id.textInput! EditText textInput;! @ViewById(R.id.myTextView) // Injects R.id.myTextView! TextView result;! @AnimationRes // Injects android.R.anim.fade_in! Animation fadeIn;! @Click // When R.id.doTranslate button is clicked ! void doTranslate() {! translateInBackground(textInput.getText().toString());! }! @Background // Executed in a background thread! void translateInBackground(String textToTranslate) {! String translatedText = callGoogleTranslate(textToTranslate);! showResult(translatedText);! }! ! @UiThread // Executed in the ui thread! void showResult(String translatedText) {! result.setText(translatedText);! result.startAnimation(fadeIn);! } ! }
Presentation ! Application logic ! Domain Presentation ! Application logic
! Domain
Data Source Android has built in SQLite
Data Source ... but lacks ORM! ! Alternatives:! − GreenDAO!
− ORMLite
ORMLite @DatabaseTable(tableName = "accounts") public class Account { @DatabaseField(id =
true) private String name; @DatabaseField(canBeNull = false) private String password; Account() { // all persisted classes must define a no-arg constructor with at least package visibility } }
// you get the SQLiteOpenHelper from your Android Activity ConnectionSource
connectionSource = new AndroidConnectionSource(sqliteOpenHelper); ! // instantiate the DAO to handle Account with String id Dao<Account,String> accountDao = BaseDaoImpl.createDao(connectionSource, Account.class); ! TableUtils.createTable(connectionSource, Account.class); ! String name = "Jim Smith"; Account account = new Account(name, "_secret"); accountDao.create(account) ! Account account2 = accountDao.queryForId(name); connectionSource.close(); ORMLite
Testing
Testing • DVM or JVM! • Automation or Unit Tests
DVM • Requires a separate Test Project! • android.test or
Robotium
Android.test public class SimpleActivityTestStandard extends! ActivityUnitTestCase<SimpleActivity> {! public SimpleActivityTestStandard() {!
super(SimpleActivity.class);! }! ! public void setUp() throws Exception {! startActivity(new Intent(getInstrumentation().getTargetContext(),! SimpleActivity.class), null, null);! }! ! ! public void testLayout() {! SimpleActivity activity = getActivity();! assertNotNull(activity.findViewById(R.id.button1));! Button view = (Button) activity! .findViewById(com.example.test.target.R.id.button1);! assertEquals("My Button 1", view.getText());! }! }
Robotium ! public void testPreferenceIsSaved() throws Exception {! ! !
Solo solo = new Solo(getInstrumentation(), getActivity());! solo.sendKey(Solo.MENU);! solo.clickOnText("More");! solo.clickOnText("Preferences");! solo.clickOnText("Edit File Extensions");! assertTrue(solo.searchText("rtf"));! ! solo.clickOnText("txt");! solo.clearEditText(2);! solo.enterText(2, "robotium");! solo.clickOnButton("Save");! solo.goBack();! solo.clickOnText("Edit File Extensions");! ! assertTrue(solo.searchText("application/robotium")! ! ! solo.finishOpenedActivities();! );!
JVM public class RoboGuiceActivityTest { ! @Test public void shouldHaveISet()
throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); } }
JVM public class RoboGuiceActivityTest { ! @Test public void shouldHaveISet()
throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); assertThat(activity.getI(), equalTo(1)); } }
None
We have Mockito! lets mock something in our
Activity ...
Activity source code
Robolectric to the rescue Allows you to run ! you
android code ! on JVM
Robolectric @RunWith(RobolectricRoboTestRunner.class) public class RoboGuiceActivityTest { ! @Test public void
shouldHaveISet() throws Exception { RoboGuiceActivity activity = new RoboGuiceActivity(); activity.onCreate(null); assertThat(activity.getI(), equalTo(1)); } }
Robolectric + Mockito
Testing • DVM or JVM! • Automation or Unit Tests!
• Robotium or Robolectric! • Or both
Conclusion
More libraries?
More libraries
Solution?
Android Bootstrap • Fragments,Fragment Pager! • android-maven-plugin, Dagger! • ActionBarSherlock
! • ViewPagerIndicator! • http-request, GSON ! • Robotium http://www.androidbootstrap.com/
Build Systems • Gradle • Maven ! https://github.com/LArchaon/ android_mvn_template/
Q&A