Android TechBooster 2014-12-30 TechBooster 1
Android Android Android ( @mhidaka) 15 Gradle Docker TechBooster TechBooster Android *1 https://plus.google.com/+techboosterorg/ * 1 TechBooster Web http://techbooster.org/ 1
1................................... 1 TechBooster................................... 1..................................... 1 1 6 1.1 Activity static......... 6 1.2 OnClickListener......... 9 1.3 Handler..................... 13 1.4......... 16 1.5 try-catch Exception................. 21 1.6 Thread killprocess........ 22 1.7 static.......... 25 1.8 AsyncTask............. 28 1.9 Preference edit........ 33 1.10 Application Service............... 38 1.11 OutOfMemoryError.............. 42 1.12 Application........... 50 1.13 xml View............. 51 1.14 synchronized........................ 52 1.15 new........... 52 1.16.................................... 53 2
2 Android100 10 54 2.1.................................... 54 2.2................................. 55 3 Google 7 60 3.1 portrait......................... 61 3.2 minsdkversion.................... 61 3.3 DialogFragment...................... 64 3.4 PreferenceActivity.................... 65 3.5 ContentProvider.................... 68 3.6.............. 69 3.7...................... 70 3.8....................... 73 4 UCD PlayStore 1 74 4.1....................................... 74 4.2 UCD............................... 75 4.3 UCD.................................. 76 4.4...................... 79 4.5....................................... 81 5 Android Gradle 84 5.1.................................... 84 5.2 applicationid.......................... 86 5.3 minsdkversion build.gradle............... 87 5.4 targetsdkversion build.gradle.............. 88 5.5 versioncode.............. 88 5.6 apk...................... 89 5.7 Product Flavor......................... 91 5.8 Build Type............................ 92 5.9 Build Type applicationid................... 93 3
5.10......................... 95 5.11 ProGuard........................... 97 5.12 apk 1........ 98 5.13 apk 2........ 99 5.14 RenderScript Support Library.................. 101 5.15 ABI apk........................ 102 5.16 density apk...................... 104 5.17 /........ 106 5.18............ 106 5.19........... 107 5.20........ 108 5.21........... 109 5.22 Build Type AndroidManifest......... 111 5.23 BuildConfig................. 113 5.24..................... 115 5.25............... 117 5.26 Android Wear...................... 117 5.27.............. 119 5.28 lint............................ 119 5.29 assets................... 121 5.30 jni.so........... 122 5.31 NDK *.c *.cpp............... 122 5.32 /........ 124 5.33 apk..................... 125 5.34 IDE........................ 126 5.35.................... 126 5.36 Gradle.................. 127 5.37 ProGuard............ 129 5.38.................................... 130 6 Docker 131 6.1..................................... 131 4
6.2 VM.................. 132 6.3........................... 134 6.4 Docker........................ 134 6.5 Docker......................... 135 6.6 VM Docker...................... 136 6.7 Docker...................... 137 6.8..................... 140 6.9..................... 141 6.10........................ 142 6.11........................ 144 6.12 Docker........................ 146 6.13 Docker................................ 149 6.14..................................... 151 152 5
1 Android View Handler Android 1.1 Activity static Android Activity Intent static 1.1 1.1: UserModel.java public class UserModel implements Serializable { public enum Role { PROGRAMMER, DESIGNNER, MANAGER private long id; private String username; private Role role; 6
1 /* Getter Setter */ 1.2 FirstDameActivity 1.3 SecondDameActivity 1.2: FirstDameActivity.java public class FirstDameActivity extends Activity implements View.OnClickListener { private UserModel musermodel; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); findviewbyid(r.id.button1).setonclicklistener(this); // musermodel /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { // SecondDameActivity.sUserModel = musermodel; Intent intent = new Intent(this, SecondDameActivity.class); startactivity(intent); 1.3: SecondDameActivity.java public class SecondDameActivity extends Activity { public static UserModel susermodel; private UserModel musermodel; 7
1 protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // static musermodel = susermodel; 1.2 FirstDameActivity#onClick musermodel SecondDameActivity.sUserModel Android SecondDameActivity.sUserModel susermodel SecondDameActivity susermodel susermodel Android 1.4 1.5 1.4: FirstRefineActivity.java public class FirstRefineActivity extends Activity implements View.OnClickListener { private UserModel musermodel; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); findviewbyid(r.id.button1).setonclicklistener(this); // musermodel /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { Intent intent = new Intent(this, SecondRefineActivity.class); // 8
1 intent.putextra(secondrefineactivity.extra_user_model, musermodel); startactivity(intent); 1.5: SecondRefineActivity.java public class SecondRefineActivity extends Activity { public static final String EXTRA_USER_MODEL = "user_model"; private UserModel musermodel; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // Intent musermodel = (UserModel) getintent().getserializableextra(extra_user_model); 1.4 Intent#putExtra Intent 1.5 Intent#putExtra Intent Activity 1.2 OnClickListener View OnClickListener OnClickListener 9
1 View#setOnClickListener OnClickListener 1.6 Activity#onCreate button1 button2 1.6: ManyOnClickListenerDameActivity.java public class ManyOnClickListenerDameActivity extends Activity { private EditText medittext1; private EditText medittext2; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); // button1 findviewbyid(r.id.button1).setonclicklistener( new View.OnClickListener() { public void onclick(view v) { medittext1.settext("button1 clicked!"); ); // button2 findviewbyid(r.id.button2).setonclicklistener( new View.OnClickListener() { public void onclick(view v) { medittext2.settext("button2 clicked!"); ); medittext1 = (EditText) findviewbyid(r.id.edittext1); medittext2 = (EditText) findviewbyid(r.id.edittext2); 1.6 Activity#onCreate 1. OnClickListener button1 button2 2. OnClickListener 3. OnClickListener 10
1 1.6 Activity#onCreate Activity#onCreate Activity 3. oncreate 1.7 OnClickListener Acitivity implements 2. 3. Activity#onClick 1.7: ManyOnClickListenerRefine1Activity.java public class ManyOnClickListenerRefine1Activity extends Activity implements View.OnClickListener { private EditText medittext1; private EditText medittext2; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); // OnClickListener findviewbyid(r.id.button1).setonclicklistener(this); findviewbyid(r.id.button2).setonclicklistener(this); medittext1 = (EditText) findviewbyid(r.id.edittext1); medittext2 = (EditText) findviewbyid(r.id.edittext2); public void onclick(view v) { if (v.getid() == R.id.button1) { medittext1.settext("button1 clicked!"); else if (v.getid() == R.id.button1) { medittext2.settext("button2 clicked!"); 1.7 Activity#onCreate Activity#onCreate View View View 11
1 OnClickListener Activity implements 1.8 1.8: ManyOnClickListenerRefine2Activity.java public class ManyOnClickListenerRefine2Activity extends Activity { private EditText medittext1; private EditText medittext2; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); findviewbyid(r.id.button1).setonclicklistener(monclicklistener); findviewbyid(r.id.button2).setonclicklistener(monclicklistener); medittext1 = (EditText) findviewbyid(r.id.edittext1); medittext2 = (EditText) findviewbyid(r.id.edittext2); private View.OnClickListener monclicklistener = new View.OnClickListener() { public void onclick(view v) { if (v.getid() == R.id.button1) { medittext1.settext("button1 clicked!"); else if (v.getid() == R.id.button1) { medittext2.settext("button2 clicked!"); ; 1.8 OnClickListener Activity implements OnClickListener Activity Activity implements 12
1 onclick onclick onclick 1.3 Handler Handler Android Handler 1.9 button1 button2 5000ms edittext1 edittext2 1.9: ManyHandlersDameActivity.java public class ManyHandlersDameActivity extends Activity implements View.OnClickListener { private EditText edittext1; private EditText edittext2; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { // Handler 5000ms new Handler().postDelayed(new Runnable() { public void run() { edittext1.settext("button1 clicked!");, 5000); else if (v.getid() == R.id.button2) { 13
1 // Handler 5000ms new Handler().postDelayed(new Runnable() { public void run() { edittext1.settext("button2 clicked!");, 5000); Handler postdelayed 5000ms Runnable Handler 1.10 Handler static 1.10: ManyHandlersRefine1Activity.java public class ManyHandlersRefine1Activity extends Activity implements View.OnClickListener { private EditText edittext1; private EditText edittext2; private static Handler shandler = new Handler(); protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { shandler.postdelayed(new Runnable() { public void run() { edittext1.settext("button1 clicked!");, 5000); else if (v.getid() == R.id.button2) { shandler.postdelayed(new Runnable() { 14
1 public void run() { edittext1.settext("button2 clicked!");, 5000); Runnable 1.11 1.11: ManyHandlersRefine2Activity.java public class ManyHandlersRefine2Activity extends Activity implements View.OnClickListener { private static final int EVENT_BUTTON1_CLICKED = 1; private static final int EVENT_BUTTON2_CLICKED = 2; private static Handler shandler = new Handler() { public void handlemessage(message msg) { super.handlemessage(msg); ManyHandlersRefine2Activity activity = (ManyHandlersRefine2Activity) msg.obj; if (msg.what == EVENT_BUTTON1_CLICKED) { activity.edittext1.settext("button1 clicked!"); else if (msg.what == EVENT_BUTTON2_CLICKED) { activity.edittext2.settext("button2 clicked!"); ; private EditText edittext1; private EditText edittext2; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { // shandler shandler 15
1 Message msg = shandler.obtainmessage(event_button1_clicked, this); shandler.sendmessagedelayed(msg, 5000); else if (v.getid() == R.id.button2) { // shandler shandler Message msg = shandler.obtainmessage(event_button2_clicked, this); shandler.sendmessagedelayed(msg, 5000); 1.11 1.10 shandler edittext1 edittext2 shandler Runnable Handler UI 1.4 UI UI button1 edittext1 1.12 Thread taskfinished taskresult UI 1000ms taskfinished true true edittext 1.12: PollingDameActivity.java 16
1 public class PollingDameActivity extends Activity implements View.OnClickListener { private int taskresult; // private boolean taskfinished; // private EditText edittext1; private EditText edittext2; private static Handler shandler = new Handler(); protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { taskfinished = false; // new Thread() { public void run() { super.run(); int result = 0; { // for (int i = 0; i <= 100; i++) { result += i; // taskresult = result; taskfinished = true;.start(); Runnable runnable = new Runnable() { public void run() { // if (taskfinished) { edittext1.settext(string.valueof(taskresult)); else { shandler.postdelayed(this, 1000); 17
1 ; shandler.postdelayed(runnable, 1000); 1. taskfinished taskresult 2. 1000ms UI 1000ms 3. 100ms 10ms CPU Thread new 1.13 1.13: PollingRefine1Activity.java public class PollingRefine1Activity extends Activity implements View.OnClickListener { private EditText edittext1; private EditText edittext2; /** UI Handler */ private static Handler shandler = new Handler(); protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { // new Thread() { 18
1 public void run() { super.run(); int result = 0; { // for (int i = 0; i <= 100; i++) { result += i; // UI final int finalresult = result; Runnable runnable = new Runnable() { public void run() { // edittext1 edittext1.settext(string.valueof(finalresult)); ; shandler.post(runnable); // shandler UI // runonuithread(runnable); //.start(); edittext1 shandler UI shandler.post Activity#runOnUiThread UI Android AsyncTask AsyncTask 1.14 1.14: PollingRefine2Activity.java public class PollingRefine2Activity extends Activity implements View.OnClickListener { private EditText edittext1; private EditText edittext2; 19
1 protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { AsyncTask<Void,Void,Integer> task = new AsyncTask<Void, Void, Integer>() { protected Integer doinbackground(void params) { // int result = 0; { // for (int i = 0; i <= 100; i++) { result += i; return result; protected void onpostexecute(integer result) { // UI edittext1.settext(string.valueof(result)); ; task.execute(); AsyncTask doinbackground onpostexecute UI doinbackground onpostexecute UI UI 1.12 taskfinished taskresult UI AsyncTask 20
1 1.5 try-catch Exception Java Exception Integer#parseInt String int String NumberFormatException IOException 1.15 EditText 1.15: ExceptionDameActivity.java EditText edittext1 = (EditText) findviewbyid(r.id.edittext1); int intvalue = -1; try { intvalue = Integer.parseInt(editText1.getText().toString()); catch (Exception e) { if (intvalue == -1) { Log.d("Hoge", "Bad input."); // else { // 1. try-catch Exception 2. -1 1. Exception edittext1 null "-1" intvalue -1 1.16 edittext1 null NullPointerException "-1" 21
1 1.16: ExceptionRefineActivity.java EditText edittext1 = (EditText) findviewbyid(r.id.edittext1); try { int intvalue = Integer.parseInt(editText1.getText().toString()); // catch (NumberFormatException e) { Log.d("Hoge", "Bad input."); // Android Java Android Java Exception 1.6 Thread killprocess UI AsyncTask Thread kill 1.17 Service#onCreate new start 1.17: KillProcessDameService.java 22
1 public class KillProcessDameService extends Service { public IBinder onbind(intent intent) { /* */ public void oncreate() { super.oncreate(); new Thread() { public void run() { super.run(); while(true) { // do some thing.start(); public void ondestroy() { super.ondestroy(); Process.killProcess(Process.myPid()); Service#onDestroy Process#killProcess kill 1. kill 2. JUnit Service#onDestroy JUnit JUnit 3. Process.killProcess 23
1 1.18 Service#onCreate Thread Thread#interrupt() 1.18: KillProcessRefine1Service.java public class KillProcessRefine1Service extends Service { private Thread mthread; public IBinder onbind(intent intent) { /* */ public void oncreate() { super.oncreate(); mthread = new Thread() { public void run() { super.run(); while(!thread.currentthread().isinterrupted()) { // do some thing ; mthread.start(); public void ondestroy() { super.ondestroy(); mthread.interrupt(); Thread#interrupt Thread#isInterrupted volatile boolean 1.18 Service#onDestroy 24
1 1.19 Thread#join 1.19: KillProcessRefine2Service.java public class KillProcessRefine2Service extends Service { private Thread mthread; /* */ public void ondestroy() { super.ondestroy(); mthread.interrupt(); // ondestroy try { mthread.join(); catch (InterruptedException e) { // Bluetooth ADK 1.7 static Activity Service static Activity Service 1.20 Service HogeThread 25
1 static sthread 1.20: StaticFieldDameService.java public class StaticFieldDameService extends Service { private static Thread sthread; static class HogeThread extends Thread { public void run() { super.run(); while(!isinterrupted()) { // public IBinder onbind(intent intent) { /* */ public void oncreate() { super.oncreate(); // sthread = new HogeThread(); sthread.start(); static Service Service HogeThread HogeThread HogeThread oncreate ondestroy static HogeThread 1.21 1.21: StaticFieldRefineService.java 26
1 public class StaticFieldRefineService extends Service { private Thread mthread; static class HogeThread extends Thread { public void run() { super.run(); while(!isinterrupted()) { // public IBinder onbind(intent intent) { /* */ public void oncreate() { super.oncreate(); // mthread = new HogeThread(); mthread.start(); public void ondestroy() { super.ondestroy(); // mthread.interrupt(); mthread = null; Service static static Android Activity Service 27
1 1.8 AsyncTask UI AsyncTask AsyncTask 1.22 button1 0 100 medittext1 button2 101 200 medittext2 1.22 1.22: ManyAsyncTaskDameActivity.java public class ManyAsyncTaskDameActivity extends Activity implements View.OnClickListener { private EditText medittext1; private EditText medittext2; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { AsyncTask<Void,Void,Integer> task = new AsyncTask<Void, Void, Integer>() { protected Integer doinbackground(void params) { int result = 0; { // for (int i = 0; i <= 100; i++) { result += i; return result; 28
1 protected void onpostexecute(integer integer) { super.onpostexecute(integer); medittext1.settext(string.valueof(integer)); ; task.execute(); else if (v.getid() == R.id.button2) { AsyncTask<Void,Void,Integer> task = new AsyncTask<Void, Void, Integer>() { protected Integer doinbackground(void params) { int result = 0; { // for (int i = 101; i <= 200; i++) { result += i; return result; protected void onpostexecute(integer integer) { super.onpostexecute(integer); medittext2.settext(string.valueof(integer)); ; task.execute(); 1.22 AsyncTask AsyncTask#doInBackground 1. AsyncTask#doInBackground 2. AsyncTask#onPostExecute EditText 3. 1. AsyncTask#doInBackground 1.23 SumAsyncTask 0-100 101-200 29
1 AsyncTask#onPostExecute 1.23: ManyAsyncTaskRefine1Activity.java public class ManyAsyncTaskRefine1Activity extends Activity implements View.OnClickListener { private EditText medittext1; private EditText medittext2; static class SumAsyncTask extends AsyncTask<Integer, Void, Integer> { protected Integer doinbackground(integer params) { int result = 0; { // for (int i = params[0]; i <= params[1]; i++) { result += i; return result; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { SumAsyncTask task = new SumAsyncTask() { protected void onpostexecute(integer integer) { super.onpostexecute(integer); medittext1.settext(string.valueof(integer)); ; task.execute(0, 100); else if (v.getid() == R.id.button2) { SumAsyncTask task = new SumAsyncTask() { protected void onpostexecute(integer integer) { super.onpostexecute(integer); medittext2.settext(string.valueof(integer)); ; 30
1 task.execute(101, 200); 2. 3. AsyncTask SumAsyncTask 1.24 SumAsyncTask ISumAsyncTaskListener muserdata muserdata Generics 1.24: SumAsyncTask.java public class SumAsyncTask<T> extends AsyncTask<Integer, Void, Integer> { public interface ISumAsyncTaskListener<T> { public void onpreexecutesumasynctask(t userdata); public void oncancelsumasynctask(t userdata); public void onpostexecutesumasynctask(int result, T userdata); private ISumAsyncTaskListener<T> mlistener; private T muserdata; public SumAsyncTask(ISumAsyncTaskListener listener, T userdata) { this.mlistener = listener; this.muserdata = userdata; protected void onpreexecute() { super.onpreexecute(); mlistener.onpreexecutesumasynctask(muserdata); protected Integer doinbackground(integer params) { int result = 0; for (int i=params[0];i<=params[1];i++) { result += i; return result; protected void oncancelled() { 31
1 super.oncancelled(); mlistener.oncancelsumasynctask(muserdata); protected void onpostexecute(integer result) { mlistener.onpostexecutesumasynctask(result, muserdata); SumAsyncTask 1.25 SumAsyncTask Generics EditText 1.25: ManyAsyncTaskRefine2Activity.java public class ManyAsyncTaskRefine2Activity extends Activity implements View.OnClickListener, SumAsyncTask.ISumAsyncTaskListener<EditText> { private EditText medittext1; private EditText medittext2; SumAsyncTask<EditText> mtask1; SumAsyncTask<EditText> mtask2; private ProgressDialog mprogressdialog; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { mtask1 = new SumAsyncTask<EditText>(this, medittext1); mtask1.execute(0, 100); else if (v.getid() == R.id.button2) { mtask2 = new SumAsyncTask<EditText>(this, medittext2); mtask2.execute(101, 200); public void onpreexecutesumasynctask(edittext userdata) { mprogressdialog = new ProgressDialog(this); mprogressdialog.show(); 32
1 public void oncancelsumasynctask(edittext userdata) { mprogressdialog.dismiss(); mprogressdialog = null; public void onpostexecutesumasynctask(int result, EditText userdata) { userdata.settext(string.valueof(result)); mprogressdialog.dismiss(); mprogressdialog = null; 1.25 1.23 AsyncTask AsyncTask#onPostExecute onpostexecutesumasynctask Generics EditText onpostexecutesumasynctask onpreexecute- SumAsyncTask oncancelsumasynctask SumAsyncTask 1.22 1.25 UI AsyncTask Interface Interface 1.9 Preference edit SharedPreference SharedPreference String Key-Value 33
1 1. String 2. ClassCastException 1.26 SharedPreferences Activity#onCreate edittext1 1.26: SharedPreferencesDameActivity.java public class SharedPreferencesDameActivity extends Activity implements View.OnClickListener { private SharedPreferences mpref; private EditText edittext1; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); findviewbyid(r.id.button1).setonclicklistener(this); findviewbyid(r.id.button2).setonclicklistener(this); edittext1 = (EditText) findviewbyid(r.id.edittext1); mpref = PreferenceManager.getDefaultSharedPreferences(this); String lastbutton = mpref.getstring("lastbutton", ""); edittext1.settext(lastbutton); public void onclick(view v) { if (v.getid() == R.id.button1) { mpref.edit().putstring("lastbutton", "button1").apply(); else if (v.getid() == R.id.button2) { mpref.edit() 34
1.putString("lastButton", "button2").apply(); SharedPreferences "lastbutton" 1.27 1.27: SharedPreferencesRefine1Activity.java public class SharedPreferencesRefine1Activity extends Activity implements View.OnClickListener { private SharedPreferences mpref; private EditText edittext1; private String KEY_LAST_BUTTON = "lastbutton"; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); findviewbyid(r.id.button1).setonclicklistener(this); findviewbyid(r.id.button2).setonclicklistener(this); edittext1 = (EditText) findviewbyid(r.id.edittext1); mpref = PreferenceManager.getDefaultSharedPreferences(this); String lastbutton = mpref.getstring(key_last_button, ""); edittext1.settext(lastbutton); public void onclick(view v) { if (v.getid() == R.id.button1) { mpref.edit().putstring(key_last_button, "button1").apply(); else if (v.getid() == R.id.button2) { mpref.edit().putstring(key_last_button, "button2").apply(); 35
1 "lastbutton" 1.28 SharedPreferences KEY_LAST_BUTTON private getlastbutton putlastbutton 1.28: MySharedPreferences.java public class MySharedPreferences { private static final String KEY_LAST_BUTTON = "lastbutton"; private SharedPreferences mpref; private SharedPreferences.Editor meditor; public MySharedPreferences(SharedPreferences mpref) { this.mpref = mpref; public MySharedPreferences edit() { meditor = mpref.edit(); return this; public void apply() { meditor.apply(); meditor = null; public String getlastbutton() { return mpref.getstring(key_last_button, ""); public MySharedPreferences putlastbutton(string value) { meditor.putstring(key_last_button, value); return this; 36
1 1.29 MySharedPreferences 1.29: SharedPreferencesRefine2Activity.java public class SharedPreferencesRefine2Activity extends Activity implements View.OnClickListener { private MySharedPreferences mpref; private EditText edittext1; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_many_handlers); findviewbyid(r.id.button1).setonclicklistener(this); findviewbyid(r.id.button2).setonclicklistener(this); edittext1 = (EditText) findviewbyid(r.id.edittext1); mpref = new MySharedPreferences( PreferenceManager.getDefaultSharedPreferences(this)); String lastbutton = mpref.getlastbutton(); edittext1.settext(lastbutton); public void onclick(view v) { if (v.getid() == R.id.button1) { mpref.edit().putlastbutton("button1").apply(); else if (v.getid() == R.id.button2) { mpref.edit().putlastbutton("button2").apply(); 37
1 1.10 Application Service Android Service Service Activity Application Service 1.30 oncreate Application ondestroy Service hoge 1.30: ResidentDameService.java public class ResidentDameService extends Service { private IResidentDameService.Stub mbinder = new IResidentDameService.Stub() { ; public IBinder onbind(intent intent) { return mbinder; public void oncreate() { super.oncreate(); DameApplication app = (DameApplication) getapplication(); app.setdameservice(this); 38
1 public void ondestroy() { super.ondestroy(); DameApplication app = (DameApplication) getapplication(); app.setdameservice(null); public String hoge() { return "hogehoge"; Service hoge Activity 1.31 1.31: ResidentDameActivity.java public class ResidentDameActivity extends Activity implements View.OnClickListener { private EditText edittext1; protected void oncreate(bundle savedinstancestate) { /* */ public void onclick(view v) { if (v.getid() == R.id.button1) { DameApplication app = (DameApplication) getapplication(); ResidentDameService service = app.getdameservice(); if (service!= null) { edittext1.settext(app.getdameservice().hoge()); Activity ResidentDameService#onCreate Service DameApplication.getDameService() null Activity 39
1 Application ServiceConnection oncreate Application ondestroy 1.32: ResidentRefineService.java public class ResidentRefineService extends Service { public class LocalBinder extends IResidentRefineService.Stub { public ResidentRefineService getservice() { return ResidentRefineService.this; private LocalBinder mbinder = new LocalBinder(); public IBinder onbind(intent intent) { return mbinder; public String hoge() { return "hogehoge"; Activity 1.33 ServiceConnection Service bind 1.33: ResidentRefineActivity.java public class ResidentRefineActivity extends Activity implements View.OnClickListener { private EditText edittext1; private ResidentRefineService mservice; ServiceConnection mserviceconnection = new ServiceConnection() { public void onserviceconnected (ComponentName name, IBinder service) { mservice = ((LocalBinder) service).getservice(); 40
1 public void onservicedisconnected(componentname name) { mservice = null; ; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); findviewbyid(r.id.button1).setonclicklistener(this); edittext1 = (EditText) findviewbyid(r.id.edittext1); protected void onstart() { super.onstart(); Intent intent = new Intent(this, ResidentRefineService.class); bindservice(intent, mserviceconnection, Context.BIND_AUTO_CREATE); protected void onpause() { super.onpause(); unbindservice(mserviceconnection); public void onclick(view v) { if (v.getid() == R.id.button1) { if (mservice!= null) { edittext1.settext(mservice.hoge()); Activity Service Bind Service Unbind ServiceCon- 41
1 nection Service bind/unbind on- Start()/onStop() oncreate()/ondestroy() onpause()/onresume() Activity 1.11 OutOfMemoryError OutOfMemoryError OOM null Android Memory Analyzer( MAT) MAT Eclipse 1.1 Memory Analyzer http://www.eclipse.org/mat/ 42
1 Eclipse DDMS Dump HPROF file 1.2 Dump HPROF file byte Activity 16MB byte 1.34: LargeBytesActivity.java public class LargeBytesActivity extends ActionBarActivity { private byte[] mlargebytes = new byte[16 * 1024 * 1024]; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); 16MB byte MAT Dump HPROF file 1.3 43
1 1.3 Memory Analyzer 1.4 44
1 1.4 Create a histogram 1.5 byte 45
1 1.5 Histogram byte 1.6 List objects 46
1 1.6 List objects Retained Heap 1.7 16MB byte 47
1 1.7 16MB byte byte GC Path to GC Roots 48
1 1.8 Path to GC Roots 1.9 16MB byte mlargebytes LargeBytesActivity 49
1 1.9 OutOfMemoryError MAT GC null null MAT 1.12 Application Application Application 50
1 1.35 Application AssetManager PackageManager NullPointerException 1.35: DameBehaviorApplication.java public class DameBehaviorApplication extends Application { public AssetManager getassets() { return null; public PackageManager getpackagemanager() { return null; Google Play Service NullPointerException 1.35 1.13 xml View Android XML 51
1 View 1.14 synchronized synchronized Java synchronized Activty Service synchronized synchronized Android Android Activity Service Handler synchronized synchronized Handler 1.15 new Java new 52
1 Android( 2.1) 1.16 Android 53
2 Android100 10 2.1 Nexus Android Android NO 100 10 Q&A Android 2014 11 Android 54
2 Android100 10 2.2 Y.Y 30 Q. Q. M2, M3, 30-50 Q. ios Android Q. 10 2.1 Y.Y 10 No. 1 Xperia A SO-04E 2013.05 HD, 4.2.2, 2 Galaxy S4 SC-04E 2013.05 FHD, 4.4.2 3 isai FL LGL24 2014.07 WQHD, 4.4, 4 Nexus 5 2013.11 FHD, 5.0, ART 5 Nexus 7 2012 2012.07 HD, 5.0, 6 Xperia Z1 SO-01F 2013.10 FHD, 4.4 7 Xperia SX SO-05D 2012.08 qhd, 4.1.2 8 Optimus Vu L-06D 2012.08 1024x768, 4.0 9 ARROWS Tab F-02F 2013.11 2560x1600, 4.2.2 10 Disney Mobile P-05D 2012.03 qhd, 4.0.4 55
2 Android100 10 Q. 2.x 2 UI Android minsdkversion 14 Q. 10 Android Q. Optimus Vu T.Y 30 Q. Q. 10 20 Q. 56
2 Android100 10 2.2 T.Y 10 No. 1 LG Nexus5 2013.11 Phone 2 ASUS Nexus7(2013) 2013.08 3 SONY SO-04E Xperia A 2013.05 SONY 4 SHARP SHL21 AQUOS PHONE SERIE 2012.11 SHARP 5 Samsung SC-04E GALAXY S4 2013.05 Samsung 6 LG LGL24 isai FL 2014.07 xxxhdpi NEC N-03E 7 Disney Mobile 2012.12 OOM 8 NEC N-05E MEDIAS W 2013.04 2 9 SONY NW-F885 Walkman 2013.10 10 Xiaomi MI-3 GooglePlay Q. 10 Q. GoogleAnalytics Q. 10 Android ICS 10 Q. 10 Nexus10 XperiaTablet 57
2 Android100 10 M.M 20 Q. Q. F2 M2 Q. WebView ios Android OS 2.3.3 Q. 10 Q. Google Samsung SONY OS 2.3.x 2 GalaxyS WebView WebView UserAgent Android 58
2 Android100 10 2.3 M.M 10 No. 1 LG Nexus 5 2013.11 FHD, 5.0, OS 2 ASUS Nexus 7 2012 2012.07 HD, 4.3, 3 SONY Xperia A SO-04E 2013.05 HD, 4.2.2, No.1 4 SAMSUNG Galaxy S4 SC-04E 2013.05 FHD, 4.4.2, 5 SHARP AQUOS PHONE ZETA SH-04F 2014.5 FHD, 4.4, 6 URBANO L01 KYY21 2013.06 HD, 4.2.2, SD 7 ARROWS X LTE F-05D 2011.02 HD, 4.0.3 8 NEC Disney Mobile N-03E 2012.12 HD, 4.1.2, 9 SAMSUNG Galaxy S SC-02B 2010.10 WVGA, 2.3.6 10 2012.03 10, 2.3 Q. 10 2 10 OS 1 Q. 59
3 Google 7 3.1 Google Android 60
3 Google 7 3.1 portrait Google Supporting Different Screens *1 UI landscape UI 3.1: <activity android:name=".mainactivity" android:configchanges="orientation keyboardhidden" android:label="@string/app_name" android:screenorientation="portrait" > landscape youtube Activity landscape 3.2 minsdkversion Google Supporting Different Platform Versions *2 * 3 Android Android 1.6 minsdkversion="4" HT-03A Nexus 9 minsdkversion * 1 Supporting Different Screens http://developer.android.com/training/basics/supporting-devices/screens. html * 2 Supporting Different Platform Versions http://developer.android.com/training/basics/supporting-devices/ platforms.html * 3 Android G 61
3 Google 7 % Android % Android Devlopers Dashboards *4 2014 12 Froyo 0.5%, Gingerbread 9.1% minsdkversion="15" ICS Android 4.0.3 90.4% 2 Wikipedia: Android *5 1st 2 2.5 3rd Android * 4 Android Developers DashBoards http://developer.android.com/about/dashboards/ * 5 Wikipedia: Android http://ja.wikipedia.org/wiki/android%e7%ab%af%e6%9c%ab%e4% B8%80%E8%A6%A7 62
3 Google 7 3.1 minsdkversion Android Play 9 2.3.1 External Display/Miracast 17 4.2 Native RTL 17 4.2 Android Wear 18 4.3 BLE Centeral 18 4.3 Immersive 19 4.4 NFC HCE 19 4.4 BLE Peripheral 21 5.0 Android Wear BLE Bluetooth Low Energy Native RTL Immersive 2014 12 Gingerbread Android 4.1 4.3 Project Butter UI 4.2 1st Play Google Play Google Play Google Google Play Google Play Google / Google Play Google Play 63
3 Google 7 Play *6 Android Android Play Google Android 3.3 DialogFragment Google BACK Dialog Dialogs *7 Android 3.x Fragment Fragment DialogFragment Android Dialog DialogFragment Fragment 1 DialogFragment Fragment Fragment DialogFramgent DialogFragment Activity static inner class Master of Fragment *8 Dialog 2 DialogFragment BACK HOME * 6 Play https://play.google.com/store/apps/details?id=com.google.android.gms&hl=ja * 7 Dialogs http://developer.android.com/guide/topics/ui/dialogs.html * 8 Master of Fragment http://tatsu-zine.com/books/master-of-fragments 64
3 Google 7 DialogFragment AlertDialog.Builder Dialog Dialog#show DialogInterface.OnClickListener#onClick Activity DialogFragment 3 DialogFragment UI View ActionBarActivity#setSupportProgressBarIndeterminateVisibility GMail Chrome UNDO 3.4 PreferenceActivity Google Android 3.0 Activity PreferenceFragment Settings - UsingPreference Fragments *9 PreferenceActivity Android API Level 1 xml PreferenceActivity Android 3.x Fragment 2 PreferenceFragment deprecated * 9 Settings - Using Preference Fragments http://developer.android.com/guide/topics/ui/settings.html# Fragment 65
3 Google 7 PreferenceFragment Android 2.x Fragment Support Library PreferenceFragment 2.x PreferenceActivity 3.x PreferenceActivity PreferenceFragment 2 1 2 PreferenceActivity deprecated Android 2.x minsdkversion 15 PreferenceActivity PreferenceFragment 2 Google 3.2 3.3 66
3 Google 7 3.2 Android 4.4.3 Nexus 10 3.3 Android 5.0 Nexus 9 2 PreferenceFragment 67
3 Google 7 3.5 ContentProvider ContentProvider Content Providers *10 ContentProvider ContentProvider SNS SQLiteOpenHelper Cursor ContentProvider URI SQLite ContentProvider ios Core Data O/R Android ActiveAndroid *11 GreenDAO *12 OSS ContentProvider Content Provider * 10 Content Providers http://developer.android.com/guide/topics/providers/content-providers.html * 11 ActiveAndroid http://www.activeandroid.com/ * 12 GreenDAO http://greendao-orm.com/ 68
3 Google 7 3.6 Supporting Tablets and Handsets *13 2014 freetel Priori *14 6 QHD 2560x1440 Android 7 UI Android 7 Android layout xml UX XML layout_home.xml XML layout_home_tablet.xml Android Support Mulitple Screens * 13 Supporting Tablets and Handsets http://developer.android.com/guide/practices/tablets-and-handsets. html * 14 Android 4.1 3.5 HVGA(480x320) 2014.08 69
3 Google 7 UI 3.7 Google Android Pure Android *15 Don t use ios Google 1 Android 3.4 3.5 * 15 Pure Android http://developer.android.com/design/patterns/pure-android.html 70
3 Google 7 3.4 Android ios facebook 71
3 Google 7 3.5 Android ios Twitter WebView ios Android HTML SplitActionBar Google Button n 72
3 Google 7 SplitActionBar View 3.8 Google Google XML UI XML AbsoluteLayout TabActivity BACK UI BACK BACK launchmode standard singletop singletask singleinstance *16 Android * 16 73
4 UCD PlayStore 1 4.1 UX UI UX UI UX UI UX UCD UI/UX UX UserExperience UI UserInterface UX UI UI UX PlayStore AppStore UI/UX Google Apple UI Apple OS 74
4 UCD PlayStore 1 UI Google Apple UI UI UX UI UX UI UX UI UX UCD 4.2 UCD UCD HumanCentralDesign HCD UCD UserCenteredDesign HCD UCD UCD UCD UI UX UCD 75
4 UCD PlayStore 1 UCD 1999 ISO13407 *1 *2 NPO UCD 1986 D.A. "The Design of Everyday Things" *3 UCD 4.3 UCD 4 UCD UCD UCD 1. 2. * 1 ISO13407 2010 ISO9241-210 http://www.webstore.jsa.or.jp/webstore/ Com/FlowControl.jsp?lang=jp&bunsyoId=ISO+9241-210%3A2010&dantaiCd=ISO&status=1 * 2 http://www.hcdnet.org/ * 3 http://www.amazon.co.jp/dp/478850362x 76
4 UCD PlayStore 1 3. 4. 4 1 1 KA 77
4 UCD PlayStore 1 UX -> -> UCD UCD Photoshop Powerpoint UI Flash NEM 3 78
4 UCD PlayStore 1 5 8 5 UCD 4.4 UCD KA 1 79
4 UCD PlayStore 1 Google keynote 2014 Google I/O Google Japan DevFest Material Design Google Material Design Keynote keynote Apple Keynote keynotopia *4 Android 2014 11 MaterialDesign PDF PDF Play Store UCD Play Store UI UI UI * 4 http://keynotopia.com/ 80
4 UCD PlayStore 1 Play Store 2013 4.5 UCD UCD 81
4 UCD PlayStore 1 UCD UCD UCD *5 UCD 6 UI UX UX UCD UX UCD UCD UCD UX UX UCD Play Store Google Analytics UCD UCD Play Store UCD * 5 http://www.amazon.co.jp/dp/4274214834/ 82
4 UCD PlayStore 1 83
5 Android Gradle Gradle Eclipse Ant / Gradle Gradle Gradle Android 5.1 Android Studio 1.0.0 Android Gradle Plugin 1.0.0 Android Studio Android Studio 1.0.0 build.gradle 5.1 5.2 5.1: build.gradle // Top-level build file where you can add configuration options common buildscript { repositories { 84
5 Android Gradle jcenter() dependencies { classpath 'com.android.tools.build:gradle:1.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files allprojects { repositories { jcenter() 5.2: app/build.gradle apply plugin: 'com.android.application' android { compilesdkversion 21 buildtoolsversion "21.1.1" defaultconfig { applicationid "com.example.myapplication" minsdkversion 15 targetsdkversion 21 versioncode 1 versionname "1.0" buildtypes { release { minifyenabled false proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro' dependencies { compile filetree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:21.0.2' 85
5 Android Gradle applicationvariants libraryvariants 5.2 applicationid app/build.gradle android.defaultconfig applicationid apk applicationid 5.3: app/build.gradle applicationid apply plugin: 'com.android.application' android { defaultconfig { applicationid "com.example.myapplication" // Product Flavor applicationid Product Flavor Build Type applicationidsuffix applicationidsuffix applicationid applicationid AndroidManifest.xml package applicationid applicationid Play Store 86
5 Android Gradle : Id Android R Eclipse Gradle R R R Java Id applicationid R R 5.3 minsdkversion build.gradle app/build.gradle android.defaultconfig minsdkversion apk minsdkversion AndroidManifest.xml app/build.gradle minsdkversion AndroidManifest.xml uses-sdk android:minsdkversion 5.4: app/build.gradle minsdkversion apply plugin: 'com.android.application' android { 87
5 Android Gradle defaultconfig { applicationid "com.example.myapplication" minsdkversion 15 // 5.4 targetsdkversion build.gradle 5.3 minsdkversion build.gradle minsdkversion targetsdkversion 5.5: app/build.gradle targetsdkversion apply plugin: 'com.android.application' android { defaultconfig { applicationid "com.example.myapplication" minsdkversion 15 targetsdkversion 21 // 5.5 versioncode build.gradle Groovy versionname versioncode "1.2.3" versionname 1020300 versioncode versionname multiple apk version- 88
5 Android Gradle Code 5.6: app/build.gradle versioncode apply plugin: 'com.android.application' // def computeversioncode() { def versions = android.defaultconfig.versionname.split('\\.') def versioncode = String.format("%d%02d%02d00", versions[0].tointeger(), versions[1].tointeger(), versions[2].tointeger()).tointeger() return versioncode android { defaultconfig { versionname "1.2.3" versioncode computeversioncode() git commit short hash versionname 5.7 short hash githash 5.7: git short hash def githash = 'git rev-parse --short HEAD'.execute().text.trim() 5.6 apk Gradle Android Build Type Product Flavor 2 apk Build Type Product Flavor 89
5 Android Gradle Build Variant) apk *1 apk Build Type x Product Flavor *2 Build Type release debug Product Flavor Product Flavor 2 Build Type 1 Product Flavor 2 apk Eclipse Build Type Product Flavor apk applicationid Product Flavor / applicationid Product Flavor applicationid 5.7 Product Flavor Product Flavor Product Flavor applicationid Product Flavor applicationid 5.7 Product Flavor / Product Flavor Build Type debug Build Type Product Flavor Multiple APK Product Flavor * 1 Apk Splits apk * 2 Product Flavor dimension Product Flavor Build Type apk 90
5 Android Gradle API Level apk Multiple APK ABI apk 5.15 ABI apk density apk 5.16 density apk Build Type ProGuard jni apk Product Flavor Product Flavor 5.7 Product Flavor Build Type 5.8 Build Type 5.7 Product Flavor Product Flavor Build Type 5.6 apk Product Flavor app/build.gradle android productflavors Product Flavor 5.8 5.8: app/build.gradle Product Flavor android { defaultconfig { applicationid "com.example.myapplication" minsdkversion 15 targetsdkversion 21 versioncode 1 versionname "1.0" // Product Flavor productflavors { flavor1 { packagename "com.example.myapplication.flavor1" versioncode 20 91
5 Android Gradle flavor2 { packagename "com.example.myapplication.flavor2" minsdkversion 14 5.8 productflavors flavor1 flavor2 Product Flavor defaultconfig defaultconfig Product Flavor Product Flavor Product Flavor defaultconfig Gradle defaultconfig productflavors.* DSL Product Flavor src main Product Flavor Product Flavor main 5.8 Build Type Build Type Product Flavor 5.6 apk Build Type app/build.gradle android buildtypes Build Type 5.9 buildtypes release debug Build Type 5.9: app/build.gradle Build Type android { // Build Type 92
5 Android Gradle buildtypes { release { minifyenabled false proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro' jnidebug.initwith(buildtypes.debug) jnidebug { packagenamesuffix ".jnidebug" jnidebuggable true 5.9 buildtypes release jnidebug debug Build Type release initwith Build Type 5.9 jnidebug debug 5.1 debug release multidexenabled 5.10 manifestplaceholders 5.22 Build Type AndroidManifest 5.9 Build Type applicationid Build Type applicationid applicationid release debug debug Build Type applicationid defaultconfig Product Flavor ".debug" 93
5 Android Gradle 5.1 Build Type debug release debuggable true false jnidebuggable false false JNI / renderscriptdebuggable false false RS / renderscriptoptimlevel 3 3 RS applicationidsuffix null null Id versionnamesuffix null null signingconfig debug null zipalignenabled false true zipalign minifyenabled false false ProGuard / shrinkresources false false / proguardfile ProGuard proguardfiles ProGuard multidexenabled false false multi-dex / manifestplaceholders null null AndroidManifest app/build.gradle android.buildtypes.* applicationidsuffix null 5.10 applicationid.debug 5.10: Build Type applicationid apply plugin: 'com.android.application' android { buildtypes { debug { // applicationid.debug applicationidsuffix '.debug' 94
5 Android Gradle 5.10 Android dex 65k dex *3 dex 5.11 app/build.gradle 5.11: multidex android { defaultconfig { multidexenabled true dependencies { compile 'com.android.support:multidex:1.0.0' 5.11 defaultconfig Product Flavor Build Type AndroidManifest.xml android.support.multidex.multidexapplication Application attachbasecontext(context) android.support.multidex.multidex.install(this); * 3 https://developer.android.com/tools/building/multidex.html 95
5 Android Gradle 5.12 android.support.multidex.multidexapplication 5.12: AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication" > <application android:name="android.support.multidex.multidexapplication"> </application> </manifest> minsdkversion 21 multidex dex ANR ProGuard dex API Level 14 Dalvik linearalloc *4 ProGuard Dalvik linearalloc limit *5 API Level 14 API Level 21 dex * 4 http://b.android.com/22586 * 5 http://b.android.com/78035 96
5 Android Gradle : multidex minsdkversion 21 21 multidex minsdkversion 21 ART ART dex oat dex minsdkversion 21 Dalvik dex dex dex dex minsdkversion 21 multidex minsdkversion 21 Product Flavor Product Flavor 5.11 ProGuard ProGuard android.buildtypes.* Build Type release 5.13 release ProGuard 5.13: app/build.gradle ProGuard android { buildtypes { release { // ProGuard minifyenabled true proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro' 97
5 Android Gradle getdefaultproguardfile() Android SDK ProGuard <SDK ROOT>/tools/proguard/ proguard-android.txt proguard-androidoptimize.txt debug Build Type ProGuard release proguardfiles Build Type release debug ProGuard 5.12 apk 1 Google Play Services 5.14 apk 5.14: android { defaultconfig { resconfigs "en", "ja" 98
5 Android Gradle 5.13 apk 2 Google Play Services 5.11 ProGuard shrinkresources 5.15 Build Type shrinkresources 5.15: android { buildtypes { release { // ProGuard shrinkresources minifyenabled true shrinkresources true proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro' shrinkresources minifyenabled 99
5 Android Gradle shrinkresources Gradle --info Strict Safe Safe Safe Resources#getIdentifier() format string 5.16 res/raw/keep.xml Strict apk 5.16: res/raw/keep.xml Strict <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkmode="strict" /> Strict 100
5 Android Gradle tools:keep tools:discard 5.17 5.17: res/raw/keep.xml <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkmode="safe" tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*" tools:discard="@layout/unused2" /> tools:keep apk tools:discard * 5.14 RenderScript Support Library RenderScript Support Library API Level 8 Android 2.2, Froyo RenderScript RenderScript Support Library RenderScript Support Library app/build.gradle android.defaultconfig android.productflavors.* 5.18 defaultconfig 5.18: app/build.gradle RenderScript Support Library android { defaultconfig { // support renderscript 101
5 Android Gradle renderscriptsupportmodeenabled true renderscripttargetapi 21 renderscriptoptimlevel 3 renderscriptndkmodeenabled false RenderScript Support Library ProGuard 5.19 app/proguard-rules.pro 5.19: app/proguard-rules.pro # RenderScript Support Library -keep class android.support.v8.renderscript.** { *; ProGuard 5.11 ProGuard 5.15 ABI apk apk splits ABI apk 5.20 5.20: ABI apk android { splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'mips' universalapk true 102
5 Android Gradle ext.versioncodes = ['armeabi-v7a':1, 'mips':2, 'x86':3] import com.android.build.outputfile android.applicationvariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> def filter = output.getfilter(outputfile.abi) if (filter == null) { // universal apk return output.versioncodeoverride = project.ext.versioncodes.get(filter) * 1000000 + android.defaultconfig.versioncode android.splits.abi apk enable 5.34 IDE IDE reset() include include ABI include ABI ABI include include reset() exclude include universalapk 103
5 Android Gradle ABI apk false versioncode Play Store versioncode Google *6 5.16 density apk apk splits density apk 5.21 5.21: apk android { splits { density { enable true exclude "ldpi", "tvdpi", "xxxhdpi" compatiblescreens 'small', 'normal', 'large', 'xlarge' ext.versioncodes = ['ldpi':1,'mdpi':2, 'tvdpi': 3,'hdpi':4, 'xhdpi':5, 'xxhdpi':6, 'xxxhdpi':7] import com.android.build.outputfile android.applicationvariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> def filter = output.getfilter(outputfile.density) if (filter == null) { // universal apk * 6 http://developer.android.com/google/play/publishing/multiple-apks.html 104
5 Android Gradle return output.versioncodeoverride = project.ext.versioncodes.get(filter) * 1000000 + android.defaultconfig.versioncode android.splits.abi apk enable 5.34 IDE IDE reset() include include DENSITY include include include reset() exclude include compatiblescreens screen size apk AndroidManifest.xml <compatible-screens><screen > ABI universal apk universal apk versioncode Play Store versioncode Google *7 * 7 http://developer.android.com/google/play/publishing/multiple-apks.html 105
5 Android Gradle ABI Product Flavor versioncode versioncode Build Type versioncode 5.17 / Build Type Product Flavor *Compile Build Type 5.22 debug grid layout 5.22: debug dependencies { //Build Type *Compile debugcompile 'com.android.support:gridlayout-v7:21.0.2' Product Flavor 5.18 Build Type Product Flavor Build Type Product Flavor configurations configuration 5.23 flavor1+debug EventBus 5.23: 106
5 Android Gradle android { productflavors { flavor1 { flavor2 { // // configuration configurations { // flavor1, debug ( ) flavor1debugcompile dependencies { // flavor1debug flavor1debugcompile 'de.greenrobot:eventbus:2.4.0' 5.19 Gradle 5.24 google-api-client-android google-api-client-android 5.24: dependencies { 107
5 Android Gradle compile('com.google.api-client:google-api-client-android:1.18.0-rc') { exclude module: 'xpp3' exclude module: 'httpclient' exclude module: 'junit' exclude module: 'android' apk 5.20 A B A B git submodule maven AAR *8 Gradle../mylibrary/ library settings.gradle 5.25 5.26 5.25: settings.gradle * 8 108
5 Android Gradle include ':app' 5.26: settings.gradle include ':app', ':library' project(':library').projectdir = new File(settingsDir, '../mylibrary/library') :library 1../mylibrary/library new File(settingsDir, " ") settingsdir Gradle settings.gradle Android Studio UI Sync Project with Gradle Files Android Studio build.gradle dependencies compile project( :library ) settings.gradle :library 5.21 dependencies compile project( :library ) debug 109
5 Android Gradle build.gradle 5.27 5.27: app/proguard-rules.pro android { // release/debug defaultpublishconfig "librelease" publishnondefault true productflavors { lib release lib Product Flavor Product Flavor Product Flavor dependencies 5.28 mylibrary 5.28: dependencies { // 110
5 Android Gradle debugcompile project(path: ':mylibrary', configuration: 'libdebug') releasecompile project(path: ':mylibrary', configuration: 'librelease') 5.22 Build Type AndroidManifest Google Play Services Maps v2 AndroidManifest.xml Build Type Build Type AndroidManifest.xml Manifest merger AndroidManifest.xml build.gradle buildtypes AndroidManifest.xml build.gradle 5.29 AndroidManifest.xml 5.29: app/build.gradle android { buildtypes { release { manifestplaceholders = [maps2_key: ' API '] debug { manifestplaceholders = [maps2_key: ' API '] 111
5 Android Gradle :, groovy map tostring() AndroidManifest.xml build.gradle AndroidManifest.xml ${ 5.30: AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication" > <application android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name=".myapplication" android:theme="@style/apptheme" > <!-- build.gradle ${ --> <meta-data android:name="com.google.android.maps.v2.api_key" android:value="${maps2_key"/> manifestplaceholders applicationid manifestplaceholders Build Type Product Flavor 112
5 Android Gradle 5.23 BuildConfig R BuildConfig 5.31 5.31: BuildConfig /** * Automatically generated file. DO NOT MODIFY */ package com.example.myapplication; public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.example.myapplication"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = ""; public static final int VERSION_CODE = 100; public static final String VERSION_NAME = "1.2.3"; Product Flavor build.gradle git commit short hash 5.32 5.32: app/build.gradle android { defaultconfig { def githash = 'git rev-parse --short HEAD'.execute().text.trim() buildconfigfield "String", "GIT_HASH", "\"" + githash + "\"" 113
5 Android Gradle buildconfigfield 3 FQCN public static final arg1 arg2 = arg3; BuildConfig " 5.32 BuildConfig.java 5.33 5.33: GIT_HASH BuildConfig /** * Automatically generated file. DO NOT MODIFY */ package com.example.myapplication; public final class BuildConfig { public static final boolean DEBUG = Boolean.parseBoolean("true"); public static final String APPLICATION_ID = "com.example.myapplication"; public static final String BUILD_TYPE = "debug"; public static final String FLAVOR = ""; public static final int VERSION_CODE = 100; public static final String VERSION_NAME = "1.2.3"; // Fields from default config. public static final String GIT_HASH = "8475e49"; buildconfigfield Product Flavor Build Type 5.34 5.34: buildconfigfield applicationvariants.all { variant -> // variant variant variant.buildconfigfield "int", "VALUE", "1" 114
5 Android Gradle 5.24 PC 5.35 gradle.properties local.properties release 5.35: app/build.gradle android { // signingconfig signingconfigs { release buildtypes { release { // release signingconfig // gradle.properties local.properties if (project.hasproperty('storefile')) { signingconfig signingconfigs.release dependencies { 115
5 Android Gradle // android.signingconfigs.release if (project.hasproperty('storefile')) { android.signingconfigs.release.storefile = file(storefile) if (project.hasproperty('storepassword')) { android.signingconfigs.release.storepassword = storepassword if (project.hasproperty('keyalias')) { android.signingconfigs.release.keyalias = keyalias if (project.hasproperty('keypassword')) { android.signingconfigs.release.keypassword = keypassword gradle.properties local.properties 5.36 5.36: storefile=/users/zaki/.android/release.keystore storepassword=hug8urv0ab5yant0 keyalias=app_release keypassword=hug8urv0ab5yant0 storefile storepassword keyalias alias keypassword keyalias app/build/outputs/apk/ apk 116
5 Android Gradle 5.25 Maps API API 5.37 5.37: android { // debug signingconfigs { debug { // ( ) debug.keystore storefile file("../debug.keystore") debug.keystore.android/debug.keystore 5.26 Android Wear Android Studio File New Module 5.1 Android Wear Module Next 117
5 Android Gradle 5.1 wear wear settings.gradle include :wear wear apk app/build.gradle dependencies 5.38 5.38: app/build.gradle dependencies wearapp project(':wear') wearapp Android Wear project() : Gradle 118
5 Android Gradle 5.27 5.39 5.39: android.applicationvariants.all { variant -> // println variant.properties android.applicationvariants.each{ each all all 5.28 lint android.lintoptions lint 5.40: lint android { lintoptions { // true quiet true // true lint abortonerror false // true warning ignorewarnings true // true ( true) absolutepaths true // true checkallwarnings true // true 119
5 Android Gradle warningsaserrors true // id disable 'TypographyFractions','TypographyQuotes' // id enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' // id check 'NewApi', 'InlinedApi' // true nolines true // true showall true // lint lintconfig file("default-lint.xml") // true textreport true // ('stdou' ) textoutput 'stdout' // true XML xmlreport false // XML ( 'lint-results.xml') xmloutput file("lint-report.xml") // true HTML htmlreport true // HTML ( 'lint-results.html') htmloutput file("lint-report.html") // fatal checkreleasebuilds true // id fatal fatal 'NewApi', 'InlineApi' // id error 'Wakelock', 'TextViewEdits' // id warning 'ResourceAsColor' // id ignore 'TypographyQuotes' 120
5 Android Gradle 5.29 assets asset app/build.gradle android aaptoptions apk 5.41: asset android { aaptoptions { // apk ignoreassetspattern "!.svn:!.git:<dir>_*:.*:!cvs:!thumbs.db" ignore pattern 5.42 ignore pattern aapt --ignore-assets 5.42: ignorepattern!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!cvs:!thumbs.db:!picasa.ini:!*~ : :! <dir> <file> 121
5 Android Gradle! <dir> <file> * / * 5.30 jni.so.so src/main/jnilibs/ apk jnilibs ABI ABI armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64 5.31 NDK *.c *.cpp Gradle NDK *.c *.cpp src/main/ jni NDK NDK local.properties ndk.dir 5.43 122
5 Android Gradle 5.43: NDK local.properties sdk.dir=/applications/android-sdk ndk.dir=/applications/android-ndk-r10d src/main/jni *.c *.cpp app/build.gradle android defaultconfig ndk Android.mk Application.mk 5.44: ndk android { defaultconfig { // NDK ndk { modulename "native_library" stl "gnustl_shared" // "gnustl_static" abifilters 'all' cflags "-DANDROID_NDK" // ABI //abifilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', // 'x86', 'x86_64', 'mips', 'mips64' ldlibs "log" apk 123
5 Android Gradle 5.32 / apache commons *9 apk android packagingoptions 5.45: android { packagingoptions { exclude 'META-INF/NOTICE.txt' pickfirst 'META-INF/LICENSE.txt' 5.45 exclude pickfirst exclude apk apk exclude pickfirst apk apk jar * 9 commons jar META-INF/LICENSE.txt META-INF/NOTICE.txt 124
5 Android Gradle 5.33 apk apk *10 Android Studio Android Studio app app-debug.apk apk app-debug.apk apk app/build.gradle 5.46 my_application-v1.2.3-debug.apk release 5.46: apk def toapkfile(originalfile) { def nameprefix = "my_application" def name = originalfile.name.replace(project.name, nameprefix + "-v" + android.defaultconfig.versionname) return new File(originalFile.parentFile, name) android.applicationvariants.all { variant -> // apk splits variant.outputs variant.outputs.each { output -> // output.outputfile = toapkfile(output.outputfile) if (output.packageapplication.outputfile!= output.outputfile) { // zipalign output.packageapplication.outputfile = toapkfile(output.packageapplication.outputfile) * 10 apk app/build/outputs/apk/ 125
5 Android Gradle my_application nameprefix 1 apk Android Studio apk 5.34 IDE IDE 5.34 IDE 5.33 apk IDE 5.47 IDE 5.47: IDE // Android Studio -Pandroid.injected.invoked.from.ide=true def isidebuild = project.properties['android.injected.invoked.from.ide'] if (isidebuild == null isidebuild.equalsignorecase("true")) { // IDE else { // IDE 5.35 predex predex predex predex skip 126
5 Android Gradle 5.48 build.gradle 5.48: predex skip project.ext { // -PdisablePreDex predexlibs =!project.hasproperty('disablepredex') subprojects { // project.plugins.whenpluginadded { plugin -> if ("com.android.build.gradle.appplugin".equals(plugin.class.name)) { project.android.dexoptions.predexlibraries = rootproject.ext.predexlibs else if ("com.android.build.gradle.libraryplugin".equals(plugin.class.name)) { project.android.dexoptions.predexlibraries = rootproject.ext.predexlibs gradle -PdisablePreDex predex 5.36 Gradle Gradle Gradle Gradle SCM *11 Gradle Gradle Android Studio Android Studio Gradle *12 * 11 Source Code Management * 12 Version Compatibility http://tools.android.com/tech-docs/new-build-system/version-compatibility 127
5 Android Gradle Gradle Gradle Android Studio 5.2 5.2 5.49 build.properties Gradle Gradle Gradle gradleversion Gradle 5.49: Gradle task wrapper(type: Wrapper) { gradleversion = '2.2.1' Windows $. gradlew.bat wrapper Windows 128
5 Android Gradle $./gradlew wrapper gradle Gradle gradle/wrapper/gradle-wrapper.properties Gradle gradle-wrapper.properties 5.50 5.50: gradle-wrapper.properties #Thu Nov 20 19:00:38 JST 2014 distributionbase=gradle_user_home distributionpath=wrapper/dists zipstorebase=gradle_user_home zipstorepath=wrapper/dists distributionurl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip distributionurl 2.2.1 Gradle all bin Gradle bin all distributionurl Gradle Gradle 5.37 ProGuard ProGuard ProGuard mapping.txt mapping.txt 5.51 mapping.txt 129
5 Android Gradle 5.51: mapping.txt android.applicationvariants.all { variant -> def mappingfile = variant.mappingfile if (mappingfile!= null) { // PrGuard // ProGuard mappingfile null 5.38 1 Gradle Android Google Groups Android Studio android gradle plugin 1.0 Gradle groovy Java Gradle Android Gradle 130
6 Docker Docker 6.1 Docker Virtualization Virtual Virtual Virtual Machine VM 1 Machine X Y X VM 1 131
6 Docker Docker Docker Docker Docker Docker Docker Docker docker Docker Hub Docker Docker Docker 6.2 VM Docker VM Virtual Machine VM 1 OS OS OS Container based chroot 1980 132
6 Docker VM OS OS *1 Unix OS OS OS VM OS OS Docker init *2 OS Linux Kernel CPU *3 VM *4 root * 1 Docker Linux Kernel http://blog.etsukata. com/2014/05/docker-linux-kernel.html * 2 Unix * 3 http://fabiokung.com/2014/03/13/memory-inside-linux-containers/ * 4 Docker http://www.slideshare.net/jpetazzo/ docker-linux-containers-lxc-and-security 133
6 Docker 6.3 Docker VM OS VM Docker VM IBM *5 Docker VM *6 VM VM 6.4 Docker Docker Docker Wikipedia *7 Docker 14 Docker 3 docker Docker Hub * 5 Wes Felter, Alexandre Ferreira, Ram Rajamony, Juan Rubio "An Updated Performance Comparison of Virtual Machines and Linux Containers" http://domino.research.ibm.com/library/cyberdig.nsf/papers/ 0929052195DD819C85257D2300681E7B/$File/rc25482.pdf * 6 http://yuuki.hatenablog.com/entry/dockerized-isucon Docker * 7 http://en.wikipedia.org/wiki/operating_system%e2%80%93level_virtualization 134
6 Docker Docker OS Vagrant *8 Docker Docker Docker Amazon Google Docker 6.5 Docker Docker Griflet Docker GitHub PDF EPUB *9 Re:VIEW *10 Griflet Re:VIEW OS PDF EPUB OS Re:VIEW * 8 https://www.vagrantup.com/ * 9 Griflet PyCon Japan 2014 https://pycon.jp/2014/ reports/slides/ "Continuous Publication" with Python: Another Approach * 10 https://github.com/kmuto/review Markdown Re:VIEW 135
6 Docker Griflet MB GB Docker Griflet Docker OS VM VM 6.6 VM Docker Docker VM VM Docker OS OS Docker Docker Docker Hub 136
6 Docker Ubuntu 14.04 LTS + Redis Ubuntu 14.04 LTS + Redis + Shibboleth IdP + owncloud + X Server + Zabbix VPS Docker OS VM VM Docker Docker Docker VM OS Docker VM Docker 6.7 Docker Docker 1 *11 * 11 Monolithic Monolith 2001 137
6 Docker 1 VM VM IaaS Infrastructure as a Service IaaS VM root Docker root *12 1 Docker Unix OS Docker OS 1 * 12 http://www.slideshare.net/jpetazzo/docker-linux-containers-lxc-and-security 138
6 Docker A/B *13 IP Docker Docker Hub Docker Hub Docker Hub GitHub GitHub git Docker *14 Docker Hub OS 1 * 13 * 14 Macro Micro http://martinfowler.com/articles/microservices.html IT 139
6 Docker Ruby RVM Python pyvenv Docker 6.8 HTTP JSON REST RPC Remote Proceduce Call 2 REST API HTTP JavaScript Docker Docker Docker 140
6 Docker Docker Docker 6.9 Docker Docker Docker PDF EPUB Docker 30 IP IP 141
6 Docker Docker 6.10 GKE Google Cloud Engine ECS Amazon EC2 Container Services GKE Kubernetes GKE ECS VM Docker Docker Kubernetes *15 *16 Kubernetes Master Minion *17 2 Master Minion Docker etcd *18 REST * 15 https://github.com/googlecloudplatform/kubernetes Google Developer Advocate https://twitter.com/kazunori_279/status/ 488232794943156225 Google I/O http://www.biblestudytools.com/lexicons/greek/nas/kubernetes.html * 16 Kubernetes https://github.com/googlecloudplatform/kubernetes/ blob/master/design.md Google Compute Engine * 17 Minion * 18 https://coreos.com/using-coreos/etcd/ CoreOS Linux Key-Value Store DB etcd CoreOS 142
6 Docker Master Minion Minion Docker Docker Kubernetes Pod Kubelet Minion Agent Label Pod Minion Kubernetes Proxy Minion Proxy TCP Kubernetes Docker Minion Pod Master Master Minion 1 Kubernetes ECS Programmatic Control Task Definitions Scheduler Kubernetes *19 GKE ECS Docker Docker OS Docker Docker OS https://coreos.com/blog/rocket/ * 19 http://aws.amazon.com/ecs/details/ 143
6 Docker Docker 6.11 Docker Docker Docker Docker Hub VM Docker Hub Docker Docker Linux Docker Linux Docker Docker VPS EC2 VM Docker MySQL Docker MySQL 144
6 Docker MySQL : Amazon Aurora 4 MySQL DB AWS Amazon Web Services Amazon Aurora MySQL Docker Hub Docker 145
6 Docker MySQL Kubernetes Docker Hub 6.12 Docker Docker Docker Docker x86_64 Linux ARM 146
6 Docker 32bits *20 2014 10 Docker Docker Linux Docker Docker *21 Windows Server Docker Hub Windows Server "docker pull" SQL DB OS CentOS Windows Server Kubernetes Docker Hub Docker Docker 1.3 Docker Hub Docker Docker Docker * 20 https://github.com/docker/docker/issues/611 * 21 http://weblogs.asp.net/scottgu/docker-and-microsoft-integrating-docker-with-windows-server-andmicrosoft-azure 147
6 Docker Docker OS VM Linux Docker Docker Docker Docker Docker 148
6 Docker *22 Docker Docker Kernel GPU 6.13 Docker Docker Docker OS * 22 Google Amazon https://plus.google.com/+riprowan/posts/eveouesvavx http: //anond.hatelabo.jp/20111018190933 149
6 Docker for SQL OR KVS Upgrade to Premioum Container! A B C Google *23 * 23 http://s-wars.jp/ 150
6 Docker 6.14 Docker Docker *24 Android : Docker Docker GKE ECS Kubernetes Docker Machine, Swarm Docker Docker Hub Enterprise, IBM VMWare Rocket Docker * 24 Docker Docker Hub 151
/ @cattaka_net / @youten_redo / @_mochicon_ MYO / @zaki50 IntelliJ IDEA 14 Re:VIEW Re:VIEW / @amedama 32 / shati / siosio 152
Android 2014 12 30 v1.0.0 TechBooster mhidaka TechBooster (C) 2014 TechBooster 153