Android 開発に関するよくある質問の投稿
1. Javaでのスコープ
- public: 他のすべてのクラスからアクセスできます
- プライベート: 自分自身のみがアクセスおよび変更できます
- protected: それ自体、サブクラス、および同じパッケージ内のクラスからアクセスできます。
- デフォルト: 同じパッケージ内のクラスにアクセスでき、宣言に修飾子は追加されないため、フレンドリーであると考えられます。
2. hashcode()、equals、== の違い
- 2 つのオブジェクトが等しい場合、Java ランタイム環境は、それらのハッシュコードが等しい必要があると判断します。
- 等しい 2 つのオブジェクトが等しくない場合、それらのハッシュコードは等しい可能性があります。
- 2 つのオブジェクトが同じハッシュコードを持つ場合、それらは等しいとは限りません。
- 2 つのオブジェクトのハッシュコードが等しくない場合、それらのオブジェクトのハッシュコードは等しくない必要があります。
- == 等号を基本データ型 (int long float ...) と比較すると、その値が
- == 等号がオブジェクトを比較する場合、オブジェクト内のアドレスが等しいかどうかが比較されます。
- 等しいは主に 2 つの文字列/文字が等しいかどうかを比較します。
3. HashMapとHashTableの違い
HashMap はスレッド安全ではありません。つまり、複数のスレッドで HashMap を使用する場合、たとえば、スレッド A (顧客) とスレッド B (顧客) がチケットを購入するためにリソース (ウィンドウ) を共有し、チケットが 1 枚残っている場合、スレッドは安全ではありません。二人ともこのチケットを同時に購入します。
HashTable はスレッドセーフです。つまり、複数のスレッドで HashTable を使用する場合、チケットの購入が例になります。A が最初にチケットを購入した場合、A はチケットを持ち、B はチケットを購入できません。それは主に、誰が最も速いインターネット速度を持っているか、そして誰がそれを最初に購入するかによって決まります。スレッドを安全にする理由は、キーワード synchronized がメソッドに追加されているため、スレッドは同期的に実行される必要があります。つまり、スレッド B はスレッド A の実行が終了した後にのみ実行できるようになります。
4. ArrayList と LinkedList の違い
ArrayList: 最下層は配列形式に基づいており、配列の特徴は連続したメモリ空間を占有し、内部的には高速なランダムアクセスを実現することであり、巨視的には検索は速く、データの挿入や削除は非常に遅い。なぜこのようなことが起こるのでしょうか? 回答: 配列のクエリ データは高速で、メモリは連続的であり、配列の途中に値が挿入されると後続の配列データはすべて元に戻されるため、挿入と削除は遅く、オーバーヘッドは比較的小さいためです。サイズが大きく、速度は比較的速いですが、遅い、削除は同じです。
LinkedList: 最下層はリンク リストの形式に基づいています。リンク リストの形式は (ノード データと次のノードへのポインタを含むノード) です。巨視的には、挿入と削除は高速で、クエリは低速です。 。なぜこのようなことが起こるのでしょうか? 回答: リンク リストの特性により、挿入と削除が高速です。データ ノードを削除する場合、リンク リストを 2 つの半分に分割して、削除されたノードが前半にあるか後半にあるかを判断します。が前半の場合は、前半の終了ノードから後ろから前にたどって削除するノードを探し、後半の場合は後半のリンクリストの先頭からたどっていきます。前から後ろに移動して、削除するノードを見つけます。それらすべてを走査する代わりに、削除されたノードを指す前のポインター フィールドを見つけるだけで十分です。クエリが遅いのは、リンク リストではプログラムがポインター フィールドを見つけて 1 つずつ走査する必要があり、コストがかかるためです。
特別なケース:
ArrayList は配列の後ろに数値を挿入しますが、後ろに数値を挿入しても前の数値を変更する必要がないため、配列の位置を変更する必要はありません。この状況は linkedList の場合と似ています。
LinkedList で数値をクエリする場合、その数値 (ノード) が真ん中にあれば、LinkedList を前半と後半に分けて数値 (ノード) をクエリするため、ArrayList クエリとほぼ同じくらい高速になります。
ArrayList 拡張機構: 容量がいっぱいになると、前の ArrayList の 1.5 倍の ArrayList が再作成され、前の ArrayList が 1.5 倍の ArrayList に順番に入れられます。
5. HashMapの内部原理
HashMap の最下層には、配列 + リンク リストの形式でデータが格納されます。つまり、配列の各要素はバケットと呼ばれるリンク リストです。HashMap はデータに高速にアクセスできるようにキーと値のペアを保存し、null キー/値を許可します
put() 操作: まず、キーのハッシュコード値が計算され、この値と配列の長さに対してモジュロ演算が実行され、put の格納場所である配列内の要素 (バケット) が取得されます。キーが同じ場合、前の値 value が置き換えられます。
get() 操作: まず、キーのハッシュコード値が計算され、この値と配列の長さに対してモジュロ演算が実行されて配列内の要素 (バケット) が取得され、次にハッシュコードの計算が実行されます。ハッシュコードの値が同じ(衝突が発生する)場合は、等しいかどうかを比較し、同じであれば取得したい位置を見つけて取り出す。衝突がなければ、同等のものは必要ありません。
HashMap 拡張メカニズム: しきい値 = 負荷係数 * 現在の容量、負荷係数のデフォルトは 0.75 です。HashMap の内部パラメータは、loadfactor と current Capacity で、最初のパラメータのデフォルトは 0.75 (75%)、2 番目のパラメータは HashMap のサイズです。HashMap の容量が 75% を占めると、2 倍の容量から再拡張されます。
6. Android におけるアクティビティのライフサイクル
onCreate()
アクティビティの作成時に実行されます
onStart()
アクティビティが表示されたとき、つまりフォアグラウンドに入ったときに実行されます。
onResme()
このメソッドは、アクティビティがユーザーと対話する準備ができたときに実行され、この時点のアクティビティはリターン スタックの最上位にあり、実行状態になっている必要があります。
onPause()
アクティブな部分が表示されているときに実行する、ステートメント: ダイアログ プロンプト ウィンドウではこのメソッドは実行されません。インターネット上のユーザーは唖然とし、テストせずに再投稿されます。アクティビティ部分が表示されているときに実行されるというのはなぜですか? アクティビティがダイアログ フォームに設定されている場合にのみ呼び出されます。
android:theme="@android:style/Theme.Dialog" を追加します。アクティビティをダイアログ スタイルに変更します。できる
現在のアクティビティがすべて非表示になっている場合にも呼び出されます。
onStop()
アクティビティが表示されていないときに呼び出されます
onDestory()
携帯電話の戻るボタンを押すか、Finish() を設定するなど、アクティビティが破棄されるときに呼び出されます。
インテントのライフサイクルを補足する [A が B にジャンプ]
A: A のライフサイクルを表します。
B: B のライフサイクルを表します。
onCreate(A)→onStart(A)→onResme(A)→onPause(A)→onCreate(B)→onStart(B)→onResme(B)→onStop(A)
Aに戻るとき
onPause(B)→onRestart(A)→onStart(A)→onResme(A)→onStop(B)→onDestroy(B)
Dialog と AlertDialog はアクティビティのライフサイクルに影響しません。
ダイアログはアクティビティにアタッチされているため、ブロックされません。
7. Intentによるデータ転送時とBundleによるデータ転送時の問題
Intent によって渡されるデータ型は、8 つの基本データ型 (int、float...) とシリアル化を実装する必要があるクラスである必要があります。
シリアル化 (Servalable、Parcable) の 2 種類のシリアル化。
シリアル化とは: オブジェクトはメモリに保存されるだけでなく、ネットワーク経由で送信したり、次回保存してロードしたりする必要があるため、Java シリアル化テクノロジが必要です。Java シリアル化テクノロジは、オブジェクトをバイナリ バイトの配列に変換します。バイナリ データをディスクまたは伝送ネットワークに保存することにより、ディスクまたはネットワークの受信側は、オブジェクトのカテゴリ オブジェクトのテンプレートでクラスを逆シリアル化して、オブジェクトの永続化の目的を達成できます。
2 つのシリアル化の違い: 1 つ目は Java に付属するシリアル化で、データのシリアル化をファイルからディスクに保存するために使用されますが、大量の一時変数が生成され、非常にスタックしてしまいます ( GC(ガベージコレクション)が頻繁に発生するため、メモリ上のデータ転送には適していません。
2 つ目は Android の組み込みシリアル化です。これはデータをディスクにシリアル化することができず、バイナリ形式からメモリ内のデータ送信をシリアル化します。
8. Android の 4 つの主要コンポーネント
- アクティビティ
- ブロードキャスト(BoderCast Receiver)は、
オーダードブロードキャストと無秩序ブロードキャストに分けられ、さらにスティッキーブロードキャストと標準ブロードキャスト、静的登録ブロードキャストとダイナミックブロードキャストに分けられます。順序付きと順序なしの違いは、ブロードキャストの優先順位が設定されていることです。優先順位が高いほど、ブロードキャストが最初に実行されます。スティッキーと標準の違いは次のとおりです。スティッキー ブロードキャストは、ブロードキャストを送信するときに他のアプリが登録されているかどうかを考慮しません。 me. Once I ブロードキャストに登録すれば受信し、登録していない場合は受信を待つことになりますが、通常のブロードキャストではこのようにはなりません。静的ブロードキャストは AndroidManifest.xml に登録する必要があり、プログラムが起動していなくてもブロードキャストは実行され続けます。ダイナミックブロードキャストの場合、AndroidManifest.xmlに登録する必要はなく、コード形式で登録され、番組起動時にのみブロードキャストが開始されます。 - サービス (Service)
クライアントとサーバー間の対話のためのバックグラウンド サービス。
1. onBindService
ライフサイクルを開始するには 2 つの方法があります: onCreate、onStart、onBind、onStop、onDestory。onCreateは作成後は実行されなくなり、再度ブロードキャストを実行する場合はonStartからのみ継続されます。onBind はバインド オブジェクトをクライアントに返します。
2. onStartService
ライフサイクル: onCreate、onStart、onStartCommnd、onStop、onDestory。上記のように、onCreate は作成後に実行されません。
3. IntentService
はサービスのサブクラスです。スレッド タスクは onHandleIntent を呼び出すことによって開始されます。各タスクはスレッドによって同期的に実行されます。つまり、1 つのスレッドが実行された後、別のスレッドが実行されます。一人ずつ来てください。たとえば、このサブカテゴリはいつ使用されます (アプリ ストアなど、大きなタスクを多くのサブタスクに分割できます。多くのアプリをダウンロードする場合は、これを考慮できますが、アプリ ストアでダウンロードされるアプリは通常、非同期的にダウンロードされます。ダウンロードのためにキューに入れられます) - コンテンツ プロバイダー (コンテンツ プロバイダー) は、
アプリケーション間でデータにアクセスし、sqlite データベースを直接操作します。たとえば、携帯電話の連絡先に直接アクセスします。
9. Android の 5 つの主要なレイアウト
- FrameLayout (フレームレイアウト、フレームレイアウト)
すべてのコントロールが画面の左上隅に順番に表示され、重なって表示されます。FrameLayout は最も単純なレイアウト オブジェクトです。これは、画面上の空白の予備領域としてカスタマイズされており、後で単一のオブジェクト (たとえば、投稿する写真) で埋めることができます。すべての子要素は画面の左上隅に固定されます。FrameLayout 内で子要素の位置を指定することはできません。後者の子要素は、前の子要素の上に直接オーバーレイされて塗りつぶされ、部分的または完全にブロックされます (後者の子要素が透明でない場合)。このレイアウトは壁の足元に物が積み上げられていると考えることができます。壁の左上隅に正方形の長方形があります。最初に物を置き、さらに置きたければそれを置きます。元の場所の上に、1 枚ずつ置き、元の場所を覆います。このレイアウトは比較的シンプルで、比較的シンプルなものをいくつかだけ配置できます。 - LinearLayout (線形レイアウト)
線形レイアウトは、すべてのレイアウトで最も一般的に使用されるクラスの 1 つであり、RadioGroup、TabWidget、TableLayout、TableRow、ZoomControls クラスの親クラスでもあります。LinearLayout は、その子要素を垂直方向 (android:orientation=”vertical”) または水平方向 (android:rientation=”horizontal”) に並べることができます (方向が設定されていない場合、デフォルトでは垂直方向に配置されます)。レイアウトが垂直の場合は、各行に要素が 1 つだけあり、複数の要素が垂直下に配置されます。レイアウトが水平の場合は、行が 1 つだけあり、各要素が順番に右に配置されます。
LinearLayout には android:layout_weight=”1” という重要な属性があります。このウェイトは縦レイアウトの場合は行間を表し、横レイアウトの場合は列幅を表し、ウェイト値が大きいほど大きくなります。 - AbsoluteLayout(絶対レイアウト)
AbsoluteLayoutはサポートされなくなったため、ここでは紹介しません。実際の開発では、携帯電話ごとに解像度が異なり、コンポーネントを配置するための固定ピクセルがあるため、AbsoluteLayout レイアウト方法を使用しないことを強くお勧めします。同時に、各レイアウトには制限もあるため、実際の開発では、より美しいユーザー インターフェイスを表示するために、1 つ以上のレイアウト メソッドを同時にネストすることがよくあります。 - RelativeLayout (相対レイアウト)
RelativeLayout を使用すると、子要素は他の要素または親要素 (ID で指定) に対する相対的な位置を指定できます。したがって、2 つの要素を画面上で右揃え、上下揃え、または中央揃えに配置できます。要素は順番に配置されるため、最初の要素が画面の中央にある場合、この要素を基準とする他の要素は画面の中央の相対位置に配置されます。XML を使用してレイアウトを指定する場合は、関連付けられた要素を定義する前にその要素を定義する必要があります。 - TableLayout (テーブル レイアウト)
テーブル レイアウト。子要素の位置を行または列に割り当てます。TableLayout は多数の TableRow (行) で構成されており、TableLayout コンテナには行、列、セルの境界線は表示されません。各行には 0 個以上のセルがあり、各セルには View オブジェクトがあります。テーブルは、多数のセルで構成される列と行で構成されます。表ではセルを空にすることができます。HTML とは異なり、セルは列をまたぐことはできません。
10. Android にはどのような種類のアニメーションがありますか?
1. モーショントゥイーン/アニメーション表示
ビューの実際の幅と高さは変更されませんが、ビューの表示位置が変更されます。そしてアニメーション動作中はクリックイベントは無効となります。実際のビューは動かなかったので
2.フレームアニメーション
フレームごとのアニメーションの場合、画像が大きすぎないように注意してください。大きすぎると、OOM やメモリ オーバーフローが発生しやすくなります。
3. プロパティアニメーション
実際のビューの位置が変更され、クリックイベントが実現されます。
アニメーションのいくつかのプロパティ
名称 原理 对应的Animation的子类
移動アニメーション (Translate) ビューの位置を移動する TranslateAnimation クラス
スケール アニメーション (Scale) ビューのサイズを拡大/縮小する ScaleAnimation クラス
回転アニメーション (Rotate) ビューの角度を回転する RotateAnimation クラス
透明度アニメーション (Alpha) 透明度を変更するビュー AlphaAnimation クラスの
11. Android の 4 つの起動モード
1.標準(デフォルトモード)
標準モードでは、新しいアクティビティ インスタンスが継続的に作成され、同じスタックに置かれます。
2.シングルトップ
現在のインスタンスが現在のタスクのスタックの最上位にある場合は直接再利用され、現在のインスタンスがスタックの最上位にない場合は新しいインスタンスが作成されます。
3.シングルタスク
singleTask が設定されたページは、タスク内にこのインスタンスが存在する限り常に再利用され、既存のインスタンスが再利用されるたびに、上記の他のインスタンスはクリアされ、直接昇格されます。それ自体を表示するスタックの最上位
4.単一インスタンス
singleInstance が設定されているページの場合、最初にこのページ用に新しいタスク スタックが作成され、その後、このスタック内のページが常に再利用されます。このモードのみが初期化されたページに新しいスタックを作成することに注意してください。最終的なリターンのルールは、最初にこのページが配置されているすべてのスタックが使い果たされてから、次のスタックの各ページがポップアップされるというものです。
12. ハンドラーのクロススレッド機構
ざっくりとお話しましょう。
4つの役割に分かれています。
ハンドラー: クロススレッド データ レシーバー。
message: スレッド間で送信されるメッセージのメッセージ本文。
メッセージ エンキュー: メッセージ キュー。リンクされたリストの形式でメッセージを保存します。メッセージは、遅延メッセージと遅延メッセージに分けられます。遅延が大きいほど、メッセージ キューは後方に配置されます。
Loopr: メッセージ キュー (メッセージ エンキュー) のマネージャー。メッセージ キュー内のメッセージの保存と解放を制御します。スレッドは Looper を通じて独自のメッセージ ループを確立し、Looper は MessageQueue からメッセージを取り出し、それをメッセージの指定されたターゲット Handler オブジェクトに配布する役割を果たします。
一般的なプロセス
サブスレッドがメインスレッドにデータを送信するときに、サブスレッドで handler.sendMessage(message) を呼び出します (デフォルトの遅延は 0ms) メッセージを送信するときは、ステップバイステップで呼び出されます
handler.sendMessageDelayd(message) では、現在時刻 + メッセージ遅延時間を実装し、次に handler.sendMessageAttime(message) を呼び出してメッセージの送信遅延時間を決定し、メッセージ エンキューを呼び出して、メッセージをメッセージに追加する準備をします。このとき、ルーパーに管理権が渡され、カレントスレッドが取得されますが、メインスレッドには多くのサブスレッドでメッセージを送信できるため、カレントスレッドを安全なスレッド(ThreadLocal)として設定します。データの混乱を防ぐためにスレッドを分離してから、メッセージを追加する必要があります。メッセージ キューで、target.dispatchMessage() メソッドが呼び出されます。ターゲットはハンドラーであり、メッセージはハンドラーに配布されます。つまり、メッセージはハンドラーにコールバックされ、ハンドラーのクロススレッド操作が完了します。
13.MVPモード
M (モデル): ほぼロジックが処理される場所
V (ビュー): アクティビティは、表示のために M からデータを出し入れする責任があります。
P(プレゼンター):仲介者。M と V は直接対話することはできませんが、P を通じて対話します。V→P↔M、VはデータをPに渡し、PはMに渡し、データを処理した後、MはPに、PはVに渡します。
この設計の利点は、結合度が低く、凝集性が高いため、1 か所を変更する必要がなく、どこでも変更できることです。
14.ANRとは何ですか
アプリケーションが応答していません。
- メイン スレッドが 5 秒以内に入力イベントの処理を終了しない場合、
この種の ANR を生成する前提として、入力イベントが存在する必要があります。ユーザーが入力イベントをトリガーしない場合は、メイン スレッドがブロックされていても、 InputDispatcher はイベントを配信しないため、ANR は生成されません。当然、アプリケーションに対しては、処理タイムアウトを検出して ANR を報告することはありません。つまり、ユーザーがAPPを操作するプロセス==入力イベントです。 - メインスレッドが BroadcastReceiver の onReceive 関数の実行を 10 秒以内に完了せず、バックグラウンド プロセスに 60 秒かかる場合、
ANR システムはダイアログ ボックス プロンプトを表示せず、ログを出力するだけです。 - メイン スレッドは Service の各ライフサイクル関数の実行を 20 秒以内に完了せず、バックグラウンド プロセスには 200 秒かかります。
同様に、この場合の ANR システムはダイアログ ボックス プロンプトを表示せず、ログを出力するだけです。
15. メモリ リークとメモリ不足 (OOM) とは何ですか
1. メモリオーバーフロー
システムは必要なスペースを割り当てることができなくなりました。たとえば、現在システムには 1G スペースしかありませんが、2G スペースが必要です。これはメモリ オーバーフローと呼ばれます。たとえば、毎回大量の大きな画像をロードし、画像リソースを解放しないと、時間が経つにつれて画像がメモリ内に残り、メモリが使い果たされるとクラッシュします。
ビットマップは画像を保存するための形式です。bitmap.recycler() を解放します。
2. メモリリーク
強参照が指すオブジェクトはリサイクルされないため、メモリ リークが発生する可能性があります。Java (jvm) 仮想マシンは、それが指すオブジェクトをリサイクルするよりも OOM をスローします。これは、リソースを使用するときに、リソースが解放されることを意味します。彼のためのスペースです。リソースを使い果たしたときに解放するのを忘れました。この時点では、メモリはまだ占有されています。一度は問題ありませんが、メモリ リークが多すぎると、メモリ オーバーフローにつながります。jvm の機能の 1 つは、メモリをより使いやすくするために、使用できないインスタンスや新しいオブジェクトなどのガベージを削除することであり、これは Java の独自のメカニズムでもあります。
ハンドラーもメモリ リークを引き起こす可能性があります。ハンドラーはスレッドを処理する必要があるため、スレッドが処理されずアクティビティがアクティブに終了した場合、ハンドラーは常にスレッドを処理します。解決策: 静的内部クラスは外部クラスへの参照を保持しないため、ハンドラーを静的内部クラス static myHandler class extend handler{} に変更します。独立した「クラス」です。
この問題を解決するには、弱い参照とソフト参照を使用することもできます。
16. ソフト参照、弱参照、強参照とは何ですか
Java のメモリ割り当てとメモリ回復はプログラマが責任を負う必要はなく、すべてが優れた JVM を担当します。オブジェクトがリサイクルできるかどうかは主に、このオブジェクトを指す参照があるかどうかによって決まります。専門的な点は到達可能性分析と呼ばれます。 。
Java がこれら 4 つの参照を設計する主な目的は 2 つあります。
- これにより、プログラマーはコードを通じてオブジェクトのライフサイクルを決定できます。
- ゴミ収集に適しています。
JVM の知識については話しません。
1. 強力な参照
強参照は最も一般的な種類の参照であり、私たちが記述するコードの 99.9999% は強参照です。
物体
新しい
物体
これは、コードのどこにでも見られるかどうかにかかわらず、最も心のこもった強力な参照です。
2. ソフトリファレンス
SoftReference<Student>studentSoftReference=new SoftReference<Student>(new Student());
//软引用就是把对象用SoftReference包裹一下,当我们需要从软引用对象获得包裹的对象,只要get一下就可以了:
Student student = studentSoftReference.get();
System.out.println(student);
メモリが不足すると、JVM の GC (ガベージ コレクション) がトリガーされ、GC (ガベージ コレクション) 後もメモリが不足する場合は、ソフト参照でラップされたオブジェクトが強制終了されます。メモリが不十分な場合、JVM はオブジェクトをリサイクルします。
ガベージコレクションとは:
ガベージ コレクションによって収集されるガベージは、不要なクラスや不要なオブジェクトなどです。プログラムの実行中に、不要なクラスやインスタンスはメモリを節約するためにクリーンアップされます。
3.弱引用
上記のコードと似ています。WeakReference オブジェクトでラップされる
弱参照の特徴は、メモリが十分であるかどうかに関係なく、GC が発生する限りリサイクルされることです。