Android code puzzlers + tips & tricks
-
Upload
nljug -
Category
Technology
-
view
1.418 -
download
0
Transcript of Android code puzzlers + tips & tricks
![Page 1: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/1.jpg)
The Dutch Android User Group http://www.dutchaug.org
Android Code Puzzlers
Can you solve all our challenges?NLJUG JFall
Wednesday November 6th
!Johan Pelgrim & Hugo Visser
+TIPS & TRICKS
![Page 2: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/2.jpg)
The Dutch Android User Group http://www.dutchaug.org
• Android Developer!
• Working at VX Company http://www.vxcompany.com!
• Organizer The Dutch Android User Group!
• Written Android articles and recipes for http://www.androidcookbook.com
Johan Pelgrim @jowipe
![Page 3: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/3.jpg)
The Dutch Android User Group http://www.dutchaug.org
• Android Developer!
• Working at Qbushttp://www.qbus-ict.nl!
• Organizer The Dutch Android User Group!
• Developer of Rainy Days and Figure Running and ...
Hugo Visser @botteaap
![Page 4: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/4.jpg)
The Dutch Android User Group http://www.dutchaug.org
• Open Group - Dutch Focus & Spread - Free to join!!
• Monthly meetups http://www.dutchaug.org !
• Started nov 2011 (at droidconNL)!
• Foundation since feb 2013!
• We are a Google Developer Group (GDG)!
• @dutchaug #dutchaug!
• The Dutch Android User Group
DutchAUG
![Page 5: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/5.jpg)
The Dutch Android User Group http://www.dutchaug.org
DutchAUG
Wiebe Elsinga!
Itude Mobile
Dennis Geurts!Luminis
Hugo Visser!Qbus
Johan Pelgrim!
VX Company
![Page 6: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/6.jpg)
The Dutch Android User Group http://www.dutchaug.org
DutchAUG Main sponsor
http://www.nspyre.nl/android
![Page 7: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/7.jpg)
The Dutch Android User Group http://www.dutchaug.org
DutchAUG Main sponsor
http://www.vxcompany.com
![Page 8: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/8.jpg)
The Dutch Android User Group http://www.dutchaug.org
![Page 9: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/9.jpg)
The Dutch Android User Group http://www.dutchaug.org
DutchAUG Upcoming meetup
Android 4.4 KitKat
& Play Services 4
January
Utrecht
![Page 10: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/10.jpg)
The Dutch Android User Group http://www.dutchaug.org
Android Code PuzzlersCan you solve all our challenges?
• We present a puzzle
• You chew on it for a while
• If you know the answer(and more importantly...why) you win!
![Page 11: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/11.jpg)
The Dutch Android User Group http://www.dutchaug.org
Everybody Ready?
![Page 12: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/12.jpg)
The Dutch Android User Group http://www.dutchaug.org
Layout puzzleWhich picture matches this layout:!<?xml version="1.0" encoding="utf-8"?>!<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"! android:layout_width="fill_parent"! android:layout_height="fill_parent" >! <TextView! android:layout_height="wrap_content"! android:layout_width="fill_parent"! android:text="Layout Puzzle 1"! android:layout_gravity="center"! android:gravity="center_vertical" />!</RelativeLayout>!!A) B) C)!
puzzle
![Page 13: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/13.jpg)
The Dutch Android User Group http://www.dutchaug.org
Layout puzzle puzzleWhich picture matches this layout:!<?xml version="1.0" encoding="utf-8"?>!<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"! android:layout_width="fill_parent"! android:layout_height="fill_parent" >! <TextView! android:layout_height="wrap_content"! android:layout_width="fill_parent"! android:text="Layout Puzzle 1"! android:layout_gravity="center"! android:gravity="center_vertical" />!</RelativeLayout>!!A) B) C)!
![Page 14: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/14.jpg)
The Dutch Android User Group http://www.dutchaug.org
You Only Frag TwiceSingle activity, with a single fragment!!
Activity:!protected void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.single_fragment);! if (savedInstanceState == null) {! getFragmentManager().beginTransaction().add(R.id.single_fragment, ! new YouOnlyFragTwiceFragment());! }!}!!single_fragment.xml:!<?xml version="1.0" encoding="utf-8"?>!<merge>!<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"! android:id="@+id/single_fragment"! android:layout_width="fill_parent"! android:layout_height="fill_parent" />!</merge>!!What happens when the Activity is started?!A) Fragment is shown and filling the screen!B) Activity crashes!C) Nothing is shown
puzzle
![Page 15: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/15.jpg)
The Dutch Android User Group http://www.dutchaug.org
You Only Frag TwiceSingle activity, with a single fragment!!
Activity:!protected void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.single_fragment);! if (savedInstanceState == null) {! getFragmentManager().beginTransaction().add(R.id.single_fragment, ! new YouOnlyFragTwiceFragment());! }!}!!single_fragment.xml:!<?xml version="1.0" encoding="utf-8"?>!<merge>!<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"! android:id="@+id/single_fragment"! android:layout_width="fill_parent"! android:layout_height="fill_parent" />!</merge>!!What happens when the Activity is started?!A) Fragment is shown and filling the screen!B) Activity crashes!C) Nothing is shown
puzzle
C) Nothing is shown
.commit();
![Page 16: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/16.jpg)
The Dutch Android User Group http://www.dutchaug.org
License to clickFragment layout:!<Button android:text="Don't click me!"! android:layout_centerInParent="true"! android:onClick="clicked" />!!In activity:!public void clicked(View v) {! Toast.makeText(this, "onClick from activity", 1).show();!}!!!In fragment:!public void clicked(View v) {! Toast.makeText(getActivity(), "onClick from fragment", 1).show();!}!!What happens when I tap the button?!A) Toast “onClick from activity” is shown!B) Toast “onClick from fragment” is shown!C) First “onClick from activity” then “onClick from fragment” is shown!D) First “onClick from fragment” then “onClick from activity” is shown!
puzzle
![Page 17: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/17.jpg)
The Dutch Android User Group http://www.dutchaug.org
License to clickFragment layout:!<Button android:text="Don't click me!"! android:layout_centerInParent="true"! android:onClick="clicked" />!!In activity:!public void clicked(View v) {! Toast.makeText(this, "onClick from activity", 1).show();!}!!!In fragment:!public void clicked(View v) {! Toast.makeText(getActivity(), "onClick from fragment", 1).show();!}!!What happens when I tap the button?!A) Toast “onClick from activity” is shown!B) Toast “onClick from fragment” is shown!C) First “onClick from activity” then “onClick from fragment” is shown!D) First “onClick from fragment” then “onClick from activity” is shown!
puzzle
A) Toast “onClick from activity” is shown
![Page 18: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/18.jpg)
The Dutch Android User Group http://www.dutchaug.org
A view to a killpuzzle
public class GetViewActivity extends Activity {!!! !! @Override!! protected void onCreate(Bundle savedInstanceState) {!! ! super.onCreate(savedInstanceState);!! ! setContentView(R.layout.view_to_a_kill);!! ! !! ! getFragmentManager().beginTransaction()!! ! ! .replace(R.id.content, new GetViewFragment())!! ! ! .commit();!! }!! !! !}!
![Page 19: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/19.jpg)
The Dutch Android User Group http://www.dutchaug.org
A view to a killpuzzle
What happens when the Activity is started?!A) Shows a Toast “my name is droid, android”!B) does nothing but showing a view!C) Exception in Inflater.inflate()!D) Exception in GetViewFragment.onCreate()!E) Exception in Fragment.onCreateView()
public class GetViewFragment extends Fragment {!!! @Override! public void onCreate(Bundle savedInstanceState) {!! ! super.onCreate(savedInstanceState);!!! ! getView().setOnClickListener(new View.OnClickListener() {!! ! ! @Override! public void onClick(View v) {!! ! ! ! Toast.makeText(getActivity(), "My name is droid, android", 1);!! ! ! }!! ! });!! }!!! @Override! public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {!! ! return inf.inflate(R.layout.fragment_get_view, view);!! }!!}!
![Page 20: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/20.jpg)
The Dutch Android User Group http://www.dutchaug.org
A view to a killpuzzle
What happens when the Activity is started?!A) Shows a Toast “my name is droid, android”!B) does nothing but showing a view!C) Exception in Inflater.inflate()!D) Exception in GetViewFragment.onCreate()!E) Exception in Fragment.onCreateView()
D) Exception in GetViewFragment.onCreate()
public class GetViewFragment extends Fragment {!!! @Override! public void onCreate(Bundle savedInstanceState) {!! ! super.onCreate(savedInstanceState);!!! ! getView().setOnClickListener(new View.OnClickListener() {!! ! ! @Override! public void onClick(View v) {!! ! ! ! Toast.makeText(getActivity(), "My name is droid, android", 1);!! ! ! }!! ! });!! }!!! @Override! public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {!! ! return inf.inflate(R.layout.fragment_get_view, view);!! }!!}!
![Page 21: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/21.jpg)
The Dutch Android User Group http://www.dutchaug.org
A view to a killpuzzle
What happens when the Activity is started?!A) Shows a Toast “my name is droid, android”!B) does nothing but showing a view!C) Exception in Inflater.inflate()!D) Exception in GetViewFragment.onCreate()!E) Exception in Fragment.onCreateView()
D) Exception in GetViewFragment.onCreate()
public class GetViewFragment extends Fragment {!!! @Override! public void onCreate(Bundle savedInstanceState) {!! ! super.onCreate(savedInstanceState);!!! ! getView().setOnClickListener(new View.OnClickListener() {!! ! ! @Override! public void onClick(View v) {!! ! ! ! Toast.makeText(getActivity(), "My name is droid, android", 1);!! ! ! }!! ! });!! }!!! @Override! public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {!! ! return inf.inflate(R.layout.fragment_get_view, view);!! }!!}!
![Page 22: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/22.jpg)
The Dutch Android User Group http://www.dutchaug.org
TIPAlpha / Beta builds
![Page 23: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/23.jpg)
The Dutch Android User Group http://www.dutchaug.org
Live And Let Diepublic class ToastFragment extends Fragment {! ...! public void onDestroy() {! super.onDestroy();! new ToastingAsyncTask().execute(null,null,null);! }!! class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{! protected Long doInBackground(String... params) {! try {Thread.sleep(500);} catch (InterruptedException e) {}! return null;! }! protected void onPostExecute(Long result) {! if (getActivity() == null){! System.out.println(getString(R.string.no_activity));! }else{! System.out.println(getString(R.string.activity_leak));! } ! }! } !! what happens when I change the orientation?! A) Sysout: no_activity! B) Sysout: activity_leak! C) Sysout: null! D) Exception in getActivity ! E) Exception in getString
puzzle
![Page 24: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/24.jpg)
The Dutch Android User Group http://www.dutchaug.org
Live And Let Diepublic class ToastFragment extends Fragment {! ...! public void onDestroy() {! super.onDestroy();! new ToastingAsyncTask().execute(null,null,null);! }!! class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{! protected Long doInBackground(String... params) {! try {Thread.sleep(500);} catch (InterruptedException e) {}! return null;! }! protected void onPostExecute(Long result) {! if (getActivity() == null){! System.out.println(getString(R.string.no_activity));! }else{! System.out.println(getString(R.string.activity_leak));! } ! }! } !! what happens when I change the orientation?! A) Sysout: no_activity! B) Sysout: activity_leak! C) Sysout: null! D) Exception in getActivity ! E) Exception in getString
puzzle
E) Exception in getString...
![Page 25: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/25.jpg)
The Dutch Android User Group http://www.dutchaug.org
Live And Let Diepublic class ToastFragment extends Fragment {! ...! public void onDestroy() {! super.onDestroy();! new ToastingAsyncTask().execute(null,null,null);! }!! class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{! protected Long doInBackground(String... params) {! try {Thread.sleep(500);} catch (InterruptedException e) {}! return null;! }! protected void onPostExecute(Long result) {! if (getActivity() == null){! System.out.println(getString(R.string.no_activity));! }else{! System.out.println(getString(R.string.activity_leak));! } ! }! } !! what happens when I change the orientation?! A) Sysout: no_activity! B) Sysout: activity_leak! C) Sysout: null! D) Exception in getActivity ! E) Exception in getString
puzzle
LogCat:
java.lang.IllegalStateException: Fragment ToastFragment not attached to
Activity!!A Context holds your Resources!!!Know about the life cycle of Activities, Fragments, Services!!!And...!
!“Use the source Luke!”!
![Page 26: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/26.jpg)
The Dutch Android User Group http://www.dutchaug.org
Live And Let Die
!public class Fragment ...!!public final String getString(int resId) {! return getResources().getString(resId);!}!!final public Resources getResources() {! if (mActivity == null) {! throw new IllegalStateException("Fragment " + this + ! " not attached to Activity");! }! return mActivity.getResources();!}!!
puzzle
![Page 27: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/27.jpg)
The Dutch Android User Group http://www.dutchaug.org
From Fragment with love
public class ActionbarFragment extends Fragment {!...! public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {! setHasOptionsMenu(true);! return inf.inflate(R.layout.fragment_get_view, null);! }! public boolean onOptionsItemSelected(MenuItem item) {! Toast.makeText(getActivity(), "from Fragment", 1).show();! return true;! } !}!!public class ActionbarActivity extends Activity {!...! public boolean onOptionsItemSelected(MenuItem item) {! Toast.makeText(this, "from Activity", 1).show();! return true;! } !}!!When clicking an ActionBar item: !a) Shows toast “from Activity”!b) Shows toast “from Fragment”!c) Shows both toasts!d) Shows toast depending on who created the menu item
puzzle
![Page 28: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/28.jpg)
The Dutch Android User Group http://www.dutchaug.org
From Fragment with love
public class ActionbarFragment extends Fragment {!...! public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {! setHasOptionsMenu(true);! return inf.inflate(R.layout.fragment_get_view, null);! }! public boolean onOptionsItemSelected(MenuItem item) {! Toast.makeText(getActivity(), "from Fragment", 1).show();! return true;! } !}!!public class ActionbarActivity extends Activity {!...! public boolean onOptionsItemSelected(MenuItem item) {! Toast.makeText(this, "from Activity", 1).show();! return true;! } !}!!When clicking an ActionBar item: !a) Shows toast “from Activity”!b) Shows toast “from Fragment”!c) Shows both toasts!d) Shows toast depending on who created the menu itemA) Shows toast “from Activity”
puzzle
![Page 29: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/29.jpg)
The Dutch Android User Group http://www.dutchaug.org
Support Library
• Fragment / ListFragment / DialogFragment!
• ViewPager!
• LoaderManager / CursorLoader!
• Many many compat classes!
• LruCache / SparseArray!
• Navigation Drawer (DrawerLayout)
Development
tips & tricks
![Page 30: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/30.jpg)
The Dutch Android User Group http://www.dutchaug.org
Google Play Services
• Google Maps v2!
• Geofencing!
• Google+ Sign-in!
• Activity Recognition!
• Google Cloud Messaging!
• And more...
Development
tips & tricks
![Page 31: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/31.jpg)
The Dutch Android User Group http://www.dutchaug.org
Casino Royalpublic class AsyncTaskActivity extends Activity{!...!protected void onResume() {! super.onResume();! TextView testV = (TextView) findViewById(R.id.async_text_1);! new WritingAsyncTask(testV,2000).execute("Bob");! new WritingAsyncTask(testV,500).execute("loves");! new WritingAsyncTask(testV,100).execute("Alice");!} ...!!public class WritingAsyncTask extends AsyncTask<String, Void, String> {...! private final TextView view; //set in Constructor! private final int timeout; //set in Constructor! protected String doInBackground(String... params) {! try {Thread.sleep(timeout);} catch (InterruptedException e) {}! return params[0];! }! protected void onPostExecute(String result) {! view.setText(view.getText()+" "+result);! }!}!!What is shown in the TextView when I start the Activity on my Galaxy Nexus: !a) Alice loves Bob!b) Bob Alice loves!c) Bob loves Alice!d) There is not enough information to decide
puzzle
![Page 32: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/32.jpg)
The Dutch Android User Group http://www.dutchaug.org
Casino Royalpublic class AsyncTaskActivity extends Activity{!...!protected void onResume() {! super.onResume();! TextView testV = (TextView) findViewById(R.id.async_text_1);! new WritingAsyncTask(testV,2000).execute("Bob");! new WritingAsyncTask(testV,500).execute("loves");! new WritingAsyncTask(testV,100).execute("Alice");!} ...!!public class WritingAsyncTask extends AsyncTask<String, Void, String> {...! private final TextView view; //set in Constructor! private final int timeout; //set in Constructor! protected String doInBackground(String... params) {! try {Thread.sleep(timeout);} catch (InterruptedException e) {}! return params[0];! }! protected void onPostExecute(String result) {! view.setText(view.getText()+" "+result);! }!}!!What is shown in the TextView when I start the Activity on my Galaxy Nexus: !a) Alice loves Bob!b) Bob Alice loves!c) Bob loves Alice!d) There is not enough information to decideD) There is not enough information to decide...
puzzle
![Page 33: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/33.jpg)
The Dutch Android User Group http://www.dutchaug.org
Casino Royal
!You need to know the targetSdkVersion and the device OS version of the target device!!android:targetSdkVersion < 13: parallel execution!!android:targetSdkVersion >= 13 ! && Device OS >= 14: serial execution!!!This is what we see in AsyncTask.Java:!!public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); !private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;!!!You are in control of the type of execution in SDK >= 11!!executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,…);!!
puzzle
D) There is not enough information to decide...
![Page 34: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/34.jpg)
The Dutch Android User Group http://www.dutchaug.org
Development
tips & tricks
Casino Royal
android:minSdkVersion=“14”!!Go for minSdkVersion=“14” (Android 4.0 / Ice Cream Sandwich)!Second best minSdkVersion = “10” (Android 2.3.3 / Gingerbread)!E.g. Google Play Services new API’s > 10!Don’t do anything lower than 10!!android:targetSdkVersion=“19”!!Always set this to the latest Android API level!!!android:maxSdkVersion!!Don’t use this. Everything is backwards compatible by default.!!!
![Page 35: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/35.jpg)
The Dutch Android User Group http://www.dutchaug.org
Custom ViewsView:!
public class MyCustomView extends LinearLayout {! public MyCustomView(Context context, AttributeSet attrs) {! super(context, attrs);! LayoutInflater.from(context).inflate(R.layout.component, this, true);! // more stuff here! }!}!!component.xml!<?xml version="1.0" encoding="utf-8"?>!<LinearLayout ... >! <TextView android:id="@+id/label” ... />! <EditText android:id="@+id/value” ... />!</LinearLayout>!!layout.xml!<LinearLayout android:orientation="vertical">! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>!</LinearLayout>!!When you inflate layout.xml in an Activity: !a) Everything works fine!b) Exception on inflating the XML!c) Everything appears to look fine, but there are subtle bugs!d) The app crashes when entering text in the first EditText!!Hint: How does the view tree look when the layout is inflated?!
puzzle
![Page 36: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/36.jpg)
The Dutch Android User Group http://www.dutchaug.org
Custom ViewsView:!
public class MyCustomView extends LinearLayout {! public MyCustomView(Context context, AttributeSet attrs) {! super(context, attrs);! LayoutInflater.from(context).inflate(R.layout.component, this, true);! // more stuff here! }!}!!component.xml!<?xml version="1.0" encoding="utf-8"?>!<LinearLayout ... >! <TextView android:id="@+id/label” ... />! <EditText android:id="@+id/value” ... />!</LinearLayout>!!layout.xml!<LinearLayout android:orientation="vertical">! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>! <org.dutchaug.androidpuzzlers.customviewmess.MyCustomView/>!</LinearLayout>!!When you inflate layout.xml in an Activity: !a) Everything works fine!b) Exception on inflating the XML!c) Everything appears to look fine, but there are subtle bugs!d) The app crashes when entering text in the first EditText!!Hint: How does the view tree look when the layout is inflated?!
C) Everything appears to look fine, but there! are subtle bugs
puzzle
![Page 37: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/37.jpg)
The Dutch Android User Group http://www.dutchaug.org
Custom ViewsAfter inflate:!!<LinearLayout>!<LinearLayout ... >! <TextView android:id="@+id/label" ... />! <EditText android:id="@+id/value" ... />!</LinearLayout>!<LinearLayout ...>! <TextView android:id="@+id/label" ... />! <EditText android:id="@+id/value" ... />!</LinearLayout>!<LinearLayout ...>! <TextView android:id="@+id/label" ... />! <EditText android:id="@+id/value" ... />!</LinearLayout>!</LinearLayout>!!Oops:!!1.OnSaveInstanceState is called in LinearLayout !2.LinearLayout calls saveHierarchyState(SparseArray<Parcelable> state) on children!3.Child returns Parcelable which is put in the state and keyed on the view id!4.When state is restored, there is a single value for label, and a single value for value.!!
puzzle
![Page 38: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/38.jpg)
The Dutch Android User Group http://www.dutchaug.org
@Override!protected void onStart() {!! super.onStart();!! ! !! String[] longList = new String[1000000];!! Intent intent = new Intent(Intent.ACTION_SEND);!! intent.setType("text/plain");!! intent.putExtra("dutchaug", longList);!! startActivityForResult(intent, 100);!!}!!!What happens when the activity is started?!A) OutOfMemoryException in onCreate() B) IllegalArgumentException in onCreate() C) Nothing happens, direct invocation of onActivityResult (with cancel code) D) Nothing happens, no invocation of onActivityResult E) System-Intent-Picker for "sent" action will be shown normally
puzzleThe World Is Not Enough
![Page 39: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/39.jpg)
The Dutch Android User Group http://www.dutchaug.org
@Override!protected void onStart() {!! super.onStart();!! ! !! String[] longList = new String[1000000];!! Intent intent = new Intent(Intent.ACTION_SEND);!! intent.setType("text/plain");!! intent.putExtra("dutchaug", longList);!! startActivityForResult(intent, 100);!!}!!!What happens when the activity is started?!A) OutOfMemoryException in onCreate() B) IllegalArgumentException in onCreate() C) Nothing happens, direct invocation of onActivityResult (with cancel code) D) Nothing happens, no invocation of onActivityResult E) System-Intent-Picker for "sent" action will be shown normally
puzzleThe World Is Not Enough
D) Nothing happens, no invocation of onActivityResult...
![Page 40: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/40.jpg)
The Dutch Android User Group http://www.dutchaug.org
Logcat shows:!26-02 17:25:53.391: E/JavaBinder(6247): !!! FAILED BINDER TRANSACTION !!!!!The Binder transaction failed because it was too large.!!During a remote procedure call, the arguments and the return value of the call are transferred as Parcel objects stored in the Binder transaction buffer. If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown.!!The Binder transaction buffer has a limited fixed size (1Mb) which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.!
puzzleThe World Is Not Enough
![Page 41: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/41.jpg)
The Dutch Android User Group http://www.dutchaug.org
But some more:No more puzzles...
![Page 42: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/42.jpg)
The Dutch Android User Group http://www.dutchaug.org
compound drawable
<RelativeLayout ...>!! <LinearLayout ...>! <ImageView! android:layout_marginRight="15dp"! android:layout_width="wrap_content"! android:layout_height="wrap_content"! android:src="@drawable/dutchaug" />!! <TextView! android:layout_width="wrap_content"! android:layout_height="wrap_content"! android:text="DutchAUG" />! </LinearLayout>!! <!-- this does not require a nested LinearLayout -->!! <TextView! android:drawableLeft="@drawable/dutchaug"! android:drawablePadding="15dp"! android:layout_width="wrap_content"! android:layout_height="wrap_content"! android:text="DutchAUG" />!!</RelativeLayout>!
Development
tips & tricks
DutchAUG
![Page 43: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/43.jpg)
The Dutch Android User Group http://www.dutchaug.org
Level list drawableDevelopment
tips & tricks
!Somewhere in a BaseAdapter far, far away...!! if (error) {! Drawable d = getContext().getResources().getDrawable(R.drawable.error);! mTextView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null)! } else {! Drawable d = getContext().getResources().getDrawable(R.drawable.ok);! mTextView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null) ! }!
• Drawables have setLevel() 0...10000!
• Assign drawable level range
![Page 44: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/44.jpg)
The Dutch Android User Group http://www.dutchaug.org
Level list drawable:!!<level-list xmlns:android="http://schemas.android.com/apk/res/android">! <item android:maxLevel="0" android:drawable="@drawable/ic_state_ok" />! <item android:maxLevel="1" android:drawable="@drawable/ic_state_error" /> ! <!-- more variants... -->!</level-list>!!BetterAdapter.java!!// Constants please!!private static final int LEVEL_OK = 0;!private static final int LEVEL_ERROR = 1;!!if (error) {! mTextView.getCompoundDrawables()[0].setLevel(LEVEL_ERROR)!} else {! mTextView.getCompoundDrawables()[0].setLevel(LEVEL_OK)!}!!Or less verbose:! !mTextView.getCompoundDrawables()[0].setLevel(error ? LEVEL_ERROR : LEVEL_OK)!!
Development
tips & tricks
Level list drawable
![Page 45: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/45.jpg)
The Dutch Android User Group http://www.dutchaug.org
android.text.format.DateUtilsDevelopment
tips & tricks
•CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)!
•now – System.currentTimeMillis()!
•minResolution – e.g. SECOND_IN_MILLIS so the smallest unit of time will be seconds.!
•English example: “2 seconds ago”!
•Or in German: “Vor 2 Sekunden”
![Page 46: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/46.jpg)
android.text.TextUtils
•boolean isDigitsOnly(CharSequence str)!
•boolean isEmpty(CharSequence str)!
•String htmlEncode(String s)!
•CharSequence commaEllipsize(...)!
•CharSequence ellipsize(...)
Development
tips & tricks
![Page 47: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/47.jpg)
The Dutch Android User Group http://www.dutchaug.org
fromHTML
TextView view = (TextView)findViewById(R.id.sampleText);!String formattedText = getString(R.string.htmlFormattedText);!Spanned result = Html.fromHtml(formattedText);!view.setText(result);
<string name="htmlFormattedText">! <![CDATA[! <p>Text with markup for! <strong>bold</strong>! and <em>italic</em> text.</p>! <p>There is also support for a ! <tt>monospaced</tt>font. ! But no use for the ! <code>code</code> tag!</p>! ]]>!</string>
Development
tips & tricks
![Page 48: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/48.jpg)
The Dutch Android User Group http://www.dutchaug.org
Annotation Processors
• @InjectView (Butter Knife) http://jakewharton.github.io/butterknife/!
• @Frozen @Argumenthttps://bitbucket.org/hvisser/bundles!
• Android Annotationshttp://androidannotations.org
Development
tips & tricks
![Page 49: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/49.jpg)
The Dutch Android User Group http://www.dutchaug.org
Annotation ProcessorsDevelopment
tips & tricks public class MainActivityBefore extends Activity {!! int mLoginCount;! String mCurrentUser;! long mSessionExpiresAt;!! @Override! protected void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.activity_main);!! if (savedInstanceState != null) {! mLoginCount = savedInstanceState.getInt("login_count");! mCurrentUser = savedInstanceState.getString("user");! mSessionExpiresAt = savedInstanceState.getLong("session_expire");!! DemoBeforeFragment fragment = new DemoBeforeFragment();! Bundle args = new Bundle();! args.putString("greeting", "Hello!");! fragment.setArguments(args);!! getFragmentManager().beginTransaction().add(R.id.main_fragment, fragment).commit();! }!! }!! @Override! protected void onSaveInstanceState(Bundle outState) {! super.onSaveInstanceState(outState);! outState.putInt("login_count", mLoginCount);! outState.putString("user", mCurrentUser);! // something is not quite right here...! outState.putLong("session_expre", mSessionExpiresAt);! }!}!
![Page 50: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/50.jpg)
The Dutch Android User Group http://www.dutchaug.org
Annotation ProcessorsDevelopment
tips & tricks public class DemoBeforeFragment extends Fragment {! TextView mTextView;! Button mLoginButton;!! String mGreeting;! int mVisitCount = 0;!! @Override! public void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! mGreeting = getArguments().getString("greeting");! mVisitCount = getArguments().getInt("visit_count", 0);! }!! @Override! public View onCreateView(LayoutInflater inflater, ViewGroup container, ! Bundle savedInstanceState) {! View view = inflater.inflate(R.layout.activity_main, container, false);! mTextView = (TextView) view.findViewById(R.id.greeting);! mLoginButton = (Button) view.findViewById(R.id.login);! mTextView.setText(mGreeting);! return view;! }!}
![Page 51: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/51.jpg)
The Dutch Android User Group http://www.dutchaug.org
Annotation ProcessorsDevelopment
tips & tricks public class MainActivityAfter extends Activity {!! @Frozen int mLoginCount;! @Frozen String mCurrentUser;! @Frozen long mSessionExpiresAt;!! @Override! protected void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.activity_main);! MainActivityAfterState.restoreInstanceState(this, savedInstanceState);! if (savedInstanceState != null) {! Fragment fragment = DemoAfterFragmentBuilder.newDemoAfterFragment("Hello");! getFragmentManager().beginTransaction().add(R.id.main_fragment,! fragment).commit();! }! }!! @Override! protected void onSaveInstanceState(Bundle outState) {! super.onSaveInstanceState(outState);! MainActivityAfterState.saveInstanceState(this, outState);! }!}
![Page 52: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/52.jpg)
The Dutch Android User Group http://www.dutchaug.org
Annotation ProcessorsDevelopment
tips & tricks public class DemoAfterFragment extends Fragment {! @InjectView(R.id.greeting) TextView mTextView;! @InjectView(R.id.login) Button mLoginButton;!! @Argument String mGreeting;! @Argument(required=false) int mVisitCount = 0;!! @Override! public void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! DemoAfterFragmentBuilder.injectArguments(this);! }!! @Override! public View onCreateView(LayoutInflater inflater, ViewGroup container, ! Bundle savedInstanceState) {! View view = inflater.inflate(R.layout.activity_main, container, false);!! Views.inject(this, view);!! mTextView = (TextView) view.findViewById(R.id.greeting);! mLoginButton = (Button) view.findViewById(R.id.login);! mTextView.setText(mGreeting);! return view;! }!}
![Page 53: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/53.jpg)
The Dutch Android User Group http://www.dutchaug.org
• Code optimalizations E.g. Log.d has no side effects!
• Code reduction Unused methods / classes!
• Code obfuscation (secure?) DexGuard does a better job!
Proguard
Watch Eric LaFortune on http://youtube.com/dutchaug
![Page 54: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/54.jpg)
The Dutch Android User Group http://www.dutchaug.org
Use Lint
• From Eclipse!
• lint <project dir>!
• Jenkins lint plugin
Development
tips & tricks
![Page 55: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/55.jpg)
The Dutch Android User Group http://www.dutchaug.org
Jenkins
Watch Christopher Orr on http://youtube.com/dutchaug
• Automate Android build, test and deploy E.g. use Jenkins build number in your AndroidManifest!
• “There’s a plug-in for that!”
![Page 56: Android code puzzlers + tips & tricks](https://reader034.fdocuments.us/reader034/viewer/2022042714/554f8300b4c905d25b8b4b1e/html5/thumbnails/56.jpg)
The Dutch Android User Group http://www.dutchaug.org
THE END
Thanks for your participation!
Get the puzzle code
http://bit.ly/android-puzzlers