The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
Android and the Seven Dwarfs from Devox'15
1. Snow White and the
Seven Dwarfs
Murat Yener
@yenerm
Android
2. who am I?
-Java, Android, web
-Android Dev @Intel
-Conference Speaker (JavaOne, Devoxx…)
-GDG Istanbul Organizer
-Book Author
-Java Champion
-GDE on Android
5. the princess…
well, the Android
had some problems
after eating an… apple
while waiting for the
prince charming…
6. can Seven Dwarfs help?
Butterknife
Dagger
Volley / OkHttp / Retrofit
GreenBus / Otto
GreenDAO / Schematic
Priority JobQueue
Timber / Hugo
7. Butterknife
Dependency Injection for views and actions
Cleaner code
Simple annotation based usage
Use Nullable to avoid exceptions
Based on compile time code generation
compile ‘com.jakewharton:butterknife:7.0.1’
8. class ExampleActivity extends Activity {
@Bind(R.id.title) TextView title;
@Bind(R.id.subtitle) TextView subtitle;
@Bind(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
10. //Simple listener injection
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
//Multi listener
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
if (door.hasPrizeBehind()) {
Toast.makeText(this, "You win!", LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Try again", LENGTH_SHORT).show();
}
}
11. ProGuard Configuration
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
12. Dagger
Fast dependency injection
Standard javax.inject (JSR 330)
Make your code easy to test
Compile time code generation (No reflection)
Complicated
Hard to do for ongoing project
compile 'com.google.dagger:dagger:2.0'
apt 'com.google.dagger:dagger-compiler:2.0'
13. @Module + @Provides: mechanism for providing
dependencies.
@Inject: mechanism for requesting dependencies.
@Component: bridge between modules and
injections
20. Volley
Simplest HttpClient fix for Android
Internal Queue
Internal Cache
Runs in a separate thread
Not good for large downloads
compile ‘com.mcxiaoke.volley:library-aar:1/0/0’
21. RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
//..
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
//..
}
});
queue.add(stringRequest);
//Cancel requests
queue.cancelAll(TAG);
23. Retrofit
REST Client for Java
Generates an implementation of the API
Uses annotation to describe URLs, query params
Object conversion to JSON request body
Multipart request body and file upload
Only good for REST APIs
compile 'com.squareup.retrofit:retrofit:1.9.0'
24.
public interface GitHubService {
@Headers("Cache-Control: max-age=640000")
@GET("/users/{user}/repos")
List<Repo> listRepos(@Path("user") String user);
@POST("/users/new")
void createUser(@Body User user, Callback<User> cb);
}
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.build();
GitHubService service = restAdapter.create(GitHubService.class);
List<Repo> repos = service.listRepos("octocat");
26. GreenRobot EventBus
Dispatches events through a bus
Event Driven
Very easy and clean implementation
Easily transfer data between components
Uses reflection on runtime
compile 'de.greenrobot:eventbus:2.4.0'
27. //Custom Event Object
public class SampleEvent {
private String message;
public SampleEvent(String message){
this.message=message;
}
}
//Caller
//geteventbus
eventBus.post(new SampleEvent(“An event”);
29. ProGuard Configuration
-keepclassmembers class ** {
public void onEvent*(**);
}
# Only required if you use AsyncExecutor
-keepclassmembers class * extends
de.greenrobot.event.util.ThrowableFailureEvent {
public <init>(java.lang.Throwable);
}
# Don't warn for missing support classes
-dontwarn de.greenrobot.event.util.*$Support
-dontwarn de.greenrobot.event.util.*$SupportManagerFragment
30. Otto
Event bus
decouple different parts of your application
Communication between components
Uses reflection
compile 'com.squareup:otto:1.3.8'
31.
Bus bus = new Bus();
bus.post(new AnswerAvailableEvent(42));
bus.register(this);
@Subscribe
public void answerAvailable(AnswerAvailableEvent event) {
// TODO: React to the event somehow!
}
32. -keepclassmembers class ** {
@com.squareup.otto.Subscribe public *;
@com.squareup.otto.Produce public *;
}
33. GreenDao
from the creators of GreenRobot EventBus
Standard SqLite
No create table… etc
Uses code generation for model and dao
compile 'de.greenrobot:greendao'
34. new DaoMaster.DevOpenHelper(this, "notes-db", null);
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
noteDao = daoSession.getNoteDao();
Note note = new Note(null, noteText, comment, new Date());
noteDao.insert(note);
35. -keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties
36. Schematic
Automatically generate ContentProviders
Backed by SQLite Database
Can be used w/ Android System
Loaders, SyncAdapter, Permissions
Harder to use (deal w/ Cursors)
apt ‘net.simonvt.schematic:schematic-compiler:0.6.0’
compile ‘net.simonvt.schematic:schematic:0.6.0’
37.
public interface ListColumns {
@DataType(INTEGER) @PrimaryKey @AutoIncrement String _ID = "_id";
@DataType(TEXT) @NotNull String TITLE = "title";
}
@Database(version = NotesDatabase.VERSION)
public final class NotesDatabase {
public static final int VERSION = 1;
@Table(ListColumns.class) public static final String LISTS = "lists";
}
@ContentProvider(authority = NotesProvider.AUTHORITY, database = NotesDatabase.class)
public final class NotesProvider {
public static final String AUTHORITY = "net.simonvt.schematic.sample.NotesProvider";
@TableEndpoint(table = NotesDatabase.LISTS)
public static class Lists {
@ContentUri(
path = Path.LISTS,
type = "vnd.android.cursor.dir/list",
defaultSort = ListColumns.TITLE + " ASC")
public static final Uri LISTS = Uri.parse("content://" + AUTHORITY + "/lists")
}
}
39. Priority JobQueue
Persistent queue for scheduling jobs
Easy to prioritize
Delay job execution
Group jobs for batch execution
Not really needed above 5.0
compile 'com.path:android-priority-jobqueue:1.1.2'
40. public class PostTweetJob extends Job {
public static final int PRIORITY = 1;
public PostTweetJob(String text) {
super(new Params(PRIORITY).requireNetwork().persist());
}
@Override
public void onAdded() {}
@Override
public void onRun() throws Throwable {
webservice.postTweet(text);
}
@Override
protected boolean shouldReRunOnThrowable(Throwable throwable) {
}
}
42. Timber
Logger with a small, extensible API
Default behavior: Nothing
Behavior is added through Tree instances.
Install instance by calling Timber.plant()
DebugTree: output logs for debug builds and auto
tag generation
compile 'com.jakewharton.timber:timber:4.1.0'
43.
/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
@Override protected void log(int priority, String tag,
String message, Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
FakeCrashLibrary.log(priority, tag, message);
if (t != null) {
if (priority == Log.ERROR) {
FakeCrashLibrary.logError(t);
} else if (priority == Log.WARN) {
FakeCrashLibrary.logWarning(t);
}
}
}
}