SlideShare uma empresa Scribd logo
1 de 40
Android Code
Puzzles
droidcon.nl
● Danny Preussler:
● Lead Engineer Android
ebay Kleinanzeigen, Germany
● Path to the green side:
C++ -> Java SE -> JME -> BlackBerry -> Android
● My current Droids:
Galaxy Nexus, Nexus 7, Logitech Revue, I'm watch
● My 1st Droid was a:
Motorola Droid/Milestone
● Johannes Orgis:
● Software Development Manager
Cortado Mobile Clients
Cortado AG, Germany
● Path to the green side:
Java EE -> Java SE -> BlackBerry -> Android
● My current Droids:
Galaxy Nexus, Nexus 7
● My 1st Droid was a:
HTC Magic
● We show code snippets that does something or maybe not
● Look out for hidden pitfalls
● All Puzzles are run with Android 4.1 Jelly Beans
There should be no platform depended puzzles
● Test yourself!
● Raise your hands when we ask you!
● Guess if you're unsure!
● Learn something if you were wrong!
● Have fun! :D
public class DroidConPuzzle extends Activity {
@Override
protected void onCreate(Bundle saved) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.add(android.R.id.content, new Fragment() {
@Override
public View onCreateView(LayoutInflater inf,
ViewGroup view, Bundle saved)
{
View v = inf.inflate(R.layout.fragment_default, null);
return null;
}
});
trans.commit();
super.onCreate(saved);
}
}
For your eyes only...
a) NullPointerException in Inflater.inflate()
b) NullPointerException after onCreateView()
c) llegalStateException in super.onCreate()
d) llegalStateException in Transaction.commit()
e) shows an empty screen
public class DroidConPuzzle extends Activity {
@Override
protected void onCreate(Bundle saved) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.add(android.R.id.content, new Fragment() {
@Override
public View onCreateView(LayoutInflater inf,
ViewGroup view, Bundle saved)
{
View v = inf.inflate(R.layout.fragment_default, null);
return null;
}
});
trans.commit();
super.onCreate(saved);
}
}
For your eyes only...
a) NullPointerException in Inflater.inflate()
b) NullPointerException after onCreateView()
c) llegalStateException in super.onCreate()
d) llegalStateException in Transaction.commit()
e) shows an empty screen
public class DroidConPuzzle extends Activity {
@Override
protected void onCreate(Bundle saved) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.add(android.R.id.content, new Fragment() {
@Override
public View onCreateView(LayoutInflater inf,
ViewGroup view, Bundle saved)
{
View v = inf.inflate(R.layout.fragment_default, null);
return null;
}
});
trans.commit();
super.onCreate(saved);
}
}
For your eyes only...
e) shows an empty screen BUT after rotation it will crash:
● Fragments need to be public:
not possible as inner or anonymous class
● Fragments must have a public empty
constructor
● RTFW: read the fucking warnings:
●
<Button ... android:onClick="clicked" />
public class OnClickToastFragment extends Fragment {...
public void clicked(View v)
{
Toast.makeText(getActivity(),getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
public class OnClickToastFragmentActivity extends FragmentActivity{
public void clicked(View v)
{
Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
public class MyMainActivity extends Activity{
public void clicked(View v)
{
Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
Licence to click
What happens when I click the Button?
a) Toast : MyMainActivity
b) Toast : OnClickToastFragmentActivity
c) Toast : OnClickToastFragment
d) Nothing
e) IllegalStateException - Could not find a method ...
<Button ... android:onClick="clicked" />
public class OnClickToastFragment extends Fragment {...
public void clicked(View v)
{
Toast.makeText(getActivity(),getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
public class OnClickToastFragmentActivity extends FragmentActivity{
public void clicked(View v)
{
Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
public class MyMainActivity extends Activity{
public void clicked(View v)
{
Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show();
}
}
Licence to click
What happens when I click the Button?
a) Toast : MyMainActivity
b) Toast : OnClickToastFragmentActivity
c) Toast : OnClickToastFragment
d) Nothing
e) IllegalStateException - Could not find a method ...
android:onClick is an easy way to trigger "click" events in xml
but remember: the calling Activity MUST implement the xxx(Viev v) method otherwise a
IllegalStateException will be thrown at runtime
be careful if you are using Fragments in multiple Activities
Every 2.2. Device has the "unique" ANDROID_ID
9774d56d682e549c ?
Be aware of platform dependent puzzles....
or did you know that?
public class GetViewFragment extends Fragment {
public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {
super.onCreateView(inf, view, saved);
return inf.inflate(R.layout.fragment_get_view, view);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getView().setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getActivity(),
"My name is droid, android",
Toast.LENGTH_SHORT);}});
}
}
A View to (a) Kill
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 {
public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {
super.onCreateView(inf, view, saved);
return inf.inflate(R.layout.fragment_get_view, view);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getView().setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getActivity(),
"My name is droid, android",
Toast.LENGTH_SHORT);}});
}
}
A View to (a) Kill
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 {
public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) {
super.onCreateView(inf, view, saved);
return inf.inflate(R.layout.fragment_get_view, view);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getView().setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(getActivity(),
"My name is droid, android",
Toast.LENGTH_SHORT);}});
}
}
A View to (a) Kill
a) shows a Toast "my name is droid, android"
b) does nothing but showing a view
c) Exception in Inflater.inflate() (2nd winner)
d) Exception in GetViewFragment.onCreateView()
e) Exception in Fragment.onCreateView()
● Know about the life cycle of Activities,
Fragments, Services!
● Example: methods as
getView() or getActivity() can return null in
certain points of their life cycle!
public class ToastFragment extends Fragment {
...
public void onDestroy() {
super.onDestroy();
new ToastingAsyncTask().execute(null,null,null);
}
class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{
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));
}
}
protected Long doInBackground(String... params) {
try {Thread.sleep(500);} catch (InterruptedException e) {}
return null;}
...
Live and let die ...
what happens when I change the orientation of my Galaxy Nexus?
a) Sysout: no_activity
b) Sysout: activity_leak
c) Sysout: null
d) Exception in getActivity
e) Exception in getString
public class ToastFragment extends Fragment {
...
public void onDestroy() {
super.onDestroy();
new ToastingAsyncTask().execute(null,null,null);
}
class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{
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));
}
}
protected Long doInBackground(String... params) {
try {Thread.sleep(500);} catch (InterruptedException e) {}
return null;}
...
Live and let die ...
what happens when I change the orientation of my Galaxy Nexus?
a) Sysout: no_activity
b) Sysout: activity_leak
c) Sysout: null
d) Exception in getActivity
e) Exception in getString
LogCat shows:
java.lang.IllegalStateException: Fragment ToastFragment not attached to Activity
A Context holds your Resources!
Know about the life cycle of Activities, Fragments,
Services!!
Until Android 4 (possible 3.x) android.app.DownloadManager only supports http
connections:
if (scheme == null || !scheme.equals("http")) {
throw new IllegalArgumentException("Can only download HTTP URIs: " + uri);
}
Because of that the stock browser (and Chrome)
could not handle https downloads.
Be aware of platform dependent puzzles....
or did you know that?
public class MyListActivity extends ListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFromServer(getApplicationContext());
}
void getFromServer(Context context) {
final ProgressDialog dlg = new ProgressDialog(context);
dlg.show();
new AsyncTask<Context, Void, ArrayAdapter>() {
protected ArrayAdapter doInBackground(Context... params) {
return new ArrayAdapter<String>(params[0],
android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "0", "0", "7" }));
}
protected void onPostExecute(ArrayAdapter result) {
setListAdapter(result);
dlg.dismiss();
}
}.execute(context);
}...
a) shows list with entries 0,0,7
b) shows list with entries 0,7
c) Exception in getFromServer
d) Exception in doInBackground
e) Exception in onPostExecute
Tomorrow never dies...
public class MyListActivity extends ListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFromServer(getApplicationContext());
}
void getFromServer(Context context) {
final ProgressDialog dlg = new ProgressDialog(context);
dlg.show();
new AsyncTask<Context, Void, ArrayAdapter>() {
protected ArrayAdapter doInBackground(Context... params) {
return new ArrayAdapter<String>(params[0],
android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "0", "0", "7" }));
}
protected void onPostExecute(ArrayAdapter result) {
setListAdapter(result);
dlg.dismiss();
}
}.execute(context);
}...
a) shows list with entries 0,0,7
b) shows list with entries 0,7
c) Exception in getFromServer
d) Exception in doInBackground
e) Exception in onPostExecute
Tomorrow never dies...
● Know your Context!
● Never use Application Context for UI!
Prefer Application Context for Non-UI!
● Be aware of Context Leaks!
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", Toast.LENGTH_SHORT).show();
return true;
}
}
public class ActionbarActivity extends Activity {
...
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(this, "from Activity", Toast.LENGTH_SHORT).show();
return true;
}
}
From Fragment with Love...
When clicking an item from actionbar:
a) shows toast: "from Activity"
b) shows toast: "from Fragment"
c) shows both toasts
d) shows toast depending on who the creator of the menu item
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", Toast.LENGTH_SHORT).show();
return true;
}
}
public class ActionbarActivity extends Activity {
...
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(this, "from Activity", Toast.LENGTH_SHORT).show();
return true;
}
}
From Fragment with Love...
When clicking an item from actionbar:
a) shows toast: "from Activity"
b) shows toast: "from Fragment"
c) shows both toasts
d) shows toast depending on who the creator of the menu item
"If you added the menu item from a fragment, then the
respective onOptionsItemSelected() method is called for that
fragment.
However the activity gets a chance to handle it first, so the
system calls onOptionsItemSelected() on the activity before
calling the fragment."
● RTFJD: read the fucking java doc:
On pre 2.3.6 Android's HttpUrlConnection is broken
as soon as the server supports more than Basic authentication ?
You'll get IndexOutOfBoundsException
Be aware of platform dependent puzzles....
or did you know that?
int realm = challenge.indexOf("realm="") + 7;
WWW-Authenticate: Basic realm="RealmName"
WWW-Authenticate: NTLM
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] longList = new String[1000000];
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra("droidcon", longList);
startActivityForResult(intent, 100);
}
protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data);
Log.e("droidcon", "result" + request + " " + result);
}
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
The world is not enough ...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] longList = new String[1000000];
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra("droidcon", longList);
startActivityForResult(intent, 100);
}
protected void onActivityResult(int request, int result, Intent data) {
super.onActivityResult(request, result, data);
Log.e("droidcon", "result" + request + " " + result);
}
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
The world is not enough ...
Logcat shows:
11-12 16:25:53.391: E/JavaBinder(6247): !!! FAILED BINDER TRANSACTION !!!
Some devices show TransactionTooLargeException:
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, currently 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.
Be aware of platform dependent puzzles....
or did you know that?
Starting with 2.3 HTTPUrlConnection handles and sets gzip as Content-Encoding.
This leads to errors if you get a response where there is no content but a Content-
Length (=0) or a Content-Encoding(=gzip).
getResponceCode leads to EOFException
public 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,100).execute("Alice");
new WritingAsyncTask(testV,500).execute("loves");
}
...
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);}
Casino Royal
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
public 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,100).execute("Alice");
new WritingAsyncTask(testV,500).execute("loves");
}
...
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);}
Casino Royal
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
public 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,100).execute("Alice");
new WritingAsyncTask(testV,500).execute("loves");
}
...
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);}
Casino Royal
What is shown in the TextView when I start the Activity on my Galaxy Nexus:
a) Alice loves Bob
b) Bob Alice loves .... usually
c) Bob loves Alice
d) There is not enough information to decide
public 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,100).execute("Alice");
new WritingAsyncTask(testV,500).execute("loves");
}
...
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);}
Casino Royal
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
You need to know the android:targetSdkVersion (and the Device Version of the Target Device)
android:targetSdkVersion < 13:
AsyncTask is executed parallel
android:targetSdkVersion >= 13 && Device OS >= 14:
AsyncTask is executed serial
from AsyncTask.Java:
...
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
...
You can enforce parallel execution in SDK >= 11
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,...);
public class ManyAsyncTasksActivity extends Activity{
...
protected void onResume() {
super.onResume();
TextView testV = (TextView) findViewById(R.id.async_text_1);
for (int i = 0; i < 200; i++) {
new WritingAsyncTask(testV,100).execute(i+",");
}
}
...
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);}
Moonraker
What is shown when I start the Activity on my G. Nexus (target SDK is 11, A: 4.1.2) :
a) Numbers from 0 to 199 in random order
b) Application Error (App has stopped)
c) Numbers from 0 to 199 in serial order
d) Numbers from 0 to 127 in random order
e) Numbers from 0 to 137 in random order
public class ManyAsyncTasksActivity extends Activity{
...
protected void onResume() {
super.onResume();
TextView testV = (TextView) findViewById(R.id.async_text_1);
for (int i = 0; i < 200; i++) {
new WritingAsyncTask(testV,100).execute(i+",");
}
}
...
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);}
Moonraker
What is shown when I start the Activity on my G. Nexus (target SDK is 11, A: 4.1.2) :
a) Numbers from 0 to 199 in random order
b) Application Error (App has stopped)
c) Numbers from 0 to 199 in serial order
d) Numbers from 0 to 127 in random order
e) Numbers from 0 to 137 in random order
LogCat shows:
java.lang.RuntimeException: Unable to resume activity {...}: java.util.concurrent.
RejectedExecutionException: Task android.os.AsyncTask ... rejected from java.util.concurrent.
ThreadPoolExecutor ... [Running, pool size = 128, active threads = 128, queued tasks = 10,
completed tasks = 0]
ThreadPoolExecutor currently only accepts a given number of Tasks, default value is a pool size of
128.
private static final int MAXIMUM_POOL_SIZE = 128;
...
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
Thank you!
dpreussler@ebay.com
johannes.orgis@team.cortado.com

Mais conteúdo relacionado

Mais procurados

ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013Mathias Seguy
 
Javascript, the GNOME way (JSConf EU 2011)
Javascript, the GNOME way (JSConf EU 2011)Javascript, the GNOME way (JSConf EU 2011)
Javascript, the GNOME way (JSConf EU 2011)Igalia
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...Luciano Mammino
 
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?Moritz Beller
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012Martin Schuhfuß
 
The Ring programming language version 1.10 book - Part 83 of 212
The Ring programming language version 1.10 book - Part 83 of 212The Ring programming language version 1.10 book - Part 83 of 212
The Ring programming language version 1.10 book - Part 83 of 212Mahmoud Samir Fayed
 

Mais procurados (8)

ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013
 
Javascript, the GNOME way (JSConf EU 2011)
Javascript, the GNOME way (JSConf EU 2011)Javascript, the GNOME way (JSConf EU 2011)
Javascript, the GNOME way (JSConf EU 2011)
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - WebReb...
 
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?
Modern Code Reviews in Open-Source Projects: Which Problems Do They Fix?
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
 
The Ring programming language version 1.10 book - Part 83 of 212
The Ring programming language version 1.10 book - Part 83 of 212The Ring programming language version 1.10 book - Part 83 of 212
The Ring programming language version 1.10 book - Part 83 of 212
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 

Semelhante a Android Code Puzzles (DroidCon Amsterdam 2012)

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalDroidcon Berlin
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android DevelopmentJussi Pohjolainen
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниStfalcon Meetups
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!Artjoker
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloadedcbeyls
 
深入淺出談Fragment
深入淺出談Fragment深入淺出談Fragment
深入淺出談Fragment毅 方
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developersPavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Murat Yener
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
02 hello world - Android
02   hello world - Android02   hello world - Android
02 hello world - AndroidWingston
 

Semelhante a Android Code Puzzles (DroidCon Amsterdam 2012) (20)

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Fragments anyone
Fragments anyone Fragments anyone
Fragments anyone
 
Minicurso Android
Minicurso AndroidMinicurso Android
Minicurso Android
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Thomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-finalThomas braun dependency-injection_with_robo_guice-presentation-final
Thomas braun dependency-injection_with_robo_guice-presentation-final
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android Development
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
 
深入淺出談Fragment
深入淺出談Fragment深入淺出談Fragment
深入淺出談Fragment
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
02 hello world - Android
02   hello world - Android02   hello world - Android
02 hello world - Android
 
Di and Dagger
Di and DaggerDi and Dagger
Di and Dagger
 
Mattbrenner
MattbrennerMattbrenner
Mattbrenner
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Mini curso Android
Mini curso AndroidMini curso Android
Mini curso Android
 

Mais de Danny Preussler

We aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiWe aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiDanny Preussler
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Danny Preussler
 
TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)Danny Preussler
 
TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)Danny Preussler
 
Junit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindJunit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindDanny Preussler
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDanny Preussler
 
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Danny Preussler
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Danny Preussler
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
 
All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...Danny Preussler
 
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016Danny Preussler
 
Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Danny Preussler
 
Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Danny Preussler
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Danny Preussler
 
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinAbgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinDanny Preussler
 
Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Danny Preussler
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With RobolectricDanny Preussler
 

Mais de Danny Preussler (17)

We aint got no time - Droidcon Nairobi
We aint got no time - Droidcon NairobiWe aint got no time - Droidcon Nairobi
We aint got no time - Droidcon Nairobi
 
Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)Test Driven Development on Android (Kotlin Kenya)
Test Driven Development on Android (Kotlin Kenya)
 
TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)TDD on android. Why and How? (Coding Serbia 2019)
TDD on android. Why and How? (Coding Serbia 2019)
 
TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)TDD on Android (Øredev 2018)
TDD on Android (Øredev 2018)
 
Junit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behindJunit5: the next gen of testing, don't stay behind
Junit5: the next gen of testing, don't stay behind
 
Demystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and ToothpickDemystifying dependency Injection: Dagger and Toothpick
Demystifying dependency Injection: Dagger and Toothpick
 
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
Unit Testing on Android: why and how? DevFest Romania, Bucharest 2016
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
 
All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...All around the world, localization and internationalization on Android (Droid...
All around the world, localization and internationalization on Android (Droid...
 
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
(Android) Developer Survival in Multiscreen World, MobCon Sofia 2016
 
Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)Unit testing on Android (Droidcon Dubai 2015)
Unit testing on Android (Droidcon Dubai 2015)
 
Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)Clean code on Android (Droidcon Dubai 2015)
Clean code on Android (Droidcon Dubai 2015)
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
 
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, BerlinAbgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
Abgeschottete Realität - Testen im Emulator, Mobile Testing Days 2014, Berlin
 
Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)Rockstar Android Testing (Mobile TechCon Munich 2014)
Rockstar Android Testing (Mobile TechCon Munich 2014)
 
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With Robolectric
 

Último

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Último (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Android Code Puzzles (DroidCon Amsterdam 2012)

  • 2.
  • 3. ● Danny Preussler: ● Lead Engineer Android ebay Kleinanzeigen, Germany ● Path to the green side: C++ -> Java SE -> JME -> BlackBerry -> Android ● My current Droids: Galaxy Nexus, Nexus 7, Logitech Revue, I'm watch ● My 1st Droid was a: Motorola Droid/Milestone ● Johannes Orgis: ● Software Development Manager Cortado Mobile Clients Cortado AG, Germany ● Path to the green side: Java EE -> Java SE -> BlackBerry -> Android ● My current Droids: Galaxy Nexus, Nexus 7 ● My 1st Droid was a: HTC Magic
  • 4. ● We show code snippets that does something or maybe not ● Look out for hidden pitfalls ● All Puzzles are run with Android 4.1 Jelly Beans There should be no platform depended puzzles ● Test yourself! ● Raise your hands when we ask you! ● Guess if you're unsure! ● Learn something if you were wrong! ● Have fun! :D
  • 5. public class DroidConPuzzle extends Activity { @Override protected void onCreate(Bundle saved) { FragmentTransaction trans = getFragmentManager().beginTransaction(); trans.add(android.R.id.content, new Fragment() { @Override public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { View v = inf.inflate(R.layout.fragment_default, null); return null; } }); trans.commit(); super.onCreate(saved); } } For your eyes only... a) NullPointerException in Inflater.inflate() b) NullPointerException after onCreateView() c) llegalStateException in super.onCreate() d) llegalStateException in Transaction.commit() e) shows an empty screen
  • 6. public class DroidConPuzzle extends Activity { @Override protected void onCreate(Bundle saved) { FragmentTransaction trans = getFragmentManager().beginTransaction(); trans.add(android.R.id.content, new Fragment() { @Override public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { View v = inf.inflate(R.layout.fragment_default, null); return null; } }); trans.commit(); super.onCreate(saved); } } For your eyes only... a) NullPointerException in Inflater.inflate() b) NullPointerException after onCreateView() c) llegalStateException in super.onCreate() d) llegalStateException in Transaction.commit() e) shows an empty screen
  • 7. public class DroidConPuzzle extends Activity { @Override protected void onCreate(Bundle saved) { FragmentTransaction trans = getFragmentManager().beginTransaction(); trans.add(android.R.id.content, new Fragment() { @Override public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { View v = inf.inflate(R.layout.fragment_default, null); return null; } }); trans.commit(); super.onCreate(saved); } } For your eyes only... e) shows an empty screen BUT after rotation it will crash:
  • 8. ● Fragments need to be public: not possible as inner or anonymous class ● Fragments must have a public empty constructor ● RTFW: read the fucking warnings: ●
  • 9. <Button ... android:onClick="clicked" /> public class OnClickToastFragment extends Fragment {... public void clicked(View v) { Toast.makeText(getActivity(),getClass().getName(),Toast.LENGTH_SHORT).show(); } } public class OnClickToastFragmentActivity extends FragmentActivity{ public void clicked(View v) { Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show(); } } public class MyMainActivity extends Activity{ public void clicked(View v) { Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show(); } } Licence to click What happens when I click the Button? a) Toast : MyMainActivity b) Toast : OnClickToastFragmentActivity c) Toast : OnClickToastFragment d) Nothing e) IllegalStateException - Could not find a method ...
  • 10. <Button ... android:onClick="clicked" /> public class OnClickToastFragment extends Fragment {... public void clicked(View v) { Toast.makeText(getActivity(),getClass().getName(),Toast.LENGTH_SHORT).show(); } } public class OnClickToastFragmentActivity extends FragmentActivity{ public void clicked(View v) { Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show(); } } public class MyMainActivity extends Activity{ public void clicked(View v) { Toast.makeText(this,getClass().getName(),Toast.LENGTH_SHORT).show(); } } Licence to click What happens when I click the Button? a) Toast : MyMainActivity b) Toast : OnClickToastFragmentActivity c) Toast : OnClickToastFragment d) Nothing e) IllegalStateException - Could not find a method ...
  • 11. android:onClick is an easy way to trigger "click" events in xml but remember: the calling Activity MUST implement the xxx(Viev v) method otherwise a IllegalStateException will be thrown at runtime be careful if you are using Fragments in multiple Activities
  • 12. Every 2.2. Device has the "unique" ANDROID_ID 9774d56d682e549c ? Be aware of platform dependent puzzles.... or did you know that?
  • 13. public class GetViewFragment extends Fragment { public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { super.onCreateView(inf, view, saved); return inf.inflate(R.layout.fragment_get_view, view); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getView().setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(getActivity(), "My name is droid, android", Toast.LENGTH_SHORT);}}); } } A View to (a) Kill 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()
  • 14. public class GetViewFragment extends Fragment { public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { super.onCreateView(inf, view, saved); return inf.inflate(R.layout.fragment_get_view, view); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getView().setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(getActivity(), "My name is droid, android", Toast.LENGTH_SHORT);}}); } } A View to (a) Kill 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()
  • 15. public class GetViewFragment extends Fragment { public View onCreateView(LayoutInflater inf, ViewGroup view, Bundle saved) { super.onCreateView(inf, view, saved); return inf.inflate(R.layout.fragment_get_view, view); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getView().setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(getActivity(), "My name is droid, android", Toast.LENGTH_SHORT);}}); } } A View to (a) Kill a) shows a Toast "my name is droid, android" b) does nothing but showing a view c) Exception in Inflater.inflate() (2nd winner) d) Exception in GetViewFragment.onCreateView() e) Exception in Fragment.onCreateView()
  • 16. ● Know about the life cycle of Activities, Fragments, Services! ● Example: methods as getView() or getActivity() can return null in certain points of their life cycle!
  • 17. public class ToastFragment extends Fragment { ... public void onDestroy() { super.onDestroy(); new ToastingAsyncTask().execute(null,null,null); } class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{ 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)); } } protected Long doInBackground(String... params) { try {Thread.sleep(500);} catch (InterruptedException e) {} return null;} ... Live and let die ... what happens when I change the orientation of my Galaxy Nexus? a) Sysout: no_activity b) Sysout: activity_leak c) Sysout: null d) Exception in getActivity e) Exception in getString
  • 18. public class ToastFragment extends Fragment { ... public void onDestroy() { super.onDestroy(); new ToastingAsyncTask().execute(null,null,null); } class ToastingAsyncTask extends AsyncTask<String, Integer, Long>{ 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)); } } protected Long doInBackground(String... params) { try {Thread.sleep(500);} catch (InterruptedException e) {} return null;} ... Live and let die ... what happens when I change the orientation of my Galaxy Nexus? a) Sysout: no_activity b) Sysout: activity_leak c) Sysout: null d) Exception in getActivity e) Exception in getString
  • 19. LogCat shows: java.lang.IllegalStateException: Fragment ToastFragment not attached to Activity A Context holds your Resources! Know about the life cycle of Activities, Fragments, Services!!
  • 20. Until Android 4 (possible 3.x) android.app.DownloadManager only supports http connections: if (scheme == null || !scheme.equals("http")) { throw new IllegalArgumentException("Can only download HTTP URIs: " + uri); } Because of that the stock browser (and Chrome) could not handle https downloads. Be aware of platform dependent puzzles.... or did you know that?
  • 21. public class MyListActivity extends ListActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFromServer(getApplicationContext()); } void getFromServer(Context context) { final ProgressDialog dlg = new ProgressDialog(context); dlg.show(); new AsyncTask<Context, Void, ArrayAdapter>() { protected ArrayAdapter doInBackground(Context... params) { return new ArrayAdapter<String>(params[0], android.R.layout.simple_list_item_1, Arrays.asList(new String[] { "0", "0", "7" })); } protected void onPostExecute(ArrayAdapter result) { setListAdapter(result); dlg.dismiss(); } }.execute(context); }... a) shows list with entries 0,0,7 b) shows list with entries 0,7 c) Exception in getFromServer d) Exception in doInBackground e) Exception in onPostExecute Tomorrow never dies...
  • 22. public class MyListActivity extends ListActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFromServer(getApplicationContext()); } void getFromServer(Context context) { final ProgressDialog dlg = new ProgressDialog(context); dlg.show(); new AsyncTask<Context, Void, ArrayAdapter>() { protected ArrayAdapter doInBackground(Context... params) { return new ArrayAdapter<String>(params[0], android.R.layout.simple_list_item_1, Arrays.asList(new String[] { "0", "0", "7" })); } protected void onPostExecute(ArrayAdapter result) { setListAdapter(result); dlg.dismiss(); } }.execute(context); }... a) shows list with entries 0,0,7 b) shows list with entries 0,7 c) Exception in getFromServer d) Exception in doInBackground e) Exception in onPostExecute Tomorrow never dies...
  • 23. ● Know your Context! ● Never use Application Context for UI! Prefer Application Context for Non-UI! ● Be aware of Context Leaks!
  • 24. 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", Toast.LENGTH_SHORT).show(); return true; } } public class ActionbarActivity extends Activity { ... public boolean onOptionsItemSelected(MenuItem item) { Toast.makeText(this, "from Activity", Toast.LENGTH_SHORT).show(); return true; } } From Fragment with Love... When clicking an item from actionbar: a) shows toast: "from Activity" b) shows toast: "from Fragment" c) shows both toasts d) shows toast depending on who the creator of the menu item
  • 25. 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", Toast.LENGTH_SHORT).show(); return true; } } public class ActionbarActivity extends Activity { ... public boolean onOptionsItemSelected(MenuItem item) { Toast.makeText(this, "from Activity", Toast.LENGTH_SHORT).show(); return true; } } From Fragment with Love... When clicking an item from actionbar: a) shows toast: "from Activity" b) shows toast: "from Fragment" c) shows both toasts d) shows toast depending on who the creator of the menu item
  • 26. "If you added the menu item from a fragment, then the respective onOptionsItemSelected() method is called for that fragment. However the activity gets a chance to handle it first, so the system calls onOptionsItemSelected() on the activity before calling the fragment." ● RTFJD: read the fucking java doc:
  • 27. On pre 2.3.6 Android's HttpUrlConnection is broken as soon as the server supports more than Basic authentication ? You'll get IndexOutOfBoundsException Be aware of platform dependent puzzles.... or did you know that? int realm = challenge.indexOf("realm="") + 7; WWW-Authenticate: Basic realm="RealmName" WWW-Authenticate: NTLM
  • 28. protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] longList = new String[1000000]; Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra("droidcon", longList); startActivityForResult(intent, 100); } protected void onActivityResult(int request, int result, Intent data) { super.onActivityResult(request, result, data); Log.e("droidcon", "result" + request + " " + result); } 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 The world is not enough ...
  • 29. protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] longList = new String[1000000]; Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra("droidcon", longList); startActivityForResult(intent, 100); } protected void onActivityResult(int request, int result, Intent data) { super.onActivityResult(request, result, data); Log.e("droidcon", "result" + request + " " + result); } 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 The world is not enough ...
  • 30. Logcat shows: 11-12 16:25:53.391: E/JavaBinder(6247): !!! FAILED BINDER TRANSACTION !!! Some devices show TransactionTooLargeException: 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, currently 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.
  • 31. Be aware of platform dependent puzzles.... or did you know that? Starting with 2.3 HTTPUrlConnection handles and sets gzip as Content-Encoding. This leads to errors if you get a response where there is no content but a Content- Length (=0) or a Content-Encoding(=gzip). getResponceCode leads to EOFException
  • 32. public 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,100).execute("Alice"); new WritingAsyncTask(testV,500).execute("loves"); } ... 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);} Casino Royal 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
  • 33. public 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,100).execute("Alice"); new WritingAsyncTask(testV,500).execute("loves"); } ... 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);} Casino Royal 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
  • 34. public 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,100).execute("Alice"); new WritingAsyncTask(testV,500).execute("loves"); } ... 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);} Casino Royal What is shown in the TextView when I start the Activity on my Galaxy Nexus: a) Alice loves Bob b) Bob Alice loves .... usually c) Bob loves Alice d) There is not enough information to decide
  • 35. public 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,100).execute("Alice"); new WritingAsyncTask(testV,500).execute("loves"); } ... 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);} Casino Royal 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
  • 36. You need to know the android:targetSdkVersion (and the Device Version of the Target Device) android:targetSdkVersion < 13: AsyncTask is executed parallel android:targetSdkVersion >= 13 && Device OS >= 14: AsyncTask is executed serial from AsyncTask.Java: ... public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; ... You can enforce parallel execution in SDK >= 11 executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,...);
  • 37. public class ManyAsyncTasksActivity extends Activity{ ... protected void onResume() { super.onResume(); TextView testV = (TextView) findViewById(R.id.async_text_1); for (int i = 0; i < 200; i++) { new WritingAsyncTask(testV,100).execute(i+","); } } ... 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);} Moonraker What is shown when I start the Activity on my G. Nexus (target SDK is 11, A: 4.1.2) : a) Numbers from 0 to 199 in random order b) Application Error (App has stopped) c) Numbers from 0 to 199 in serial order d) Numbers from 0 to 127 in random order e) Numbers from 0 to 137 in random order
  • 38. public class ManyAsyncTasksActivity extends Activity{ ... protected void onResume() { super.onResume(); TextView testV = (TextView) findViewById(R.id.async_text_1); for (int i = 0; i < 200; i++) { new WritingAsyncTask(testV,100).execute(i+","); } } ... 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);} Moonraker What is shown when I start the Activity on my G. Nexus (target SDK is 11, A: 4.1.2) : a) Numbers from 0 to 199 in random order b) Application Error (App has stopped) c) Numbers from 0 to 199 in serial order d) Numbers from 0 to 127 in random order e) Numbers from 0 to 137 in random order
  • 39. LogCat shows: java.lang.RuntimeException: Unable to resume activity {...}: java.util.concurrent. RejectedExecutionException: Task android.os.AsyncTask ... rejected from java.util.concurrent. ThreadPoolExecutor ... [Running, pool size = 128, active threads = 128, queued tasks = 10, completed tasks = 0] ThreadPoolExecutor currently only accepts a given number of Tasks, default value is a pool size of 128. private static final int MAXIMUM_POOL_SIZE = 128; ... private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(10);