1.Handlerの動作メカニズム、スレッド間はどのように通信しますか?
5216 ワード
Androidアプリケーションはメッセージによって駆動され、システムは各アプリケーションのためにメッセージキュー(MessageQueue)を維持し、アプリケーションのメインスレッドは絶えずこのメッセージキューからメッセージ(Looper)を取得し、これらのメッセージを処理(Handler)し、メッセージによってアプリケーションを駆動する実行を実現する.
HandlerはAndroidアプリケーション全体で重要な場所を占めているので、面接では、面接者がその原理を理解しているかどうかをよく調べ、大体の流れを明確に表現することができ、コミュニケーションと表現能力が技術能力よりも重要になることがあります.
面接問題:AndroidのHandlerメカニズムを話してもらえますか?
Androidのメッセージメカニズムを明らかにするには、Handlerに関連するいくつかのクラスを先に説明する必要があります.
Message:メッセージは、ボタン、タッチなどのハードウェアによって生成されたメッセージと、ソフトウェアによって生成されたメッセージに分けられる.MessageQueue:メッセージ・キューの主な機能は、メッセージ・プールにメッセージ(MessageQueue.enqueueMessage)とメッセージ・プールを取り出すメッセージ(MessageQueue.next)を配信する.Handler:メッセージ支援クラスで、主な機能はメッセージプールに各種メッセージイベント(Handler.sendMessage)を送信し、対応するメッセージイベント(Handler.handleMessage)を処理する.Looper:繰り返し実行(Looper.loop)を実行し、配布メカニズムによってメッセージをターゲット処理者に配布します.Handler関連クラスのコード量はそれほど多くないので、みんなが見てみることをお勧めします.ネット上にもこれらのソースコードを紹介し分析する文章がたくさんあります.みんな自分でGoogleを見てください.コードを一度通過すると、プロセス全体の理解が深まり、話すと余裕があります.面接のために裏書することはお勧めしません.
面接では、Handlerの仕組みをはっきり伝えることができれば、次に面接官は実際の開発で注意していることを主に聞きます.たとえば、ワークスレッドで独自のメッセージ・キュー・インスタンスを作成するにはどうすればいいですか?
実は側面から彼が正しいかどうかを検証し、Looperを呼び出すことを知っているかどうかを検証したいのです.prepare(スレッドごとに1回しか実行できません).
あるいはHandlerThreadを使ったことがあるかどうか、何かメリットとデメリットがあるかどうかなどを聞いてみましょう.
メリット
1.開発においてnew Thread(){…}のようなものを複数回使用する.start()この方法でサブスレッドを開くと、複数の匿名スレッドが作成され、プログラムの実行がますます遅くなりますが、HandlerThreadはLooperを持っていて、メッセージを通じて現在のスレッドを何度も繰り返し使用することができ、支出を節約することができます.2.Androidシステムが提供するHandlerクラス内部のLooperはデフォルトでUIスレッドのメッセージキューにバインドされており、非UIスレッドに対してメッセージメカニズムを使用したい場合は、HandlerThread内部のLooperが最も適切であり、UIスレッドを干渉したりブロックしたりしない.
注意事項
HandlerThreadを使用すると、HandlerThreadに異なるスレッド優先度を設定することに特に注意する必要があり、CPUは設定された異なるスレッド優先度に基づいてすべてのスレッドをスケジューリング最適化する.
注意:Handlerによるメモリの漏洩
HandlerはAndroidアプリケーション全体で重要な場所を占めているので、面接では、面接者がその原理を理解しているかどうかをよく調べ、大体の流れを明確に表現することができ、コミュニケーションと表現能力が技術能力よりも重要になることがあります.
面接問題:AndroidのHandlerメカニズムを話してもらえますか?
Androidのメッセージメカニズムを明らかにするには、Handlerに関連するいくつかのクラスを先に説明する必要があります.
Message:メッセージは、ボタン、タッチなどのハードウェアによって生成されたメッセージと、ソフトウェアによって生成されたメッセージに分けられる.MessageQueue:メッセージ・キューの主な機能は、メッセージ・プールにメッセージ(MessageQueue.enqueueMessage)とメッセージ・プールを取り出すメッセージ(MessageQueue.next)を配信する.Handler:メッセージ支援クラスで、主な機能はメッセージプールに各種メッセージイベント(Handler.sendMessage)を送信し、対応するメッセージイベント(Handler.handleMessage)を処理する.Looper:繰り返し実行(Looper.loop)を実行し、配布メカニズムによってメッセージをターゲット処理者に配布します.Handler関連クラスのコード量はそれほど多くないので、みんなが見てみることをお勧めします.ネット上にもこれらのソースコードを紹介し分析する文章がたくさんあります.みんな自分でGoogleを見てください.コードを一度通過すると、プロセス全体の理解が深まり、話すと余裕があります.面接のために裏書することはお勧めしません.
面接では、Handlerの仕組みをはっきり伝えることができれば、次に面接官は実際の開発で注意していることを主に聞きます.たとえば、ワークスレッドで独自のメッセージ・キュー・インスタンスを作成するにはどうすればいいですか?
実は側面から彼が正しいかどうかを検証し、Looperを呼び出すことを知っているかどうかを検証したいのです.prepare(スレッドごとに1回しか実行できません).
あるいはHandlerThreadを使ったことがあるかどうか、何かメリットとデメリットがあるかどうかなどを聞いてみましょう.
メリット
1.開発においてnew Thread(){…}のようなものを複数回使用する.start()この方法でサブスレッドを開くと、複数の匿名スレッドが作成され、プログラムの実行がますます遅くなりますが、HandlerThreadはLooperを持っていて、メッセージを通じて現在のスレッドを何度も繰り返し使用することができ、支出を節約することができます.2.Androidシステムが提供するHandlerクラス内部のLooperはデフォルトでUIスレッドのメッセージキューにバインドされており、非UIスレッドに対してメッセージメカニズムを使用したい場合は、HandlerThread内部のLooperが最も適切であり、UIスレッドを干渉したりブロックしたりしない.
注意事項
HandlerThreadを使用すると、HandlerThreadに異なるスレッド優先度を設定することに特に注意する必要があり、CPUは設定された異なるスレッド優先度に基づいてすべてのスレッドをスケジューリング最適化する.
注意:Handlerによるメモリの漏洩
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};```
, , Android lint , :
>In Android, Handler classes should be static or leaks might occur, Messages enqueued on the application thread’s MessageQueue also retain their target Handler. If the Handler is an inner class, its outer class will be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a WeakReference to its outer class
, , , ? 。
* 1. Android , Looper 。Looper 。 Android , Android ( Activity ) , Looper , Looper 。 Looper 。
* 2. Handler , target Handler Looper , Handler , Looper Handler#handleMessage(Message) 。
* 3. Java , 。 。 [ Java:” ” private ](http://droidyue.com/blog/2014/10/02/the-private-modifier-in-java/)
,
```java
public class SampleActivity extends Activity {
private final Handler mLeakyHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// ...
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mLeakyHandler.postDelayed(new Runnable() {
@Override
public void run() { /* ... */ }
}, 1000 * 60 * 10);
// Go back to the previous Activity.
finish();
}
}```
, Activity finish , 10 , Handler , Handler , SampleActivity , SampleActivity , SampleActivity , 。
### : new Runnable , SampleActivity , SampleActivity 。
, , Handler , , 。 , 。 Activity , [ ](http://droidyue.com/blog/2014/10/12/understanding-weakreference-in-java/) 。 Runnable 。 : 。
```java
public class SampleActivity extends Activity {
/**
* Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class MyHandler extends Handler {
private final WeakReference mActivity;
public MyHandler(SampleActivity activity) {
mActivity = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
SampleActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
private final MyHandler mHandler = new MyHandler(this);
/**
* Instances of anonymous classes do not hold an implicit
* reference to their outer class when they are "static".
*/
private static final Runnable sRunnable = new Runnable() {
@Override
public void run() { /* ... */ }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mHandler.postDelayed(sRunnable, 1000 * 60 * 10);
// Go back to the previous Activity.
finish();
}
}