building more with less
DESCRIPTION
Slides for the talk given at AppsWorld America 2013TRANSCRIPT
More With Lesswith android bootstrap
building
Wednesday, February 6, 13
@donnfelker
Wednesday, February 6, 13
Wednesday, February 6, 13
Building More With Less
Wednesday, February 6, 13
agenda
open sourcelibrariesexamplesbootstrap
Wednesday, February 6, 13
Wednesday, February 6, 13
Pay with Square GitHub Gaug.es
Wednesday, February 6, 13
tons of integration work
tons of open source
Wednesday, February 6, 13
open source
roboguiceaction bar sherlockhttp-requestgsonview pager indicatorrobotiummavenandroid maven pluginfragments
Wednesday, February 6, 13
roboguicedependency injection for android
roboguice.org
Wednesday, February 6, 13
class RoboWay extends RoboActivity { @InjectView(R.id.name) TextView name; @InjectView(R.id.thumbnail) ImageView thumbnail; @InjectResource(R.drawable.icon) Drawable icon; @InjectResource(R.string.app_name) String myName; @Inject LocationManager loc;
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); name.setText( "Hello, " + myName ); } }
roboguice.org
Wednesday, February 6, 13
User Interface
Service Layer
Persistence Layerwhat if I need a string
resource down here?
service layer: goo.gl/7NQVZ persistence layer: goo.gl/j5u74
roboguice.org
Wednesday, February 6, 13
public class UserRepository {
@InjectResource(R.string.public_key) String publicKey;
public void saveProfile(UserProfile profile) { // user publicKey to do some encryption // Now, save the encrypted profile to db/api/etc } }
roboguice.org
Wednesday, February 6, 13
public class UserRepository {
@InjectResource(R.string.public_key) String publicKey; @Inject protected AuthService authService;
public void saveProfile(UserProfile profile) { // Get auth token from auth service then save // user publicKey to do some encryption // Now, save the encrypted profile to api } }
roboguice.org
Wednesday, February 6, 13
must extend
RoboActivityRoboListActivityRoboFragmentActivityRoboListFragmentActivity...
roboguice.org
Wednesday, February 6, 13
roboguice.org
Wednesday, February 6, 13
action bar sherlockaction bar support for pre 3.x
actionbarsherlock.com
Wednesday, February 6, 13
Pay with Square GitHub Gaug.es
actionbarsherlock.com
Wednesday, February 6, 13
actionbarsherlock.com
Wednesday, February 6, 13
usage
getSupportActionBar()
native calls
supports theming
must use Sherlock themes as parent
actionbarsherlock.com
Wednesday, February 6, 13
must extend
SherlockActivitySherlockListActivitySherlockFragmentActivitySherlockListFragmentActivity...
actionbarsherlock.com
Wednesday, February 6, 13
ruh roh.roboguice and actionbarsherlock must both extend activity
actionbarsherlock.com
Wednesday, February 6, 13
roboguice-sherlockcombines roboguice and sherlock
github.com/rtyley/roboguice-sherlock
Wednesday, February 6, 13
public class CarouselActivity extends RoboSherlockFragmentActivity {
@InjectView(id.tpi_header) private TitlePageIndicator indicator; @InjectView(id.vp_pages) private ViewPager pager;
@Override protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.onCreate(savedInstanceState); setContentView(R.layout.carousel_view);
pager.setAdapter(new BootstrapPagerAdapter(getResources(), getSupportFragmentManager()));
indicator.setViewPager(pager); pager.setCurrentItem(1); }
}
github.com/rtyley/roboguice-sherlock
Wednesday, February 6, 13
github.com/rtyley/roboguice-sherlock
Wednesday, February 6, 13
http-request
kevinsawicki.github.com/http-request/
A simple convenience library for using a HttpURLConnection to make requests and access the response.
Wednesday, February 6, 13
kevinsawicki.github.com/http-request/
Wednesday, February 6, 13
kevinsawicki.github.com/http-request/
Wednesday, February 6, 13
Wednesday, February 6, 13
kevinsawicki.github.com/http-request/
Wednesday, February 6, 13
gsona library for working with json
code.google.com/p/google-gson/
Wednesday, February 6, 13
class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-‐args constructor }}
BagOfPrimitives obj = new BagOfPrimitives();Gson gson = new Gson();String json = gson.toJson(obj);
a pojo
serialization
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
deserialization
code.google.com/p/google-gson/
Wednesday, February 6, 13
woohoo! no more manual json parsing
code.google.com/p/google-gson/
Wednesday, February 6, 13
code.google.com/p/google-gson/
Wednesday, February 6, 13
view pager indicator
viewpagerindicator.com
Wednesday, February 6, 13
viewpagerindicator.com
Wednesday, February 6, 13
viewpagerindicator.com
Wednesday, February 6, 13
viewpagerindicator.com
Wednesday, February 6, 13
android-maven-pluginan easy to use maven plugin for android
code.google.com/p/maven-android-plugin/
Wednesday, February 6, 13
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-‐instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-‐v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<artifactId>android-‐bootstrap</artifactId> <packaging>apk</packaging> <name>Android Bootstrap app</name> <url>https://github.com/donnfelker/android-‐bootstrap</url>
<parent> <version>1.0</version> <groupId>com.donnfelker.android.bootstrap</groupId> <artifactId>android-‐bootstrap-‐parent</artifactId> </parent>
<properties> <abs.version>4.1.0</abs.version> </properties> <dependencies> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <scope>provided</scope> <version>${android.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>com.github.rtyley</groupId> <artifactId>roboguice-‐sherlock</artifactId> <version>1.4</version> </dependency> ...
<dependency> <groupId>com.github.kevinsawicki</groupId> <artifactId>wishlist</artifactId> <version>0.3</version> <type>apklib</type> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-‐library</artifactId> <version>1.3.RC2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-‐core</artifactId> <version>1.9.0</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-‐maven-‐plugin</artifactId> </plugin> <plugin> <artifactId>maven-‐compiler-‐plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>release</id> <!-‐-‐ via this activation the profile is automatically used when the release is done with the maven release plugin -‐-‐> <activation> <property> <name>performRelease</name> <value>true</value> </property> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-‐jarsigner-‐plugin</artifactId> <executions> <execution> <id>signing</id> <goals> <goal>sign</goal> <goal>verify</goal> </goals> <phase>package</phase> <inherited>true</inherited> <configuration> <removeExistingSignatures>true</removeExistingSignatures> <archiveDirectory /> <!-‐-‐ These values can either be placed directly into to file below, or provided via the command line during the build process as such: "mvn clean release -‐Dbootstrap.sign.keystore=foobar" ... etc. This will keep the keystore out of your file so no prying eyes can see. Also, if you have a ci (Continuous Integration) profile, these values can be passed in via the build server. -‐-‐> <keystore>${bootstrap.sign.keystore}</keystore> <alias>${bootstrap.sign.alias}</alias> <storepass>${bootstrap.sign.storepass}</storepass> <keypass>${bootstrap.sign.keypass}</keypass> <verbose>true</verbose> </configuration> </execution> </executions> </plugin> <!-‐-‐ the signed apk then needs to be zipaligned -‐-‐> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-‐maven-‐plugin</artifactId> <inherited>true</inherited> <configuration> <sign> <debug>false</debug> </sign> <zipalign> <verbose>true</verbose> <outputApk>${project.build.directory}/${project.artifactId}-‐${project.version}-‐signed-‐aligned.apk</outputApk> </zipalign> <manifest> <debuggable>false</debuggable> </manifest> </configuration> <executions> <execution> <id>alignApk</id> <phase>package</phase> <goals> <goal>zipalign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles></project>
Wednesday, February 6, 13
build process easier to manage
code.google.com/p/maven-android-plugin/
Wednesday, February 6, 13
resources
google group
ch14 of sonatype book goo.gl/3Waf5 (sample next)
code.google.com/p/maven-android-plugin/
Wednesday, February 6, 13
Wednesday, February 6, 13
code.google.com/p/maven-android-plugin/
Wednesday, February 6, 13
fragments android support library
Wednesday, February 6, 13
download from android sdk
Wednesday, February 6, 13
“its like selenium, but for android”
code.google.com/p/robotium
Wednesday, February 6, 13
public class EditorTest extends ActivityInstrumentationTestCase2<EditorActivity> {
private Solo solo;
public EditorTest() { super("com.test.editor", EditorActivity.class); }
public void setUp() throws Exception { solo = new Solo(getInstrumentation(), getActivity()); } public void testPreferenceIsSaved() throws Exception { solo.sendKey(Solo.MENU); solo.clickOnText("More"); solo.clickOnText("Preferences"); solo.clickOnText("Edit File Extensions"); Assert.assertTrue(solo.searchText("rtf")); solo.clickOnText("txt"); solo.clearEditText(2); solo.enterText(2, "robotium"); solo.clickOnButton("Save"); solo.goBack(); solo.clickOnText("Edit File Extensions"); Assert.assertTrue(solo.searchText("application/robotium")); }
@Override public void tearDown() throws Exception { solo.finishOpenedActivities(); }}
code.google.com/p/robotium
Wednesday, February 6, 13
code.google.com/p/robotium
Wednesday, February 6, 13
androidbootstrap.com
Wednesday, February 6, 13
Wednesday, February 6, 13
influences are from github and gaug.es
GitHub Gaug.es
androidbootstrap.com
Wednesday, February 6, 13
androidbootstrap.com
includesroboguiceaction bar sherlockhttp-requestgsonview pager indicatorrobotiummavenandroid maven pluginfragmentsapi consumptionimage downloadingimage cachingcache mechanismpojo supportand more...
ahhhhhh yeah
Wednesday, February 6, 13
uses
template for your next projectuse as a referencea how to tutorialproject MVP bootstrap
androidbootstrap.com
Wednesday, February 6, 13
q & a
androidbootstrap.com
Wednesday, February 6, 13
Thank You.questions? tweet @donnfelker
Wednesday, February 6, 13