Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Architecture Components

takahirom
June 02, 2017
1.3k

Android Architecture Components

takahirom

June 02, 2017
Tweet

More Decks by takahirom

Transcript

  1. ⟃♴אךإحءّٝ ˖ *OUSPEVDUJPO ˖ "OESPJE"SDIJUFDUVSF$PNQPOFOUTך嚊銲铡僇 ˖ "OESPJE%FWFMPQFSTך
 (VJEFUP"QQ"SDIJUFDUVSF ˖ 4PMWJOHUIF-JGFDZDMF1SPCMFN

    ˖ -JGFDZDMFꟼ鸬ך$PNQPOFOUT ˖ 1FSTJTUFODFBOE0JOF ˖ 宕竲⻉ٓ؎ـٓٔך3PPN $PNQPOFOUTךא (PPHMF*0דך "SDIJUFDUVSF$PNQPOFOUT
  2. – Android DevelopersͷAndroid Architecture ComponentsΑΓ l"OFXDPMMFDUJPOPGMJCSBSJFTUIBUIFMQZPV EFTJHOSPCVTU UFTUBCMF BOENBJOUBJOBCMF BQQT

    4UBSUXJUIDMBTTFTGPSNBOBHJOHZPVS6* $PNQPOFOUTMJGFDZDMFBOEIBOEMJOHEBUB QFSTJTUFODFz 㛙暕דծذأز〳腉דծًٝذشٝأ׃װְׅ،فٔך 鏣鎘׾⸔ֽ׷倜׃ְٓ؎ـٓٔך꧊ת׶דׅկ 6*؝ٝه٦طٝزךٓ؎ؿ؟؎ؙٕך盖椚ה ر٦ةך宕竲⻉׾䪔ֲ׋׭ךؙٓأַ׵㨣׭ג׫ת׃׳ֲկ
  3. "SDIJUFDUVSF$PNQPOFOUTך 圓䧭銲稆 ˖ -JGFDZDMF0XOFS -JGFDZMF0CTFSWFS ˖ ٓ؎ؿ؟؎ؙٕ׾䠐陎׃׋؝ٝه٦طٝز׾⡲䧭ׅ׷ֿהָ
 דֹ׷ ˖ -JWF%BUB

    ˖ 錁庠〳腉 0CTFSWBCMF זر٦ةمٕت٦ ˖ 7JFX.PEFM ˖ 6*חꟼ鸬ׅ׷ر٦ة׾⥂䭯ׅ׷ؙٓأ ˖ 3PPN ˖ 42-JUF׾知⽃ח䪔ֲٓ؎ـٓٔ
 42-JUFךػٙ٦׾崞欽׃ծ厫鮾חر٦ةك٦أח،ؙإأדֹ׷ؔـ آؙؑزوحؾؚٝ䬄韋⻉ٖ؎َ٦׾䲿⣘
  4. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) this.lifecycle.addObserver(MyObserver()) } } class MyObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d("MyObserver","onResume") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d("MyObserver","onPause") } } -JGFDZDMF0XOFS  -JGFDZMF0CTFSWFSהכ ٓ؎ؿ؟؎ؙٕ׾䠐陎׃׋؝ٝه٦طٝز׾⡲䧭ׅ׷ֿהָ
 דֹ׷
  5. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) this.lifecycle.addObserver(MyObserver()) } } class MyObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d("MyObserver","onResume") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d("MyObserver","onPause") } } -JGFDZDMF0XOFS  -JGFDZMF0CTFSWFSהכ -JGFDZDMF"DUJWJUZכ -JGFDZDMF0XOFS׾㹋鄲׃גְ׷ "QQ$PNQBU"DUJWJUZח窟さ✮㹀
  6. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) this.lifecycle.addObserver(MyObserver()) } } class MyObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d("MyObserver","onResume") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d("MyObserver","onPause") } } -JGFDZDMF0XOFS  -JGFDZMF0CTFSWFSהכ -JGFDZDMF0XOFSַ׵ -JGFDZDMFؔـآؙؑز׾《䖤׃ BEE0CTFSWFSׅ׷
  7. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) this.lifecycle.addObserver(MyObserver()) } } class MyObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d("MyObserver","onResume") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d("MyObserver","onPause") } } -JGFDZDMF0XOFS  -JGFDZMF0CTFSWFSהכ -JGFDZDMF0CTFSWFSדכ !0O-JGFDZDMF&WFOUדٓ؎ؿ؟؎ؙٕך ؎كٝز׾「ֽ《׷ֿהָ⳿勻׷
  8. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) this.lifecycle.addObserver(MyObserver()) } } class MyObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d("MyObserver","onResume") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d("MyObserver","onPause") } } -JGFDZDMF0XOFS  -JGFDZMF0CTFSWFSהכ ٓ؎ؿ؟؎ؙٕ׾䠐陎׃׋؝ٝه٦طٝزָ⡲䧭דֹ׷
  9. ˖ 錁庠〳腉 0CTFSWBCMF זر٦ةمٕت٦ ˖ ٓ؎ؿ؟؎ؙٕח״׶⹛ָֹ㢌׻׷ val stringLiveData = //

    LiveDataΫϥεͷΠϯελϯε࡞੒ stringLiveData.observe(this, Observer<String?> { value -> // σʔλΛऔಘɺมߋ͞ΕͨΒݺ͹ΕΔ }) -JWF%BUB
  10. class LocationLiveData(context: Context) : LiveData<Location>() { private val locationManager: LocationManager

    = context.getSystemService( Context.LOCATION_SERVICE) as LocationManager private val listener = object : LocationListener { override fun onLocationChanged(location: Location) { value = location } … } override fun onActive() { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, listener) } override fun onInactive() { locationManager.removeUpdates(listener) } } -JWF%BUBך⡲׶倯 ⡘縧䞔㜠׾床ׅ-JWF%BUBך⢽
  11. class LocationLiveData(context: Context) : LiveData<Location>() { private val locationManager: LocationManager

    = context.getSystemService( Context.LOCATION_SERVICE) as LocationManager private val listener = object : LocationListener { override fun onLocationChanged(location: Location) { value = location } … } override fun onActive() { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, listener) } override fun onInactive() { locationManager.removeUpdates(listener) } } -JWF%BUBך⡲׶倯 -JWF%BUBؙٓأ׾竰䪫ׅ׷
  12. class LocationLiveData(context: Context) : LiveData<Location>() { private val locationManager: LocationManager

    = context.getSystemService( Context.LOCATION_SERVICE) as LocationManager private val listener = object : LocationListener { override fun onLocationChanged(location: Location) { value = location } … } override fun onActive() { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, listener) } override fun onInactive() { locationManager.removeUpdates(listener) } } -JWF%BUBך⡲׶倯 PO"DUJWF ד -PDBUJPO.BOBHFSךٔأش٦׾إحز
  13. class LocationLiveData(context: Context) : LiveData<Location>() { private val locationManager: LocationManager

    = context.getSystemService( Context.LOCATION_SERVICE) as LocationManager private val listener = object : LocationListener { override fun onLocationChanged(location: Location) { value = location } … } override fun onActive() { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, listener) } override fun onInactive() { locationManager.removeUpdates(listener) } } -JWF%BUBך⡲׶倯 ⡘縧䞔㜠ח㢌刿ָ֮׏׋׵-JWF%BUBTFU7BMVF׾ㄎן⳿ׅ
  14. class LocationLiveData(context: Context) : LiveData<Location>() { private val locationManager: LocationManager

    = context.getSystemService( Context.LOCATION_SERVICE) as LocationManager private val listener = object : LocationListener { override fun onLocationChanged(location: Location) { value = location } … } override fun onActive() { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, listener) } override fun onInactive() { locationManager.removeUpdates(listener) } } -JWF%BUBך⡲׶倯 PO*OBDUJWF ד ٔأش٦׾⵴ꤐׅ׷
  15. class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val stringLiveData = // LiveDataΫϥεͷΠϯελϯε࡞੒ stringLiveData.observe(this, Observer<String?> { value -> // σʔλΛऔಘɺมߋݕ஌ }) 歗꬗㔐鯄儗ח"DUJWJUZָⱄ欰䧭ׁ׸ծת׋PO$SFBUFָㄎל׸ծ ⱄ《䖤ׁ׸ג׃תֲ -JWF%BUB׾⢪׏גְ׷儗ח 歗꬗㔐鯄ָ饯ֿ׷הծծ ׉ֿד7JFX.PEFM
  16. 7JFX.PEFM class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val activityViewModel = ViewModelProviders.of(this) .get(MyActivityViewModel::class.java) val locationLiveData = activityViewModel.locationLiveData locationLiveData.observe(this, Observer<Location?> { location -> // }) ... } class MyActivityViewModel(application: Application):
 AndroidViewModel(application) { val locationLiveData: LocationLiveData = LocationLiveData(application) }
  17. 7JFX.PEFM class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val activityViewModel = ViewModelProviders.of(this) .get(MyActivityViewModel::class.java) val locationLiveData = activityViewModel.locationLiveData locationLiveData.observe(this, Observer<Location?> { location -> // }) ... } class MyActivityViewModel(application: Application):
 AndroidViewModel(application) { val locationLiveData: LocationLiveData = LocationLiveData(application) } 7JFX.PEFM1SPWJEFSTַ׵7JFX.PEFM׾《䖤ׅ׷
  18. 7JFX.PEFM class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val activityViewModel = ViewModelProviders.of(this) .get(MyActivityViewModel::class.java) val locationLiveData = activityViewModel.locationLiveData locationLiveData.observe(this, Observer<Location?> { location -> // }) ... } class MyActivityViewModel(application: Application):
 AndroidViewModel(application) { val locationLiveData: LocationLiveData = LocationLiveData(application) } 7JFX.PEFMדכ-JWF%BUB׾⥂䭯ׅ׷ "OESPJE7JFX.PEFM׾⢪ֲהBQQMJDBUJPOָ⢪ִ׷
  19. 7JFX.PEFM class MyLifecycleActivity : LifecycleActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val activityViewModel = ViewModelProviders.of(this) .get(MyActivityViewModel::class.java) val locationLiveData = activityViewModel.locationLiveData locationLiveData.observe(this, Observer<Location?> { location -> // }) ... } class MyActivityViewModel(application: Application): ViewModel() { val locationLiveData: LocationLiveData = LocationLiveData(application) } -JWF%BUBך朐䡾׾湊鋔ׅ׷
  20. &OUJUZ @Entity class Memo(@PrimaryKey(autoGenerate = true) val uid: Int =

    0, val title: String, val text: String) !&OUJUZ׾אֽ׷ !1SJNBSZ,FZד1SJNBSZ,FZה׃גو٦ؙ׾אֽ׋׶ծ JE׾⹧䩛ח⡲׏גֻ׸׷ؔفءָّ֮ٝ׏׋׶ׅ׷
  21. %BUB"DDFTT0CKFDU @Dao interface MemoDao { @Query("SELECT * FROM memo ORDER

    BY uid DESC") fun get(): LiveData<List<Memo>> @Insert fun insertAll(vararg memos: Memo) @Update fun editMemo(memo: Memo) } !%BP׾אֽ׷ ؝ٝػ؎ٕ儗ח!2VFSZך42-ךⰻ㺁ָ嗚鏾ׁ׸׷ ؝ٝػ؎ٕ儗ח؝٦سָ欰䧭ׁ׸׷ 鵤׶⦼ח-JWF%BUBװ3Y+BWBך'MPXBCMF׾ⵃ欽ׅ׷ה
 ر٦ةك٦أך刿倜׾「ֽ《׸׷
  22. 3PPN%BUBCBTF @Database(entities = arrayOf(Memo::class), version = 1) abstract class AppDatabase

    : RoomDatabase() { abstract fun memoDao(): MemoDao } val db = Room.databaseBuilder(application, AppDatabase::class.java, "database-name").build() fun getMemo(): LiveData<List<Memo>> { return db.memoDao().get() } !%BUBCBTF׾אֽ׷ FOUJUJFTװWFSTJPO׾䭷㹀ׅ׷
  23. (VJEFUP"QQ"SDIJUFDUVSF ⰻ㺁 ˖ "OESPJE،فٔꟚ涪ח黝欽ׁ׸׷ ⾱⵱ך㹀纏 ˖ ׉ך⾱⵱׾黝欽דֹ׷
 ،فٔ،٦ؗذؙثٍך铡僇 ˖ ،٦ؗذؙثٍ؝ٝه٦طٝز׾

    ⢪׏׋،٦ؗذؙثٍך㹋鄲倯岀 ך铡僇 IUUQTEFWFMPQFSTKQHPPHMFCMPHDPNBOESPJEBOEBSDIJUFDUVSFIUNM״׶ IUUQTEFWFMPQFSBOESPJEDPNUPQJDMJCSBSJFTBSDIJUFDUVSFHVJEFIUNM
  24. אך鏣鎘ך♳דꅾ銲ז銲稆ָ֮׷ה剅ַ׸גְ׷կ ˖ ְ׍ל׿ꅾ銲זךכꟼ䗰✲ךⴓꨄկ"DUJWJUZװ 'SBHNFOUחⰋג剅ַ׸׷ךָ״ֻ֮׷꟦麩ְկ ˖ 04ח״׶盖椚ׁ׸׷ؙٓأד֮׶ծ
 ٓ؎ؿ؟؎ؙٕך㉏겗׾鼘ֽ׷׋׭կ  ˖ 宕竲⻉ׁ׸׋ٌرַٕ׵6*׾⹛ַֿׅהկ

    ˖ 04ח״׷ٔا٦أ鍑佝הطحزٙ٦ؙ䱸竲ָ♶ 㸜㹀ז儗חِ٦ؠ٦ָر٦ة׾㣟׻זְ״ֲח ׅ׷׋׭կ "OESPJE،فٔꟚ涪ח黝欽ׁ׸׷⾱⵱ך㹀纏
 $PNNPOBSDIJUFDUVSBMQSJODJQMFT IUUQTEFWFMPQFSBOESPJEDPNUPQJDMJCSBSJFTBSDIJUFDUVSFHVJEFIUNM״׶
  25. 䭷ꆙ (VJEJOHQSJODJQMFT ˖ "DUJWJUZծ4FSWJDFזוחכر٦ة׾⥂䭯׃זְ ˖ ٌآُ٦ٕך顑⹡׾ⴓꨄ׃״ֲ ˖ ٌآُ٦ٕ꟦דװ׶《׶ׅ׷㜥さכⰻ鿇㹋鄲׾ⰕꟚ׃זְ ˖ ٌآُ٦ٕ꟦דװ׶《׶ׅ׷㜥さכذأزָדֹ׷״ֲחׅ׷

    ˖ ن؎ٓ٦فٖ٦زז؝٦س׾⡦䏝׮剅ְג儗꟦׾嶊顤׃זְ
 "SDIJUFDUVSF$PNQPOFOUTװ䱿㤺הז׏גְ׷ٓ؎ـٓٔ׾ⵃ欽ׅ׷ ˖ ؔؿٓ؎ٝד׮⹛⡲ׅ׷״ֲח倜׃ְꟼ鸬ָ֮׷ر٦ة׾⥂㶷ׅ׷ֿה ˖ ずׄر٦ةا٦أַ׵邌爙׾遤ֲ״ֲחׅ׷
 ♧אך-JWF%BUB׾醱侧ךהֿ׹ד鋅׋׶ׅ׷ IUUQTEFWFMPQFSBOESPJEDPNUPQJDMJCSBSJFTBSDIJUFDUVSFHVJEFIUNM״׶
  26. public class SearchFragment extends LifecycleFragment implements Injectable { @Inject ViewModelProvider.Factory

    viewModelFactory; private SearchViewModel searchViewModel; ... @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel.class); ... private void doSearch(View v) { String query = binding.get().input.getText().toString(); ... // ͜͜ͰViewModel΁ͷݺͼग़͠ʂʂ searchViewModel.setQuery(query); } 'SBHNFOU7JFX.PEFM
  27. public class SearchFragment extends LifecycleFragment implements Injectable { @Inject ViewModelProvider.Factory

    viewModelFactory; private SearchViewModel searchViewModel; ... @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel.class); ... private void doSearch(View v) { String query = binding.get().input.getText().toString(); ... // ͜͜ͰViewModel΁ͷݺͼग़͠ʂʂ searchViewModel.setQuery(query); } 'SBHNFOU7JFX.PEFM 7JFX.PEFM1SPWJEFSTח״׶
 TFBSDI7JFX.PEFM׾⡲䧭ׅ׷
  28. public class SearchFragment extends LifecycleFragment implements Injectable { @Inject ViewModelProvider.Factory

    viewModelFactory; private SearchViewModel searchViewModel; ... @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel.class); ... private void doSearch(View v) { String query = binding.get().input.getText().toString(); ... // ͜͜ͰViewModel΁ͷݺͼग़͠ʂʂ searchViewModel.setQuery(query); } 'SBHNFOU7JFX.PEFM 杝荈ך7JFX.PEFM1SPWJEFS'BDUPSZד7JFX.PEFM׾⡲׷ֿהד 7JFX.PEFMךٌحؙ׾⡲׷ֿהָדֹծذأز〳腉ח
  29. public class SearchFragment extends LifecycleFragment implements Injectable { @Inject ViewModelProvider.Factory

    viewModelFactory; private SearchViewModel searchViewModel; ... @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel.class); ... private void doSearch(View v) { String query = binding.get().input.getText().toString(); ... // ͜͜ͰViewModel΁ͷݺͼग़͠ʂʂ searchViewModel.setQuery(query); } 'SBHNFOU7JFX.PEFM &EJU5FYUך؎كٝز״׶ EP4FBSDIָㄎן⳿ׁ׸׷
  30. public class SearchFragment extends LifecycleFragment implements Injectable { @Inject ViewModelProvider.Factory

    viewModelFactory; private SearchViewModel searchViewModel; ... @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); searchViewModel = ViewModelProviders.of(this, viewModelFactory).get(SearchViewModel.class); ... private void doSearch(View v) { String query = binding.get().input.getText().toString(); ... // ͜͜ͰViewModel΁ͷݺͼग़͠ʂʂ searchViewModel.setQuery(query); } 'SBHNFOU7JFX.PEFM 7JFX.PEFM׾ㄎן⳿ׅ
  31. public class SearchViewModel extends ViewModel { private final LiveData<Resource<List<Repo>>> results;

    private final MutableLiveData<String> query = new MutableLiveData<>(); ... public void setQuery(@NonNull String originalInput) { String input = originalInput.toLowerCase(Locale.getDefault()).trim(); ... query.setValue(input); } ... @Inject SearchViewModel(RepoRepository repoRepository) { ... results = Transformations.switchMap(query, search -> { if (search == null || search.trim().length() == 0) { return AbsentLiveData.create(); } else { return repoRepository.search(search); } }); } ... 7JFX.PEFM3FQPTJUPSZ
  32. public class SearchViewModel extends ViewModel { private final LiveData<Resource<List<Repo>>> results;

    private final MutableLiveData<String> query = new MutableLiveData<>(); ... public void setQuery(@NonNull String originalInput) { String input = originalInput.toLowerCase(Locale.getDefault()).trim(); ... query.setValue(input); } ... @Inject SearchViewModel(RepoRepository repoRepository) { ... results = Transformations.switchMap(query, search -> { if (search == null || search.trim().length() == 0) { return AbsentLiveData.create(); } else { return repoRepository.search(search); } }); } ... 7JFX.PEFM3FQPTJUPSZ 7JFX.PEFMך⚥ד-JWF%BUB׾⥂䭯׃גְ׷
  33. public class SearchViewModel extends ViewModel { private final LiveData<Resource<List<Repo>>> results;

    private final MutableLiveData<String> query = new MutableLiveData<>(); ... public void setQuery(@NonNull String originalInput) { String input = originalInput.toLowerCase(Locale.getDefault()).trim(); ... query.setValue(input); } ... @Inject SearchViewModel(RepoRepository repoRepository) { ... results = Transformations.switchMap(query, search -> { if (search == null || search.trim().length() == 0) { return AbsentLiveData.create(); } else { return repoRepository.search(search); } }); } ... 7JFX.PEFM3FQPTJUPSZ ת׆ծ-JWF%BUBؙٓأך؎ٝأةٝأךRVFSZח㼎׃ג TFU7BMVF
  34. public class SearchViewModel extends ViewModel { private final LiveData<Resource<List<Repo>>> results;

    private final MutableLiveData<String> query = new MutableLiveData<>(); ... public void setQuery(@NonNull String originalInput) { ... SearchViewModel(RepoRepository repoRepository) { ... results = Transformations.switchMap(query, search -> { if (search == null || search.trim().length() == 0) { return AbsentLiveData.create(); } else { return repoRepository.search(search); } }); } ... 7JFX.PEFM3FQPTJUPSZ 5SBOTGPSNBUJPOTTXJUDI.BQח״׶ RVFSZָ㢌刿ׁ׸׋׵؝٦ٕغحָؙ㹋遤ׁ׸׷
  35. public class SearchViewModel extends ViewModel { private final LiveData<Resource<List<Repo>>> results;

    private final MutableLiveData<String> query = new MutableLiveData<>(); ... public void setQuery(@NonNull String originalInput) { ... SearchViewModel(RepoRepository repoRepository) { ... results = Transformations.switchMap(query, search -> { if (search == null || search.trim().length() == 0) { return AbsentLiveData.create(); } else { return repoRepository.search(search); } }); } ... 7JFX.PEFM3FQPTJUPSZ SFQP3FQPTJUPSZַ׵嗚稊穠卓ך-JWF%BUB׾《䖤׃ג ًٝغ㢌侧חⰅ׸׷
  36. 3FQPTJUPSZ .PEFM 3FNPUF%BUB4PVSDF @Singleton public class RepoRepository { ... public

    LiveData<Resource<List<Repo>>> search(String query) { return new NetworkBoundResource<List<Repo>, RepoSearchResponse>(appExecutors) { @Override protected void saveCallResult(@NonNull RepoSearchResponse item) { ... } @NonNull @Override protected LiveData<List<Repo>> loadFromDb() { ... } @Override protected boolean shouldFetch(@Nullable List<Repo> data) { ... } @NonNull @Override protected LiveData<ApiResponse<RepoSearchResponse>> createCall() { ... } @Override protected RepoSearchResponse processResponse(ApiResponse<RepoSearchResponse> response) { ... } }.asLiveData(); }
  37. 3FQPTJUPSZ .PEFM 3FNPUF%BUB4PVSDF @Singleton public class RepoRepository { ... public

    LiveData<Resource<List<Repo>>> search(String query) { return new NetworkBoundResource<List<Repo>, RepoSearchResponse>(appExecutors) { @Override protected void saveCallResult(@NonNull RepoSearchResponse item) { ... } @NonNull @Override protected LiveData<List<Repo>> loadFromDb() { ... } @Override protected boolean shouldFetch(@Nullable List<Repo> data) { ... } @NonNull @Override protected LiveData<ApiResponse<RepoSearchResponse>> createCall() { ... } @Override protected RepoSearchResponse processResponse(ApiResponse<RepoSearchResponse> response) { ... } }.asLiveData(); } /FUXPSL#PVOE3FTPVSDF 䖓鶢 ׾ⵃ欽׃ծ ְֻאַך؝٦ٕغحؙ׾㹋鄲׃ծ-JWF%BUBה׃ג鵤ׅ
  38. 3FQPTJUPSZ .PEFM @Singleton public class RepoRepository { ... public LiveData<Resource<List<Repo>>>

    search(String query) { return new NetworkBoundResource<List<Repo>, RepoSearchResponse>(appExecutors) { ... @NonNull @Override protected LiveData<List<Repo>> loadFromDb() { return Transformations.switchMap(repoDao.search(query), searchData -> { if (searchData == null) { return AbsentLiveData.create(); } else { return repoDao.loadOrdered(searchData.repoIds); } }); } @NonNull @Override protected LiveData<ApiResponse<RepoSearchResponse>> createCall() { return githubService.searchRepos(query); } @Override /FUXPSL#PVOE3FTPVSDF 䖓鶢 ך ؝٦ٕغحؙⰻדSFQP%BPַ׵ر٦ة׾《䖤ׅ׷ 3FQP%BPؙٓأכ3PPN׾⢪׏גְ׷
  39. 3FQPTJUPSZ 3FNPUF%BUB4PVSDF @Singleton public class RepoRepository { ... public LiveData<Resource<List<Repo>>>

    search(String query) { return new NetworkBoundResource<List<Repo>, RepoSearchResponse>(appExecutors) { ... @NonNull @Override protected LiveData<ApiResponse<RepoSearchResponse>> createCall() { return githubService.searchRepos(query); } @Override protected RepoSearchResponse processResponse(ApiResponse<RepoSearchResponse> response { ... }.asLiveData(); } /FUXPSL#PVOE3FTPVSDF 䖓鶢 ך ؝٦ٕغحؙⰻד 3FUSPUך؟٦ؽأؙٓأַ׵《䖤ׅ׷
  40. 3FQPTJUPSZ .PEFM @Singleton public class RepoRepository { ... public LiveData<Resource<List<Repo>>>

    search(String query) { return new NetworkBoundResource<List<Repo>, RepoSearchResponse>(appExecutors) { ... ... }.asLiveData(); } 穠卓כ-JWF%BUBה׃ג鵤ׅ
  41. 3FQPTJUPSZ .PEFM 3FNPUF%BUB4PVSDF public class SearchFragment extends LifecycleFragment implements Injectable

    { ... searchViewModel.getResults().observe(this, result -> { binding.get().setSearchResource(result); binding.get().setResultCount((result == null || result.data == null) ? 0 : result.data.size()); adapter.get().replace(result == null ? null : result.data); binding.get().executePendingBindings(); }); 7JFX.PEFMך-JWF%BUB׾湊鋔ׅ׷ֿהדծ 7JFXח⿾僥ׅ׷