Androidインタビューの質問の一般的なソースコード(2つ):OkHttp、Retrofit、カスタムソースコード分析の概要を表示

面接に対して責任ある態度で、入門シリーズではなく、面接プロセスのすべての知識ポイントを記録します。理解できない場合は、自分で学習してください。

現在、以下の側面が要約されています。

  • Androidの最適化
  • HashMap分析
  • ハンドラーのソースコード分析
  • OkHttp分析
  • レトロフィット分析
  • カスタムビュー

スペースの都合上、2つのパートに分けて共有します。前回の記事では最初の3つの側面について説明しましたが、今日は残りの3つのパートについて説明し、以下は引き続き更新されます。

OkHttp分析

OkhttpはSocketのパッケージです。デフォルトでは、新しいOkHttpClient()を使用して初期クライアントオブジェクトを作成する、Request、Response、およびCallの3つの主要なクラスがあります。

タイムアウト、インターセプターなどのネットワーク要求のパラメーターを初期化する必要がある場合は、Builderを作成し、builder.build()を使用して初期クライアントオブジェクトを作成できます。

new Request.Builder()。url()。builder()を使用して、最初のrequstオブジェクトを作成します。

client.newCall()を介して呼び出しオブジェクトを作成し、call.excute()を同期的に使用し、call、enqueue()を非同期的に使用します。ここで、Callはインターフェイスであり、特定の実装はRealCall実装クラスにあります。

Okhttpの効率は、okhttpのDispatcherクラスに反映されます。これは、okhttpによって内部的に維持されるスレッドプールであり、最初に最大接続数と最大ホスト訪問数を定義します。3つのキューと1つのスレッドプールを維持する

readyAsyncCalls

実行する要求を格納する保留中のアクセス要求キュー。

runningAsyncCalls

キャンセルされたが完了していないリクエストを含む、進行中の実行を格納する非同期リクエストキュー。

runningSyncCalls

同期要求キュー。キャンセルされたがまだ終了していない要求を含む、実行中の要求。

ExecutorService

スレッドプール、最小0、最大最大スレッドプール

call.excute()を実行すると、realcallクラスのexcuteメソッドが呼び出されます。これは同期メソッドです。メソッドの最初の行がロックされ、実行されたフラグが判断されます。trueの場合、例外がスローされます。リクエストを確認する1回だけ実行されます。falseの場合、下方実行を続行します。client.dispatcher.excute()を呼び出してディスパッチャークラス入り、現在の要求をrunningSyncCallsキューに追加します。完成したメソッドは実行の最後に呼び出されます

非同期操作の場合、RealCall.AsyncCallオブジェクトが作成され、NamedRunnableインターフェイスAsyncCallによって継承されNamedRunnableは実行可能です。Dispatcherのenqueue()メソッドで、まずスレッドプール内のスレッドデータとホストのアクセス量を判断し、到達しない場合はrunningAsyncCallsに追加して実行します。それ以外の場合は、readyAsyncCallsキューに追加されます。
終了したメソッド、非同期操作の場合は、promoteCallメソッド、イテレーターを使用して、promoteCalls()でreadyAsyncCallsをトラバースし、runningAsyncCallsに追加します。

RealConnection

実際の接続操作クラス、soketパッケージ、http1 / http2選択、sslプロトコルなど。recalconnectionはリンクです

ConnectionPool

リンクプールはhttp1 / http2接続を管理し、同じアドレスが接続を共有してリンクの再利用を実現します。

StreamAlloction

保存されたリンク情報、アドレス、HttpCodec、realconnection、connectionpoolおよびその他の情報

realCallのgetResponseWithInterceptorChain()でインターセプターチェーンを作成して開始します

Okhttpのインターセプターはデフォルトで5つのタイプに分けられます

  • RetryAndFollowUpInterceptor
    はネットワーク障害の再接続を行いますが、応答コードによると、すべての要求を再接続する必要はありません。MAX_FOLLOW_UPS = 20
    再接続の最大数インターセプトメソッドでStreamAllocationオブジェクトを作成し、chain.proceedメソッドを呼び出して、次のインターセプターを実行し、要求を処理して、応答を返します。
  • BirdgeInterceptorの
    初期化情報、gzip、キープアライブなどのリクエストヘッダーの追加、返された応答の解凍
  • CacheInterceptorに
    は、キャッシュ操作、キャッシュ間内部クラス、disklrucacheアルゴリズムなどを処理するCacheクラスがあります。
    焦点は非get要求をキャッシュすることではありません。
    ファクトリモードで取得したCacheStrategyキャッシュ戦略クラス
  • ConnectionInterceptorソースコードの読み取りに集中することをお勧めします
    は、リンクを確立し、以前に作成したStreamAllocationを使用し、httpcodec、realConnectionを初期化します。同様のgcマーククリーニングアルゴリズムが内部で使用され、不要な接続をマークします。StramAlloctionは徐々に0になります。スレッドプールが検出されてリサイクルされ、複数の正常なキープアライブリンクが確保されます。
  • CallServerInterceptor
    は、実際のネットワーク要求を開始し、返されたデータ
    httpを解析してネットワークIOストリームに書き込み、ネットワークIOストリームからクライアントに返されたデータを読み取ります。
  • ネットワークインターセプター
    アプリケーションインターセプターとネットワークインターセプターの違いビュー関連情報
    okhttpwiki

OkHttpのデザインパターン

シングルトン、ビルダー、戦略、責任の連鎖、オブザーバー

思考:
戦略と単純なファクトリの違い

関連する面接の質問:

  1. Chain of Responsibility ModelDEMO
  2. IO操作プロセス
  3. 3レベルのキャッシュプロセスについて話しましょう
  4. 構成を要求する方法は何ですか。
  5. okhttp再開可能送信の節約とは何ですか?再開可能送信プロセスを実現する方法

レトロフィット分析

関連するデザインパターン

アピアランスモード、ビルダーモード、ファクトリモード、エージェントモード、アダプターモード、ストラテジーモード、オブザーバーモード

一般化する

Retrofitは、ネットワークリクエストフレームワークのカプセル化です。基になるネットワークリクエストにデフォルトで使用されるOkhttpは、ユーザーのネットワークリクエストのパラメータ設定を簡素化するだけです。また、Rxjavaと組み合わせて、より簡潔で使いやすくすることもできます。 。

  • アプリアプリケーションは、Retrofitを介してネットワークを要求します。Retrofitは実際にRetrofitインターフェイスレイヤーを使用して要求パラメーターをカプセル化し、OkHttpは後続の要求操作を完了します。
  • サーバーがデータを返した後、OkHttpは元の結果をRetrofitに配信し、Retrofitはユーザーのニーズに応じて結果を解析します。
  • 完全なデータ変換(converterFactory)、適応(callAdapterFactory)、およびデザインパターンによるさまざまな拡張。

使用する

    @GET("/user/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);

    //call封装了整个okhttp的请求

    Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl("https://api.github.com/")
                        .addConverterFactory(GsonConverteractory.create())
                        //.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .build();
    //converterFactory
    //后续交个okhttp

Retrofitを使用するための7つのステップ

  • Retrofitの依存関係、ネットワーク権限を追加します
  • サーバーから返されたデータを受信するBeanを定義します
  • アノテーション(動的プロキシ、コア)を使用して、ネットワーク要求のインターフェイスを作成します
  • ビルダーモードは、Retrofitインスタンス、コンバーター、calladapterを作成します...
  • インターフェイスインスタンスを作成し、特定のネットワークリクエストを呼び出します
  • 同期/非同期ネットワーク要求を呼び出す
  • サーバーから返されたデータを処理します

ネットワーク通信を8ステップ改造する

  1. Retrofitインスタンスを作成する
  2. ネットワーク要求インターフェースを定義し、インターフェースのメソッドに注釈を追加します
  3. 動的プロキシを介してネットワーク要求オブジェクトを生成する
  4. ネットワークリクエストアダプタを介して、ネットワークリクエストオブジェクトをプラットフォームに適合させます
  5. ネットワークリクエストエグゼキュータを介してネットワークリクエスト(呼び出し)を送信します
  6. データパーサーを介してデータを解析する
  7. コールバックエグゼキュータを介してスレッドを切り替えます
  8. ユーザーは返された結果をメインスレッドで処理します

プロキシ

このオブジェクトへのアクセスを制御するために、他のオブジェクトのプロキシを提供します

  1. 静的

  2. 動的

    • プログラムの実行時に作成されるエージェントモード
    • 非侵襲的強化
    • jdk動的プロキシとcglib

jdk動的プロキシ

  • インターフェイスダイナミクスのみ
  • InvocationHandlerを実装する必要があります
  • 呼び出しパラメーターからパラメーターを取得する
  • invokeの戻り値がユーザーに返されます
  • InvocationHandlerはnewProxyInstanceで渡されます

総括する:

  1. ランタイム
  2. InvocationHandlerインターフェースとプロキシクラス
  3. 動的プロキシと静的プロキシの違い

ソースコード

  1. serviceMethonCache //キャッシュ、ネットワークリクエストオブジェクト
  2. ファクトリcallFactory //デフォルトOK
  3. HttpUrl baseUrl
  4. List <Converter.Factory> ConverterFactories
  5. List <CallAdapter.Factory> callAdapterFactories
  6. Executor callbackExecutor //コールバックを実行する
  7. boolean validateEagerly //インターフェースのメソッドをすぐに解析するかどうか

ビルダー

  1. プラットホーム

シングルトンは
さまざまなプラットフォームのAndroidプラットフォームでMainthreadExecutorを取得します

callAdapterFactory

calladapterを介して元のCallをカプセル化し、対応するアクチュエータを見つけます。たとえば、rxjavaCallFactoryに対応するObservable、変換形式Call <T>-> Observable <T>

ConverterFactory

データ分析コンバーターは、converterFactoryを介して応答を対応するデータ形式GsonConverterFactory、FastJsonConverterFactoryに変換します。

後付け

外部インターフェースを提供するRetrofitコアクラス。retrofit.create()を使用して、レトロフィットインスタンスと外観モードを作成します。create()メソッドでは、動的プロキシモードを使用して、要求されたインターフェイス(ServiceMethod)でメソッドをカプセル化し、OkhttpCallが初期化されます。

ServiceMethod

コア処理クラス、分析メソッド、およびアノテーションであるHttpRequestは、toRequest()メソッドで生成されます。responseConverterを作成し(応答ストリームを文字列またはエンティティに変換します)、callAdapterを作成します

OkhttpCall

okhttp3.Callへのパッケージ呼び出しです。

カスタムビュー

ビューをカスタマイズする、既存のコントロールを組み合わせる、既存のコントロールを継承する、ビューを継承する3つの方法

この記事では、Viewを継承する方法と、他の2つの自己学習にのみ焦点を当てています。

1.書き換え方法

onMeasure、onLayout、onDraw、onTouchEvent

onMeasure

複数回トリガーされる可能性があります。測定プロセス中はMeasureSpecに注意してください。SpecModeとspecSizeは
、LinearLayoutとRelativeLayoutのソースコードについて説明しています。

MeasureSpec

MeasureSpec、specMode、specSize

  1. 丁度

親レイアウトが子レイアウトのサイズがspecSizeの値によって決定されることを望んでいることを示します。システムはデフォルトでこのルールに従って子レイアウトのサイズを設定します。もちろん、開発者はそれを任意のサイズに設定することもできます。彼らの希望に応じて。

  1. せいぜい

サブレイアウトは、specSizeで指定されたサイズまでしか指定できないことを示します。開発者は、このレイアウトをできるだけ小さく設定し、specSizeを超えないようにする必要があります。デフォルトでは、システムはこのルールに従ってサブレイアウトのサイズを設定します。もちろん、開発者は希望に応じて任意のサイズに設定できます。

  1. 不特定

開発者が制限なしに、希望に応じてレイアウトを任意のサイズに設定できることを意味します。このような状況は比較的まれであり、ほとんど使用されません。

childParams / parentMode 丁度 せいぜい 不特定
dp / px 正確に(子サイズ) 正確に(子サイズ) 正確に(子サイズ)
match_parent 正確に(親サイズ) AT_MOST(親サイズ) UNSPECIFIED(0)
wrap_content AT_MOST(親サイズ) AT_MOST(親サイズ) UNSPECIFIED(0)

上記のグラフはhttps://blog.csdn.net/singwhatiwanna/article/details/38426471から抜粋したものです

onLayout

ViewGroupでは、子ビューの位置を決定するために1回だけトリガーされます

onDraw

コンテンツの描画、Canvas.drawxxx()、ペイント

onTouchEvent

クリックイベントの処理

2.カスタムビューとビューグループの違い

  1. onDraw(キャンバスキャンバス)

Viewクラスでの再描画に使用されるメソッド。このメソッドは、すべてのView、ViewGroup、およびそれらの派生クラスが持つメソッドであり、AndroidUI描画の最も重要なメソッドでもあります。開発者はこのメソッドをオーバーライドし、オーバーロードされたメソッド内のパラメーターキャンバスに基づいて独自のグラフィックスと画像効果を描画できます。

  1. onLayout()

このクラスのオーバーロードは、レイアウトが変更されたときにカスタマイズできます。これは、いくつかの特殊効果を実装するときに非常に役立ちます。ViewのOnLayoutを書き直す必要はなく、ViewGroupのonLayout()は抽象的であり、カスタムViewGroupを書き直す必要があります。

  1. dispatchDraw()

ViewGroupクラスとその派生クラスには、サブビューの描画と分散を制御するメソッドがあります。このメソッドをオーバーロードすると、サブビューの描画が変更され、複雑な視覚効果が実現する可能性があります。一般的な例については、dispatchDrawオーバーロードを参照してください。ランチャーモジュールワークスペースの。

  1. drawChild()

ViewGroupクラスとその派生クラスには、特定のビューローの特定のサブビューの描画を直接制御するメソッドがあり、このメソッドをオーバーロードして特定のサブビューを制御します。

3.メソッド実行プロセスを表示します

3つのメジャー、2つのレイアウト、1つの描画
http://blog.csdn.net/u012422440/article/details/52972825

Androidビューツリーのルートノードは、FrameLayoutのサブクラスであるDecorViewであるため、そのサブビューは2回描画されるため、onMeasure関数は最初に2回呼び出されます。

  • onResume(アクティビティ)
  • onPostResume(Activity)
  • onAttachedToWindow(View)
  • onMeasure(表示)
  • onMeasure(表示)
  • onLayout(View)
  • onSizeChanged(View)
  • onMeasure(表示)
  • onLayout(View)
  • onDraw(表示)
  • dispatchDraw()

4. invalidate()、postInvalidate()、requestLayout()

invalidate()

/**
     * Invalidate the whole view. If the view is visible,
     * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
     * the future.
     * <p>
     * This must be called from a UI thread. To call from a non-UI thread, call
     */
    public void invalidate() {
        invalidate(true);
    }

invalidateメソッドは、描画プロセスを実行し、ビューツリーを再描画します。
ビューの表示、背景、状態(フォーカス/有効化)などを変更すると、これらはすべて外観のカテゴリに属し、無効化操作が発生します。インターフェイスの表示を更新する必要があります。invalidateメソッドを直接呼び出すことができます。

注意:

View(非コンテナクラス)呼び出しinvalidateメソッドはそれ自体を再描画するだけであり、ViewGroup呼び出しはViewツリー全体を再描画します。

postInvalidate()

/**
     * <p>Cause an invalidate to happen on a subsequent cycle through the event loop.
     * Use this to invalidate the View from a non-UI thread.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     */
    public void postInvalidate() {
        postInvalidateDelayed(0);
    }

UIを更新するために子スレッドで呼び出されます。

requestLayout()

 /**
     * Call this when something has changed which has invalidated the
     * layout of this view. This will schedule a layout pass of the view
     * tree. This should not be called while the view hierarchy is currently in a layout
     * pass ({@link #isInLayout()}. If layout is happening, the request may be honored at the
     * end of the current layout pass (and then layout will run again) or after the current
     * frame is drawn and the next layout occurs.
     *
     * <p>Subclasses which override this method should call the superclass method to
     * handle possible request-during-layout errors correctly.</p>
     */
    @CallSuper
    public void requestLayout() {
        }

ビューの幅と高さが変更され、現在の領域に収まらなくなった場合は、requestLayoutメソッドを呼び出してビューを再レイアウトします。
ビューがrequestLayoutメソッドを実行すると、最上位の親ビューまで上向きに再帰し、次にこの最上位の親ビューのrequestLayoutを実行するため、他のビューのonMeasureおよびonLayoutも呼び出される場合があります。

大手工場へのインタビュールートの見直し

余計な言葉はお話ししませんが、次に面接のレビュールートをご紹介します。面接の準備もしているのに効率よくレビューする方法がわからない場合は、私のレビュールートを参考にしてください。ご不明な点がございましたら、お気軽にお問い合わせください。

誰もが体系的に学ぶための方向性は次のとおりです。

1.体系的な学習のためのビデオを見る

過去数年間のCrudの経験から、私は本当に新人の戦闘機であることがわかりました。また、Crudのおかげで、私の技術は比較的断片化されており、体系化するのに十分な深さではないため、もう一度勉強する必要があります。 。私に欠けているのは、システムの知識、貧弱な構造フレームワークとアイデアです。そのため、ビデオを通じて学ぶことは、より良く、より包括的です。ビデオ学習に関しては、個人がステーションBでの学習を推奨できます。ステーションBには多くの学習ビデオがあります。唯一の欠点は、無料で簡単に古くなることです。

また、私は自分でいくつかのビデオを集めました。必要に応じてそれらをあなたと共有することができます。

2.知識を体系的に整理し、準備金を改善する

クライアント開発には非常に多くの知識ポイントがあり、インタビューにはまだほとんど何もありません。したがって、これらの知識ポイントにどれだけ準備しているかを確認するためだけに、面接のための他のトリックはありません。したがって、面接に出かけるときは、レビューでどの段階に到達したかを確認することをお勧めします。

システム学習の方向性:

  • アーキテクトに不可欠なスキル:詳細なJavaジェネリック+単純な言語でのアノテーション+並行プログラミング+データ送信とシリアル化+ Java仮想マシンの原則+リフレクションとクラスローディング+動的プロキシ+効率的なIO

  • Androidの高度なUIとFrameWorkのソースコード:高度なUIプロモーション+フレームワークカーネル分析+ Androidコンポーネントカーネル+データの永続性

  • 360°の全体的なパフォーマンスチューニング:設計アイデアとコード品質の最適化+プログラムパフォーマンスの最適化+開発効率の最適化

  • オープンソースフレームワーク設計アイデアの解釈:ホットリペア設計+プラグインフレームワーク解釈+コンポーネントフレームワーク設計+画像読み込みフレームワーク+ネットワークアクセスフレームワーク設計+ RXJavaレスポンシブプログラミングフレームワーク設計+ IOCアーキテクチャ設計+ AndroidアーキテクチャコンポーネントJetpack

  • NDKモジュール開発: NDK基本知識システム+基礎となる画像処理+オーディオおよびビデオ開発

  • WeChatミニプログラム:ミニプログラムの紹介+ UI開発+ API操作+ WeChatドッキング

  • ハイブリッド開発とFlutter: Html5プロジェクトの戦闘+ Flutter Advanced

知識を整理した後、不足している点を確認する必要があるので、これらの知識点については、手元にたくさんの電子書籍やメモを用意しました。これらのメモは、各知識点の完全な要約を提供します。

3.ソースコードを読み、実際の戦闘ノートを読み、神の考えを学びます

「プログラミング言語はプログラマーが表現する方法であり、アーキテクチャーはプログラマーの世界に対する認識です。」したがって、プログラマーがアーキテクチャーをすばやく理解して学習したい場合は、ソースコードを読むことが不可欠です。ソースコードを読むことは、問題を解決し、物事を理解することであり、さらに重要なことは、ソースコードの背後にあるアイデアを参照することです。プログラマーは、何千行ものソースコードを読み、何千もの方法を練習します。

主にWeChatMMKVソースコード、AsyncTaskソースコード、Volleyソースコード、Retrofitソースコード、OkHttpソースコードなどが含まれます。

4.インタビューの前夜に、スプリントの質問

面接前1週間以内に全力疾走を開始できます。質問をブラッシングするときは、テクノロジーが最優先であり、アルゴリズムは並べ替えなどの基本であり、知的質問は、学校の新入生でない限り、通常は質問されないことに注意してください。

面接の質問に関して、私はあなたがお互いから学ぶのを助けるために一連の体系的な面接の質問を個人的に準備しました:

総括する

人生を変える近道はありません。自分でこの道を歩む必要があります。深い思考、絶え間ない反省と要約、学習への熱意の維持、段階的な独自の完全な知識システムの構築だけが、勝つための究極の方法です。プログラマーが着手すべき使命でもあります。

上記のコンテンツは、フルバージョンが必要なすべての人、友人と無料で共有できますすべてのコンテンツを表示するにはここをクリックしてください

おすすめ

転載: blog.csdn.net/weixin_44339238/article/details/112616741
おすすめ