後に:エルpokedexエヌアンドロイドyきれいな建築
ねえ、Ma chamacos!イェー・デ・デ・リグス・デ・デット・ド・ヌドロス・コンM .エエスタOcasiは、n nキレロConarles sobreウンpoquito mは、デdesarrolloアンドロイドです.コモUstedes Sabrは、Nは、UNOデロスEjercicios que como ingenierosデソフトウェアnosotros hacemos - para pulir nuestras tソフトウェアcicas en el desarrolloデソフトウェアes el desarrolloデルポピュラーpokedex、エルcual es la gu de de todo maestro pok es mon mon pr cicamente su mano derecha.
コモ・ヤ・ロー・メッシオンの作品『エヌ・ラ・グー』について
プエス・ビエン,デモン・デ・エスト・デラローロ・エ・ケルシュリン100 % , se Estuvieron Applzando Pr . ccicas usadas hoy en d ' le a en el desarrollo m . vle la como la実装について
<翻訳>パラオ,ユモトス・コウンパラドール・ラ・インサイチィー・デ・デ・ディノエンシアスとフイスマ・アルマンド・ラ・パルト・デ・データ・エヌM .エヌラParteデLlamadasは、API API Tambiを使用します.
LuegoパラEl Backend、SE実装pokeapi comoバックエンド、mismoque que ha haのConfertiteエヌdel desarrolloエヌproe eceecto en diferentes lenguajes、sobre todo enn los que ususos en frontend(js,dart,typescript)y Apps m del viles(swift,kotlin,java)
IninasとしてのFinalmente paraラスLibrer und , Ese Thepo Theo comoに関する非現実的なものに対する利用可能性滑空 レトロフィット GSON(EXTESI DEN N DEレトロフィット)
クリーン建築ESは、マルコデTrabajo Propuesto PorロバートC .マーティンcomo formaデ構造家ニュエストロC通dioエヌcapas、mismas que solamente se pueden comunicarにラス・エストええとラスラディオスを集中させます.
クリーン建築のEl Eququema
yラスcapas、tomando en cuentaアンドロイド息子ラスsiguientes: UI:La InterfazデUsuario(エル断片).ペルーいいえQueereデカールque vayasメートルトダラl lgadas datos enエルフラグメント(mala praxis)、パラエロseアメリカエルビューモデルデルミッモ、que es donde viene la siguiente capa. Presentaciは、以下を言います:息子clase que se comunican con lae cle eインターフェースは、interacciとn nuestra aplicaciを得ます.コモLo Mencionは、enエルプント前に、Aqueをはいています. ユースケースを使用して:Estas Clase se Encargan de Negocio de Timinente Parel el Mannelo de Negocio Pertinente Parel El Manejo de Nodos de Nutratra Aplicaci Regitorios O実体:AQA - es donde se albergan todas las llamadas datos internos y externos de nuestra aplicaci
Ahora Bien , Culo un Coco Pr , Culo un Caso Pr . Culo un Caso Pr . Culo un Caso Pr . Culo un Caso Pr . Reactivex(タルヴェズ私aviavite algo sobre corrutinas). inyecci disde endependencias. エルModelo MVVMは、利用可能なApplzadoエヌm m Villesです. Esta formaのレトロフィットとしてのNuestro Lamadoについて
Capa 4 :リポジトリ
Luego、Pasamosは、ロサンゼルスリポジトリのパースです.Las M ' s To Pas Obtener Los Diferentes Tipos de "Pokedex "をめぐって
キャパ3:俳優
<研究ノート>ロス・リポジトリとしてのミサ・マーラ・レーク
チャパ2:presentaci
<研究ノート>アンドロイドにおける表現と表現の仕方: Nuestro Fragmento en Cuesti - en N . Por Lo Tanto , Dicho Viewmodels Tiene que Estar Bestlecido y Asignado dentro del FragmentoアルマノエルViewmodel como sigue :
CACA 1 : UI
Finalmente , El Carcarado de invocar Todo este Caminito ser Ele Fragment ( Peues usar活動, Pero gastar - en s s s memory )
<研究ノート>トド・オン・アクティ-ト-
Hasta ahorita Ando Viendo el Trabajar Lo Siguiente ya que que tiene una versi des estable mejorarエルUX/UIデラアプリ.Ahorita Lo hiceは、y yシーコです. Agregar国連ニュースフィードenエルダッシュボード.あいにきの愛について en lugar de usar rxkotlin,poder cambiar a corrutinas para la parte as la ncrona y tener una partiva de trabajar las lllamadas de este tipo .AunqueラVerdad、大豆Mは、ファンデReactivex queラスcorrutinas、Pero宇野Nunca Sabe Cuによって、NDO Necesitarを得ますTrabajarコンEllas. リバイサルque no hayaメモリリークエヌラアプリ. ci/cd comes es costumbreは、彼de comentar queなし大豆のmemeor desarrolladorデアンドロイドy queタルvez este cのdioの海のエルmejor que hayas visto y me gustar - me mejorarlo.SI Te Interesa dejar Tsの問題、ダーレスター、forkearlo o ayudarme a mejorar、puedes hacerlo en el sigigienteリポジトリ:https://github.com/RZEROSTERN/roadtocertification_pokedex
Igualmente、SI quieren dejarのSus ComentItalia、Pueden Hacerlo Bajoエステポスト.フェリスデContestarlos.
ブエノpues、エスパーque lesハヤgustadoエステ柱、Aunque Largo、栄養塩エヌCuestiones queタルvez puedan sacarデdudas a m ' s s de una persona.
ハッピーコーディング!
<研究ノート> Rays es Le POKEDEX
コモ・ヤ・ロー・メッシオンの作品『エヌ・ラ・グー』について
<武井>
プエス・ビエン,デモン・デ・エスト・デラローロ・エ・ケルシュリン100 % , se Estuvieron Applzando Pr . ccicas usadas hoy en d ' le a en el desarrollo m . vle la como la実装について
<翻訳>パラオ,ユモトス・コウンパラドール・ラ・インサイチィー・デ・デ・ディノエンシアスとフイスマ・アルマンド・ラ・パルト・デ・データ・エヌM .エヌラParteデLlamadasは、API API Tambiを使用します.
LuegoパラEl Backend、SE実装pokeapi comoバックエンド、mismoque que ha haのConfertiteエヌdel desarrolloエヌproe eceecto en diferentes lenguajes、sobre todo enn los que ususos en frontend(js,dart,typescript)y Apps m del viles(swift,kotlin,java)
IninasとしてのFinalmente paraラスLibrer und , Ese Thepo Theo comoに関する非現実的なものに対する利用可能性
ソープクリーン建築
クリーン建築ESは、マルコデTrabajo Propuesto PorロバートC .マーティンcomo formaデ構造家ニュエストロC通dioエヌcapas、mismas que solamente se pueden comunicarにラス・エストええとラスラディオスを集中させます.
クリーン建築のEl Eququema
yラスcapas、tomando en cuentaアンドロイド息子ラスsiguientes:
カコPR
Ahora Bien , Culo un Coco Pr , Culo un Caso Pr . Culo un Caso Pr . Culo un Caso Pr . Culo un Caso Pr .
Capa 4 :リポジトリ
interface RestApi {
@GET("region")
fun getRegions(): Observable<RegionResult>
@GET("region/{region}")
fun getDetailedRegion(@Path("region") region: String): Observable<RegionDetailedResult>
@GET("pokedex/{pokedex}")
fun getPokedex(@Path("pokedex") pokedex: String): Observable<PokedexResult>
@GET("pokemon/{pokemon}")
fun getPokemonByName(@Path("pokemon") pokemon: String): Observable<PokemonResult>
@GET("pokemon-species/{pokemon}")
fun getPokemonSpeciesByName(@Path("pokemon") pokemon: String): Observable<PokemonSpeciesResult>
}
カダUnoデロスmは、Dos HaがそうであるTheDos Deshados en Dicha Interfaz Serであります.Posteriororte , se Reiziza la Manufaciti in Dicha Interfaz por medio de una clase :class RestApiImp {
companion object{
var retrofit: Retrofit? = null
val REQUEST_TIMEOUT: Long = 30
var okHttpClient: OkHttpClient? = null
fun getClient(): Retrofit {
if(okHttpClient == null)
initOkHttpClient()
if(retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(Constant.MAIN_URL)
.client(okHttpClient!!)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit!!
}
private fun initOkHttpClient() {
var httpClient: OkHttpClient.Builder = OkHttpClient().newBuilder()
.connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
var interceptor: HttpLoggingInterceptor = HttpLoggingInterceptor()
interceptor.level = HttpLoggingInterceptor.Level.BODY
httpClient.addInterceptor(interceptor)
httpClient.addInterceptor { chain ->
var original = chain.request()
val newRequest = chain.request().newBuilder()
.addHeader("Accept", "application/json")
.build()
chain.proceed(newRequest)
}
okHttpClient = httpClient.build()
}
}
}
コモpueden ver , la clase cuenta con un "コンパニオンオブジェクト",エルcual es el s des mil en kotlin de宣言ar na cle est en tica een dicho objeto , tenemos el m ee todo getclient , mismo que se encargar und de realizar la implementation to i n n de retrofitLa Extensiは、パラggson y国連迎撃器パラinyectar cabeceras antesデllamar al要請(es aquoのdonde podrはエーモスのinyectarトークン、sin禁輸のno necesitamos en esta ocasiのn)を要求します.Luego、Pasamosは、ロサンゼルスリポジトリのパースです.Las M ' s To Pas Obtener Los Diferentes Tipos de "Pokedex "をめぐって
interface PokedexRepository {
fun getPokedex(pokedex: String): Observable<PokedexResult>
}
<研究ノート>人間の倫理観class PokedexRepositoryImp: PokedexRepository {
private var apiRequest: RestApi = RestApiImp.getClient().create(RestApi::class.java)
override fun getPokedex(pokedex: String): Observable<PokedexResult> {
return apiRequest.getPokedex(pokedex)
}
}
en esta interfaz y clase , podemos nosotros ver que que invocaremos como talレトロなhacia un endpoint de los definados en restapiKT pero como parte de laきれいな建築、キーンse encargarは、デ・エロSerとロスInteractorの上で言います.キャパ3:俳優
<研究ノート>ロス・リポジトリとしてのミサ・マーラ・レーク
interface PokedexInteractor {
fun getPokedex(pokedex: String): Observable<PokedexResult>
}
Y La Clase que実装者:class PokedexInteractorImp(private val pokedexRepositoryImp: PokedexRepositoryImp,
private val pokemonRepositoryImp: PokemonRepositoryImp): PokedexInteractor {
val logger: Logger = LoggerFactory.getLogger(PokedexInteractorImp::class.java.simpleName)
override fun getPokedex(pokedex: String): Observable<PokedexResult> {
return pokedexRepositoryImp.getPokedex(pokedex)
.doOnNext { response ->
run {
for(item: Pokemon in response.pokemonEntries) {
var pokemonID: String = item.pokemonSpecies.url
.replace(Constant.MAIN_URL, "")
.replace("pokemon-species", "")
.replace("/", "")
item.pokemonImage = Constant.POKEMON_IMAGE_URL + pokemonID + ".png"
pokemonRepositoryImp.getPokemon(item.pokemonSpecies.name)
.subscribeOn(Schedulers.io())
.subscribe({response2 -> item.pokemonDetails = response2}, {t -> logger.error(t.message)})
}
}
}
.doOnComplete { logger.debug("Service complete") }
.onErrorReturn { error ->
logger.error(error.message)
null
}
}
}
y como podemos天文台en pokedexinteractorimpKT , Ecarcarde de Armar L . Gias Complejas en Genas Freejas de Nogcio de la AplicaciEPAにおけるEPAの役割についてチャパ2:presentaci
<研究ノート>アンドロイドにおける表現と表現の仕方: Nuestro Fragmento en Cuesti - en N . Por Lo Tanto , Dicho Viewmodels Tiene que Estar Bestlecido y Asignado dentro del FragmentoアルマノエルViewmodel como sigue :
class PokedexInfoViewModel : ViewModel() {
var compositeDisposable = CompositeDisposable()
lateinit var dependencies: ApiDependencies // I'll talk about this later
var pokemon: MutableLiveData<MutableList<Pokemon>> = MutableLiveData()
fun getPokedex(pokedex: String) {
compositeDisposable.add(dependencies.getPokedex(pokedex)
.subscribeOn(Schedulers.io())
.subscribe(
{res -> pokemon.postValue(res.pokemonEntries) },
{t: Throwable -> Log.e(ContentValues.TAG, t.message!!) }
)
)
}
}
コンEsto、nosotros vamos armando la capa 2 y dejamos todo dispuesto que la capa 1 no nnicamente quede a la escucha de la informaci n n que llegue al momento de request ery y seguir el flujo de ida y velta conforme a la clean architectureCACA 1 : UI
Finalmente , El Carcarado de invocar Todo este Caminito ser Ele Fragment ( Peues usar活動, Pero gastar - en s s s memory )
class PokedexInfoFragment : Fragment() {
private lateinit var viewModel: PokedexInfoViewModel
private lateinit var toolbar: Toolbar
private val dependencies: ApiDependencies by inject()
lateinit var items: MutableList<Pokemon>
lateinit var recyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.pokedex_info_fragment, container, false)
val activity = requireActivity() as AppCompatActivity
toolbar = view.findViewById(R.id.tb_pokedex_info)
activity.setSupportActionBar(toolbar)
activity.supportActionBar!!.title = arguments?.getString("pokedex")!!
.capitalize(Locale.getDefault()).replace("-", " ") + "'s Pokedex"
activity.supportActionBar!!.setDisplayHomeAsUpEnabled(true)
return view
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
var bundle = bundleOf("region" to arguments?.getString("region"))
Navigation.findNavController(requireView()).navigate(R.id.action_pokedexInfoFragment_to_regionFragment, bundle)
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(PokedexInfoViewModel::class.java)
viewModel.dependencies = dependencies
viewModel.pokemon.observe(viewLifecycleOwner, Observer {
items = it
initRecyclerView()
})
viewModel.getPokedex(arguments?.getString("pokedex")!!)
}
private fun initRecyclerView() {
val listener = View.OnClickListener() {
val bundle = bundleOf("pokemon" to it
.findViewById<TextView>(R.id.txt_pokemon_name)
.text.toString().toLowerCase(Locale.getDefault()),
"pokedex" to arguments?.getString("pokedex"))
Navigation.findNavController(requireView())
.navigate(R.id.action_pokedexInfoFragment_to_pokemonFragment, bundle)
}
recyclerView = requireView().findViewById(R.id.rv_pokedex_info)
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = GridLayoutManager(requireContext(), 3)
recyclerView.adapter = PokedexInfoAdapter(items, listener)
}
override fun onDetach() {
viewModel.compositeDisposable.dispose()
items.clear()
super.onDetach()
}
override fun onDestroy() {
viewModel.compositeDisposable.dispose()
items.clear()
super.onDestroy()
}
}
Varios Mは、1つの息子息子のParte de la apiデアンドロイド、罪禁輸息子デ不可欠な輸入品(ondetach y ondestroy)パラqueエルエルModModel no se Queen en Memania al MomentoデCambiarデ断片、SalirデLaアプリo Alg Ant n n Punto enエルque Cel Lico de vidaデラapp se vea terminado o interrumpidoをオーバーライドします.<研究ノート>トド・オン・アクティ-ト-
viewModel.pokemon.observe(viewLifecycleOwner, Observer {
items = it
initRecyclerView()
})
viewModel.getPokedex(arguments?.getString("pokedex")!!)
アル・モメント・デ・アネラル・エル・ビューモデルの研究(第1部)シグイティエンパロス
Hasta ahorita Ando Viendo el Trabajar Lo Siguiente ya que que tiene una versi des estable
Igualmente、SI quieren dejarのSus ComentItalia、Pueden Hacerlo Bajoエステポスト.フェリスデContestarlos.
ブエノpues、エスパーque lesハヤgustadoエステ柱、Aunque Largo、栄養塩エヌCuestiones queタルvez puedan sacarデdudas a m ' s s de una persona.
ハッピーコーディング!
Reference
この問題について(後に:エルpokedexエヌアンドロイドyきれいな建築), 我々は、より多くの情報をここで見つけました https://dev.to/rzerostern/post-mortem-el-pokedex-en-android-y-clean-architecture-2lc9テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol