問題タブ [looper]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
2814 参照

android - StrictModeの混乱-これはどのように間違ったスレッドですか?

私の問題:

12-18 17:05:03.336:DEBUG / StrictMode(2112):StrictModeポリシー違反。〜duration = 2073 ms:android.os.StrictMode $ StrictModeDiskReadViolation:policy=23違反=2

ファクトリメソッドから

12-18 17:05:03.336:DEBUG / StrictMode(2112):android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)

それから私のコードで

12-18 17:05:03.336:DEBUG / StrictMode(2112):blah.ImageCache.getFromCache(ImageCache.java:248)

12-18 17:05:03.336:DEBUG / StrictMode(2112):
blah2 $ LoaderThread $ 1.handleMessage(blah.java:63)

重要な切り取り-その

クラスLoaderThreadはHandlerThreadを拡張します{

パブリックハンドラーmHandler;

public LoaderThread(String name){super(name); }

@Override public void onLooperPrepared(){mHandler = new Handler(){public void handleMessage(Message msg){Bitmap bit = ImageCache.getInstance()。getFromCache((String)msg.obj、ImageCache.USE_DISK); }}; }}

ImageCacheクラスのgetFromCacheメソッドは

これはUIスレッドで実行されているようですが、私には意味がありません。これはバックグラウンドスレッドで呼び出されるべきではありませんか?結局、これがHandlerThreadを使用する目的でした...

LoadThreadクラスはこのように私のonCreate(bundle)で作成されます

LoaderThread loader = new LoaderThread( "imgLoader")

loader.start();

メッセージはUIスレッドからハンドラーを介して渡されます

loader.mHandler.dispatchMessage(loader.mHandler.obtainMessage(args ..));

これは静的なgetInstanceメソッドと関係があるのだろうかと思います

パブリック静的同期ImageCachegetInstance(){

if(_instance == null){_instance = new ImageCache(); } return _instance; }

0 投票する
4 に答える
45893 参照

android - ルーパースレッドを作成し、すぐにメッセージを送信するにはどうすればよいですか?

メッセージを処理するバックグラウンドにあるワーカースレッドがあります。このようなもの:

メインスレッド(UIスレッド、それは重要ではありません)から私は次のようなことをしたいと思います:

問題は、これが私を美しい競合状態に設定することworker.handlerです。読み取り時に、ワーカースレッドがすでにこのフィールドに割り当てられていることを確認する方法はありません。

コンストラクターはメインスレッドで実行されるため、コンストラクターHandlerからを単純に作成することはできません。そのため、コンストラクターは間違ったスレッドに関連付けられます。WorkerHandler

これは珍しいシナリオのようには思えません。私はいくつかの回避策を思い付くことができますが、それらはすべて醜いです:

  1. このようなもの:

    そしてメインスレッドから:

    しかし、これも信頼できるものではありません。のnotifyAll()前に発生した場合wait()、私たちは決して起こされません!

  2. イニシャルMessageWorker'sコンストラクターに渡し、run()メソッドにポストさせます。アドホックソリューションは、複数のメッセージに対しては機能しません。または、すぐに送信したくない場合はすぐに送信します。

  3. handlerビジー-フィールドがなくなるまで待機しますnull。うん、最後の手段...

スレッドに代わってHandlerとを作成したいのですが、これは不可能のようです。これから最もエレガントな方法は何ですか?MessageQueueWorker

0 投票する
1 に答える
2589 参照

android - Android でノンブロッキング イベント処理を行うにはどうすればよいですか?

この質問は、Android でのイベント処理に関するものです。これは c++ に固有のものではありません。

すべてのイベントが処理されたときにブロックせずに、UI/OS イベントを処理する必要があります。

その理由は、移植しようとしているアプリケーションが非常に大きく、ワーカー スレッドで独自のものを処理するように簡単に書き直すことができないためです。代わりに、アプリケーション エンジンは、他の方法ではブロックされるような時間のかかる操作中に、UI/OS イベントを処理するように要求します。

ALooper_pollAll(...) がこれを行わないことがわかりました。たとえば、アクティビティでダイアログを作成して長い操作を開始した場合、ALooper_pollAll() はダイアログを表示しません。メイン ループに戻ったときにのみ表示されます (onNativeWindowCreated でテストしました)。

ほとんど機能することがわかった唯一の解決策は、JNI を介して次のコードを呼び出して、UI スレッドで内部ループを実行することです。

ただし、これは最適な解決策ではありません。処理するイベントがなくなるまでループしないためです (ループの実行中にイベントが作成される可能性があるため)。

調査中に、ルーパーから MessageQueue を取得し、内部ループを終了できる IdleHandler を追加できることがわかりました。私はまだこれを試していません。もっと良い方法があるはずです。

これが私が固執しなければならないアーキテクチャであるという事実を考えると、より良い解決策は何ですか?

アップデート:

MessageQueue を使用して、必要なものを達成できます。

ただし、より良い解決策があるかどうかを知りたいです。

0 投票する
2 に答える
3908 参照

android - ハンドラー-Androidでのルーパーの実装

  1. ハンドラーを使用したアクティビティ(UIスレッド)があります
  2. 新しいスレッドを開始し、handler.post(new MyRunnable())-(新しい作業スレッド)を作成します

Androidのドキュメントには、postメソッドについて次のように記載されています。「Runnablerがメッセージキューに追加されます。Runnableは、このハンドラーが接続されているスレッドで実行されます。」

UIスレッドにアタッチされたハンドラー。新しいスレッドを作成せずに、Androidを同じUIスレッドで実行可能にするにはどうすればよいですか?

新しいスレッドはhandler.post()からRunnableを使用して作成されますか?または、run()メソッドのみがRunnableサブクラスから呼び出されますか?

0 投票する
1 に答える
2086 参照

android - Android: 一定間隔で場所をプルすると、Looper Prepare がクラッシュします (はい、検索しました!!)

定期的に場所を取得して、ネットワーク経由で送信しようとしています。それを行う前に、場所を正しく取得していることを確認することが重要だと感じています! そのために、場所を取得して、メッセージを画面に表示する Handler に送信しようとします。私はあちこちを検索し、実際にスタック オーバーフローで非常に便利なコード セグメントを使用しました (どうもありがとうございました!) Android でユーザーの現在の場所を取得する最も簡単で最も堅牢な方法は何ですか?

いくつかのコードを次に示します。

MyLocation (例から):

このように使用すると、正常に動作します (以下は Main アクティビティ クラスのコードです)。

ただし、これを定期的に実行したいので、次のようなものがあります (次のコードはメイン アクティビティ クラスにあり、今回は Runnable を実装しています)。

注: threadHandler は、次で定義されている MyHandler 型です。

Looper.prepare() を呼び出していないスレッドから Handler への書き込みに関するエラーが発生しています。アクティビティとスレッドのさまざまな部分に Looper.prepare() と Looper.loop() を追加しようとしましたが、役に立ちませんでした。run() + sleep() の代わりにタイマーを使用してみました。

後で、スレッド ハンドラーに書き込む代わりに、場所をキューに挿入します。ソケット接続を処理する別のスレッドは、キューが空かどうかをチェックします。要素がある場合、dequeue() して送信します。

アドバイスをお願いします。

0 投票する
1 に答える
994 参照

java - Android でスレッド内にハンドラーを作成する

スレッドからトーストを見せてみました。

しかし、例外をスローします

この問題を解決するにはどうすればよいですか? Looper.myLooper().prepare();を前に置きましたToast.makeText(....).show();

これを行った場合、例外はスローされませんが、トースト メッセージは表示されません。

では、どうすればこの問題を解決できますか?

前もって感謝します。

0 投票する
1 に答える
4072 参照

android - AndroidサービスをUIスレッドで実行する必要があるのはなぜですか?

おそらく簡単な質問があります。私はAndroidサービスを持っています。ここで、ロックを要求し、別のスレッドで実際の(拡張)サービスコードを実行する汎用サービスクラスを作成しました。以下の例:

上記の例では、Looper.prepare()とLooper.loop()が呼び出されたスレッドで呼び出されなくても、すべてが正常に機能します。

ただし、GPSまたはネットワークを介して位置情報を取得しようとすると、次に問題が発生し、「Looper.prepare()を呼び出さなかったスレッド内にハンドラーを作成できません」というコードが実行されません。

UIスレッドと通信するためにルーパーとハンドラーを作成する必要があることを理解しています。UIに影響するイベントの場合。ただし、場所の取得はUIに影響しますか?これは、ロケーションプロバイダーが電話のトップバーにもGPSアイコンを描画しようとし、UIスレッドで実行されていないためです。それはできませんか?

ここでの問題は何ですか。looper.prepare()とLooper.loop()を呼び出すことで、この問題を修正できます。しかし、私は次のことを理解する必要がありますか?

  • UIスレッドと同じメインスレッドでサービスが実行されることは知っています。つまり、サービスにはUIを変更する機能がありますが、ユーザーエクスペリエンスが良くないため、変更を加えていません。そのため、通知を通じてすべてを伝達するのでしょうか。(通知もUIスレッドで実行する必要がありますか?)
  • ロケーションプロバイダーをUIスレッドで実行する必要があるのはなぜですか?
  • ここではハンドラーを宣言していません。looper.prepare();を呼び出しているだけです。では、メッセージキューはバックグラウンドでどのように機能し、Androidコードでは以下で何が起こるのでしょうか。

これらの質問へのポインタと回答は本当に役に立ちます。よろしくお願いします。

乾杯

0 投票する
5 に答える
16937 参照

android - ルーパーとスレッドを管理する方法(スレッドはもう死なない!)

Threadを拡張するクラスを作成して、UI以外のスレッドでLocationManagerを介してユーザーの場所を取得しました。リクエストに応じて開始し、限られた時間だけ作業を行う必要があるため、これをスレッドとして実装しました。ちなみに、LocationManager(onLocationChanged)のハンドラーを作成できるようにするには、スレッドにLooperオブジェクトを追加する必要がありました。

これはコードです:

スレッドを開始し、ユーザーの場所データを受信し(この場合は一度だけ)、ハンドラーへのメッセージを介してデータをメインスレッドに送信してから、終了します。問題は、私の場合、runメソッドが終了すると、スレッドが停止しなくなることです(そうしないと、onLocationChangedが新しい場所を受け取らないため、問題ありません)。

しかし、このように、スレッドのstopメソッドとsuspendメソッドが非推奨になったとすると、少なくともこの場合、ルーパーダイを使用してスレッドを作成するための良い方法は何でしょうか。

前もって感謝します ;)

0 投票する
2 に答える
1728 参照

android - 別のスレッドから AsyncTask を正しく呼び出す方法は?

別のスレッドで実行されているゲームを開発しています。ここで、インターネットから画像をダウンロードする必要があります。そのためのクラスを作成しましたAsyncTaskが、ゲーム スレッドから適切に呼び出す方法がわかりません。実際、AsyncTask画像がダウンロードされるまで待つ必要がありますが、ブロックされています。を使用するrunOnUIThreadと、スレッドがブロックされず、さらに先に進みます。これは私にはまったく合いません。Looper.prepare()before runningも使用してみましAsyncTaskたが、これにもいくつか問題があります。Looper.myLooper().quit()動作していないようです。もう一度 を呼び出そうとすると、2 番目AsyncTaskを呼び出そうとしていることを示す例外が発生します。Looper.prepare()時間。どのように進めればよいですか?前もって感謝します。