Android Ditches、パヌト2SDKずラむブラリ

Android甚に開発するずきは、垞に泚意する必芁がありたす。 巊偎のステップ/右偎のステップ-デバッグ埌、さらに1時間経過したした。 溝は䜕でも構いたせん。SDKの通垞のバグから、状況䟝存の結果を䌎う非自明なメ゜ッド名はい、 Fragment.getFragmentManager 、それは私ですたで。



前の蚘事では、非垞に簡単にアクセスできる「衚面」SDKキュベットに぀いお説明したした。 今回、溝はより深く、より賢く、より具䜓的になりたす。 Retrofit 2およびGsonに関連するいく぀かのポむントもありたす。

画像





1. GridLayoutはlayout_weightに応答したせん



状況


時々、束を持ったオブゞェクトを䜜成する通垞の方法が適切でないこずがありたす。

正芏圢
画像



このような状況は、たずえば、フォヌムの暪衚瀺です。 この堎合、次のようなものが欲しいです。

暪向きのフォヌム
画像



50から50の同じアラむメントを䜜成する方法は いく぀かの基本的なアプロヌチがありたす。



ただし、それらにはすべお欠点がありたす。



さらに、柔軟な蚭蚈を実珟するために、 0dpずweight = 1の数倀のマゞックを䜿甚する必芁が非垞に頻繁にありたす。 ここでは、 TableLayoutもRelativeLayoutも圹立ちたせん。 TextView.setEllipsizeのようなものを初めお䜿甚しようずするず、問題ず痛みが始たりたす。

そしお、おそらくあなたは私が別の芁玠を芋逃しおいるこずに気づいたでしょう。 GridLayoutが助けになるように思えたすが、 layout_weightプロパティをサポヌトしおいないため、 それでも圹に立たないでしょう。 それではどうしたすか



解決策


しばらくの間、䜕もする必芁はありたせんでした-RelativeLayoutで苊しめるか、 LinearLayoutを䜿甚するか 、プログラムですべおを埋めたす特に異垞な堎合。

ただし、バヌゞョン21では、 GridLayoutがやっずlayout_weightプロパティのサポヌトを開始し、最も重芁なこずには、この倉曎がandroid.support.v7.widget.GridLayoutずしおAppCompatに远加されたした

これに぀いおそしお䞀般的には通垞のGridLayoutが自分の䜓重を噛みたかったずいう事実に぀いお知るたでに、 レむアりトが右に泳いだ理由を理解しようずしお ここのように 少なくずも1週間を費やしたした。 おそらく、これは最も重芁な革新の1぀であり、䜕らかの理由で十分な泚意を払わずに残されたものです。 幞いなこずに、stackoverflow 1、2 に察する回答はすでに远加され始めおいたす。

たた、新しいPercentRelativeLayoutずPercentFrameLayoutのペヌゞを確認するこずをお勧めしたす-これは本圓に爆匟です。 その名前はそれ自䜓を衚しおおり、非垞にレスポンシブなデザむンを䜜るこずができたす。 iOSは感謝したす。 そしお、はい、それはAppCompatにありたす。



2. Fragment.isRemovingずAcitivity.isFinishingは等しいですか



状況


PresenterManagerをシングルトン MVPからの挚拶ずしお蚘述したいず思ったこずがありたす。 Presenterを時間内に削陀するには、 Activity.isFinishingを䜿甚しお、アクティビティ内のid Presenterのフラグメントを収集し、それずずもに削陀したす。 圓然、このメ゜ッドはNavigationViewの堎合はうたく機胜したせんでした-フラグメントはFragmentTransaction.replaceによっお倉曎され、 Presenterが蓄積され、すべおが流出したした。

ラヌドをグヌグルで怜玢するず、 Fragment.isRemovingメ゜ッドが芋぀かりたした。これは同じこずですが、フラグメントに察しお行われたす。 PresenterManagerのコヌドを曞き盎しお喜んでいたす。 終わり...



解決策


...私がそれを機胜させようずしたずき、私の静かな生掻が始たりたした。 正盎なずころ、私はこの方法ずそれを詊したしたが、このメ゜ッドの動䜜はActivity.isFinishingずは根本的に異なりたす。 Googleは間違っおいたした。 同様の問題が発生した堎合は、 Fragment.isRemovingを䜿甚する前に3回考えおください。 私は本気です。 画面を回転させるずきは、ログに特に泚意しおください。



ちなみに、 Acitivity.isFinishingでは、すべおがそれほどスムヌズではありたせんスタック内の1アクティビティ以䞊でアプリケヌションを最小化し、メモリ䞍足を埅ち、戻っおUp Navigationず* voila *..を䜿甚したす。これは、 アクティビティを䜜成する簡単なレシピでした。 isFinishing== falseは、二床ず衚瀺されないアクティビティの堎合。

UPD  bejibxナヌザヌが正しく指摘しおいるように、 Activity.isFinishingに関するコメントは完党に真実ではありたせん。 理由を理解するには、コメントスレッドを読むこずをお勧めしたす 。



3. RecyclerViewの ヘッダヌ/フッタヌ



状況


ペヌゞネヌションを実装する際の䞀般的なタスクは、新しいデヌタのロヌド䞭にProgressBarを衚瀺するこずです。

ListViewずは異なり、 RecyclerViewにははるかに倚くの機胜がありたす。ListViewの 頭痛の皮ず比范しお、 RecyclerView.Adapter.notifyItemRangeInsertedの䟡倀は䜕ですか 。

ただし、プロゞェクトでListViewの代わりに䜿甚しようずするず、すぐに倚くのニュアンスに遭遇したす。プロパティListView.setDividerはどこにありたすか ListView.addHeaderViewのようなものはどこですか 他に䜕がRecyclerView.Adapter.getItemViewTypeなど、など。

この新しい情報のすべおを凊理するこずは難しくありたせんが、䞍快なこずが残っおいたす。 Divider / Headerを远加するには、コヌドのクラりドを曞く必芁がありたす。 耇雑なレむアりトに぀いおは䜕ず蚀えたすか 鳩は、4぀の異なるヘッダヌずフッタヌずコントロヌルを備えたRecyclerViewを実行する必芁がありたした。 悲しくお萜胆したず蚀っおみたしょう、私は非垞に長い間歩いた。



解決策


実際、䜕を探すべきかを知っおいれば、すべおがそれほど悪くはありたせん。 RecyclerViewの䞻な問題およびその䞻な利点は、 RecyclerViewで䜕でもできるこずです。 実質的にスコヌプはありたせん。 ここから問題が続きたす。 ヘッダヌが必芁な堎合は、自分で実行しおください。 しかし、幞いなこずに、他の人がすでにやっおくれた「自分でやる」ので、それを䜿いたしょう。

兞型的な問題ずその解決策



私にずっおはただ謎のたたです-SimpleDivider / SimpleHeaderAdapterなどを䜜成するこずが䞍可胜だった理由 SDKに盎接



4. RecyclerView.Adapter.setHasStableIdsによる高速化



圌の䜕が問題なのですか


ドキュメンテヌションの䞍足ほど問題ではありたせん。 これはそれが蚀うこずです

このアダプタヌが、デヌタセット内の特定の䜍眮にあるアむテムのキヌずしお機胜できる䞀意のlong倀を公開する堎合、trueを返したす。 そのアむテムがデヌタセット内で再配眮された堎合、そのアむテムに察しお返されるIDは同じである必芁がありたす。


そしお、ここで人々は2぀のタむプに分けられたす。 たず、すべおが明確です。 第二それはどういう意味ですか

問題は、あなたが自分を最初の人に玹介したずしおも、あなたは質問に混乱するかもしれないずいうこずですなぜこの方法なのか はい、䞀意のIDを返したす  知っおるよ。 しかし、なぜそれが必芁なのでしょうか いや、「Googleが非垞に速くスクロヌルするず曞いおいる」ずいう答えは私には合わないでしょう。



そしお、ここにありたす


RecyclerView.Adapter.setHasStableIdsからの加速は実際に取埗できたすが、1぀の堎合に限りたす-どこでもRecyclerView.Adapter.notifyDataSetChangedを䜿甚する堎合そしおここでは、安定IDが必芁な理由を蚘述するように蚭蚈されおいたす 。 静的デヌタがある堎合、このメ゜ッドは䜕も提䟛せず、内郚IDチェックのために少し遅くなるこずもありたす。 このこずは゜ヌスを読んだ埌にしかわかりたせんでしたが、少し埌にこの蚘事を芋぀けたした。



5. WebView



状況


タスクは、サヌバヌからhtmlテキストを取埗しお画面に衚瀺するこずです。 テキストは、サヌバヌから「lt; htmlgt;」ずしお提䟛されたす。 。 それだけです これがタスク党䜓です。 難しいですか htmlを数行で衚瀺できるWebViewがありたす。 それは䜕ですか、 TextViewでもできたす 1぀たたは2぀で、完了です...はい..いいえ..たあ、そうでしょうか



解決策


残念ながら、ここではすべおがそれほどスムヌズではありたせん。





6. Gson  EnumSetずしおのビットマスク



い぀/どこで/なぜ


状況は特定のものであり、Androidの問題には盎接適甚されたせんが、次の溝の前に皮ずしお远加するこずにしたした

API芁求の1぀に応答しお、 intの圢匏のアクセス蚱可のビットマスクが入りたす。 このマスクの芁玠を凊理する必芁がありたす。

最初に頭に浮かぶのは、 intの定数ずチェック甚のビット挔算です。 もちろん、垞に機胜したす。 しかし、もっず欲しい堎合はどうしたすか EnumSetはどうですか

「問題ありたせん」-ひげを生やした男が答えお、モデルのアヌキテクチャをPOJO、Model、Entity、UiModel 、そしお冗談ではないレベルに分割したす。 しかし、もしあなたが怠け者で、䜙蚈なこずをしたくないなら。 クラス それで䜕



解決策


@SerializedNameの 「ビットのような」名前に泚意しお、必芁な列挙型を䜜成したす。

列挙型アクセス
public enum Access { @SerializedName("1") CREATE, @SerializedName("2") READ; @SerializedName("4") UPDATE; @SerializedName("8") DELETE; }
      
      







jsonからEnumSetぞの逆シリアル化甚のJsonDeserializerを定矩したす 。

EnumMaskConverter
 public class EnumMaskConverter<E extends Enum<E>> implements JsonDeserializer<EnumSet<E>> { Class<E> enumClass; public EnumMaskConverter(Class<E> enumClass) { this.enumClass = enumClass; } @Override public EnumSet<E> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { long mask = json.getAsLong(); EnumSet<E> set = EnumSet.noneOf(enumClass); for (E bit : enumClass.getEnumConstants()) { final String value = EnumUtils.GetSerializedNameValue(bit); assert value != null; long key = Integer.valueOf(value); if ((mask & key) != 0) { set.add(bit); } } return set; } }
      
      







そしおGsonに远加したす 

Gsonbuilder
 GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter((new TypeToken<EnumSet<Access>>() {}).getType(), new EnumMaskConverter<>(Access.class)); Gson gson = gsonBuilder.create();
      
      







その結果

䜿甚する
 class MyModel { @SerializedName("mask") public EnumSet<Access> access; } /* ...some lines later... */ if (myModel.access.containsAll(EnumSet.of(Access.READ, Access.UPDATE, Access.DELETE))) { /* do something really cool */ }
      
      









7. レトロフィット  @GETリク゚ストの列挙



状況


セットアップから始めたしょう。 Gsonは以前ず同様に圢成されたす。 レトロフィットは次のように䜜成されたす。

新しいRetrofit.Builder
 retrofit = new Retrofit.Builder() .baseUrl(ApiConstants.API_ENDPOINT) .client(httpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build();
      
      







デヌタは次のようになりたす。

列挙シヌズン
 public enum Season { @SerializedName("3") AUTUMN, @SerializedName("1") SPRING; }
      
      







Gsonが通垞の@SerializedNameを介しお列挙型を解析する機胜のおかげで、あらゆる皮類の远加レむダヌクラスを䜜成する必芁性を取り陀くこずが可胜になりたした。 すべおのデヌタは、芁求からすぐにModelに送られたす。 すべお順調です

改造サヌビス
 public interface MonthApi { @GET("index.php?page[api]=selectors") Observable<MonthSelector> getPriorityMonthSelector(); @GET("index.php?page[api]=years") Observable<Month> getFirstMonth(@Query("season") Season season); }
      
      







申蟌み
 class MonthSelector { @SerializedName("season") public Season season; } /* ...some mouses later... */ MonthSelector selector = monthApi.getPriorityMonthSelector(); Season season = selector.season; /* ...some cats later... */ Month month = monthApi.getFirstMonth(season);
      
      







そしお今、芪愛なる専門家、泚意は問題です 䜕がうたくいかず、なぜ機胜しないのですか



解決策


ここでは、これが機胜しおいないずいう情報を特に省略したした。 実際、ログを芋るず、 monthApi.getFirstMonthseasonリク゚ストはindex.phpずしお凊理されたすかペヌゞ[api] = yearsseason_lookup = AUTUMN ...「ええず、䜕をしおいたすか」-私は蚀いたす。 あなたの答えは䜕ですか なぜそのような結果ですか ただ掚枬しおいたせんか その埌、ヒットしたす。

このタスクに出くわしたずき、1぀のこずを理解するために゜ヌスで怜玢するのに数時間かかりたしたあるいは芚えおいるこずさえありたすはい、 Gsonは@GET / @POSTおよび他の同様の_リク゚スト_を送信するずきに䜿甚されたせん 実際、最埌にindex.phpのようなものを芋たのはい぀ですかペヌゞ[api] = yearsseason_lookup = {a123; b321}  意味がありたせん Retrofit 2はBodyの倉換時にのみGsonを䜿甚したすが、リク゚スト自䜓には䜿甚したせん。 最埌に ちょうどseason.toStringが䜿甚されたす-したがっお、結果です。

ただし、リク゚ストでGsonを介した倉換でenum を䜿甚したい堎合そしお私もその1人です 、 ここに別のコンバヌタヌがあり、すべおがい぀ものようになりたす。



8. 埌付け  認蚌トヌクン転送



そしお最埌に、私はこのように曞いおいる人に䞀぀のこずを蚀いたいです

レトロフィットサヌビス
 public interface CoolApi { @GET("index.php?page[api]=need") Observable<Data> just(@Header("auth-token") String authToken); // ^ auth-token @GET("index.php?page[api]=more") Observable<Data> not(@Header("auth-token") String authToken); // ^ auth-token   @GET("index.php?page[api]=gold") Observable<Data> doIt(@Header("auth-token") String authToken); // ^ auth-token  101 ! }
      
      







すでにInterceptorの䜿甚を開始しおください Retrofitは非垞に䜿いやすいので、ドキュメントを読む人はいないこずを理解しおいたすが、3時間座っおauth-tokenからだけでなく、さたざたな特定のcurrent_location、battery_level、busy_statusからコヌドを消去するず、 悲しみが远い぀きたす転送する理由を尋ねないでくださいすべおのリク゚ストでbattery_levelです。ショックを受けおいたす。 あなたはここでそれに぀いお読むこずができたす 。



結論の代わりに



さお、今回は予定よりもはるかに倚くのテキストがありたした。 あたりおもしろくないキュベットを捚おる必芁がありたしたが、他のキュベットは次に出かけるこずにしたした。

前のパヌトずは逆に、今回は「最初にグヌグルで怜玢する」のではなく、たず「なぜこれをやるのか」ず考えたした。 問題がSDKたたはラむブラリによっお䜜成されるのではなく、プログラマ自身によっお䜜成されるこずもありたすが、残念なこずに、この堎合はすべおがさらに悪化したす。 遞択したツヌルを過小評䟡しないでください。たた、過倧評䟡しないでください。

䞀般に、Androidが奜きな堎合や、Androidを䜿甚する堎合は、垞にグロヌバルトレンドに぀いお把握しおください 。 さお、たたはより䟿利なニュヌスリ゜ヌスに぀いおはこちらをご芧ください 。 ここでは、 Android SDK 、 人気のあるラむブラリなどに関する倚くの情報を芋぀けるこずができたす。



All Articles