[Q&A] peer.destroy()時に落ちる

670 views
Skip to first unread message

小西裕介

unread,
May 25, 2016, 9:01:46 AM5/25/16
to SkyWay Technical Forum
peer.destroy()の中で、以下のエラーで落ちるケースがあります。
callした後に逆にcall仕返された場合に発生しています。
情報が少なくて申し訳ないのですが、どのように対処すればいいかわからないので何かわかることがあればおしえていただけますでしょうか?

05-25 21:58:17.455 4102-4463/com.taptrip.integration I/NIO: Selector exception, shutting down
                                                            com.koushikdutta.async.AsyncServer$AsyncSelectorException: java.nio.channels.ClosedSelectorException
                                                                at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:756)
                                                                at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:626)
                                                                at com.koushikdutta.async.AsyncServer.access$700(AsyncServer.java:41)
                                                                at com.koushikdutta.async.AsyncServer$13.run(AsyncServer.java:568)
                                                             Caused by: java.nio.channels.ClosedSelectorException
                                                                at java.nio.SelectorImpl.checkClosed(SelectorImpl.java:146)
                                                                at java.nio.SelectorImpl.selectInternal(SelectorImpl.java:168)
                                                                at java.nio.SelectorImpl.selectNow(SelectorImpl.java:164)
                                                                at com.koushikdutta.async.SelectorWrapper.selectNow(SelectorWrapper.java:26)
                                                                at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:730)
                                                                at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:626) 
                                                                at com.koushikdutta.async.AsyncServer.access$700(AsyncServer.java:41) 
                                                                at com.koushikdutta.async.AsyncServer$13.run(AsyncServer.java:568) 
05-25 21:58:18.483 885-2936/? E/ConnectivityService: RemoteException caught trying to send a callback msg for NetworkRequest [ id=220, legacyType=5, [ Transports: CELLULAR Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN] ]
05-25 21:58:18.491 885-915/? W/WindowAnimator: Failed to dispatch window animation state change.
                                               android.os.DeadObjectException
                                                   at android.os.BinderProxy.transactNative(Native Method)
                                                   at android.os.BinderProxy.transact(Binder.java:503)
                                                   at android.view.IWindow$Stub$Proxy.onAnimationStarted(IWindow.java:520)
                                                   at com.android.server.wm.WindowAnimator.updateWindowsLocked(WindowAnimator.java:282)
                                                   at com.android.server.wm.WindowAnimator.animateLocked(WindowAnimator.java:678)
                                                   at com.android.server.wm.WindowAnimator.-wrap0(WindowAnimator.java)
                                                   at com.android.server.wm.WindowAnimator$1.doFrame(WindowAnimator.java:123)
                                                   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:856)
                                                   at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                                                   at android.view.Choreographer.doFrame(Choreographer.java:603)
                                                   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                   at android.os.Looper.loop(Looper.java:148)
                                                   at android.os.HandlerThread.run(HandlerThread.java:61)
                                                   at com.android.server.ServiceThread.run(ServiceThread.java:46)

Hiroki Kato

unread,
May 25, 2016, 10:07:42 PM5/25/16
to SkyWay Technical Forum
小西様

初めまして。
SkyWay開発チームの加藤です。

申し訳ございませんが、頂いたエラーメッセージから原因を把握するのは難しそうです。

我々の環境でも確認いたしますので、お手数ですが事象の再現手順をお教えいただけますでしょうか。
特にpeer.destroy()の発行と2端末から相互のpeer.cal()lの発行タイミングについての関係を教えていただければと思います。

また、利用端末・OSバージョンもお教えください。
よろしくお願いします。



2016年5月25日水曜日 22時01分46秒 UTC+9 小西裕介:

小西裕介

unread,
May 25, 2016, 11:01:35 PM5/25/16
to SkyWay Technical Forum
返信ありがとうございます。

もともとの経緯からお話しします。

チャット待機状態のユーザーに対して、別のユーザーがチャットをかけるという流れを想定しています。
チャット待機状態を画面を閉じても有効にしておくために、Serviceクラスでpeerを作って各callbackをセットしています。
Serviceクラスでcallを受け取った時、着信中の画面を表示するためにActivityを開きます。コードで言えば、以下の部分です。

peer.on(Peer.PeerEventEnum.CALL, object -> {

    // 着信中の画面を表示する

}


着信中の画面でOKを押すと、ビデオチャット状態に遷移させたいのですが、問題はServiceクラスで作成したpeerとActivityのpeerを共有できないことでした。そこで、Service側のpeerを一度切り、Activityで同じpeerIdでpeerを作って、電話を受けた側がかけ直すというやり方で実装しています。


少し複雑で申し訳ないのですが、まとめますと

1. Serviceクラスでpeerをopen、callを受ける。
2. callを受けたら一旦peerをdestroyしてActivityを表示する。
3. 表示したActivityでpeerをoepnしてcallし直す。
4. ビデオチャット状態になる。
5. Activityを閉じる時にpeer.destroy()を呼ぶ
6. エラーが出て落ちる

という流れです。

利用端末はSumsung GalaxyNote3 5.1とNexus5x 6.0で試しています。両方発生します。


2016年5月26日木曜日 11時07分42秒 UTC+9 Hiroki Kato:

Hiroki Kato

unread,
May 26, 2016, 1:01:02 AM5/26/16
to SkyWay Technical Forum
小西様

まず、対応方法としては、
peer.destroy()を行う前にmediaConnection.close()を呼び出す形に変更してご確認いただけませんでしょうか。
peer接続がある中でdestroyを行うと不具合が発生する場合がございます。


また、こちらは参考情報ですが、
待機状態への通知にはGCM等を使う方が望ましいかと思います。
待機状態でpeerを接続したままにするとSkyWayのサーバとWebSocket通信を維持し続けることになり、

・NWなどの環境起因でWebSocket通信が途切れる=待機状態が解除される可能性がある。
・電池の消費が激しい

と言ったデメリットがございます。

また、SkyWay SDKを使う場合にも接続前の処理でしたら、MediaConnectionではなく、
DataConnectionをご利用頂くと、接続相手の確認等の処理を容易に入れることができるかと思います。

お作りになるアプリの要件次第ですので、もし要件として必要でしたらご参考にしていただければと思います。


よろしくお願いします。


2016年5月26日木曜日 12時01分35秒 UTC+9 小西裕介:

小西裕介

unread,
May 26, 2016, 1:40:27 AM5/26/16
to SkyWay Technical Forum
返信ありがとうございます。
peerのdestroy前にmediaConnectionのcloseは呼ぶようにしていました。以下のようなコードです。

final void destroyPeer() {

    // 略
    if (mediaConnection != null) {
        if (mediaConnection.isOpen) mediaConnection.close();
       
mediaConnection.on(MediaConnection.MediaEventEnum.STREAM, null);
       
mediaConnection.on(MediaConnection.MediaEventEnum.CLOSE, null);
       
mediaConnection.on(MediaConnection.MediaEventEnum.ERROR, null);
       
mediaConnection = null;
   
}

    Navigator.terminate();

    if
(peer != null) {
        peer.on(Peer.PeerEventEnum.OPEN, null);
       
peer.on(Peer.PeerEventEnum.CONNECTION, null);
       
peer.on(Peer.PeerEventEnum.CALL, null);
       
peer.on(Peer.PeerEventEnum.CLOSE, null);
       
peer.on(Peer.PeerEventEnum.DISCONNECTED, null);
       
peer.on(Peer.PeerEventEnum.ERROR, null);

        if
(!peer.isDisconnected) peer.disconnect();
        if
(!peer.isDestroyed && canDestroy()) peer.destroy();
       
peer = null;
   
}
}


> 待機状態への通知にはGCM等を使う方が望ましいかと思います。

ネットワークの通信が切れた場合は、コールバックで検知できるので待機が解除されるという挙動で問題はないです。
GCMでの通知も検討したのですが、以下の要件を満たせず諦めた経緯があります。
・LINEのようにコール中の表示を出す場合、コール開始は問題ないが、GCMは数分単位で遅れる可能性があるためコール終了を正しく通知することができない。

着信中の表示と、着信の拒否ボタンを押下したことが相手にもわかるようにする、という2点を実現できればいいのですが、うまいやり方が思いつかずコールを受け取った側が掛け直すというやり方にしているという感じです。

無理やりなやり方だとはわかってはいるのですが、Serviceで待機してコール時にこのような画面を表示させるやり方はありますでしょうか?




2016年5月26日木曜日 14時01分02秒 UTC+9 Hiroki Kato:

Hiroki Kato

unread,
May 26, 2016, 4:02:31 AM5/26/16
to SkyWay Technical Forum
コードのご提示ありがとうございます。

事象に関して、我々の環境で事象が再現できておらず、再現に関わりそうな部分のコードのご提示をお願いできませんでしょうか。

具体的には、SkyWayの利用という点で整理すると下記のような認識をしております。

1. Serviceクラスでpeerをopen、callを受ける。
2. callを受けたら一旦peerをdestroyしてActivityを表示する。
peerを初期化してcall -> destroy:peerを破棄
 
3. 表示したActivityでpeerをoepnしてcallし直す。
(peerIDを指定して、) peerを初期化
 
4. ビデオチャット状態になる。
5. Activityを閉じる時にpeer.destroy()を呼ぶ
mediaconnection.close();
peer.disconnect();
peer.destroy() ;
 
6. エラーが出て落ちる


上記から、
1.通常のActivityからpeerの初期化
2.ビデオチャットの実施
3. mediaconnection.close(); -> peer.disconnect(); -> peer.destroy() ;
を行えばSkyWay周りのテストでは同義と考え、我々の環境で試験しているのですが、事象が再現出来ておりません。

オブジェクトの管理の再確認、又はエラーに関わりそうな箇所のコードのご確認をお願いできませんでしょうか。



無理やりなやり方だとはわかってはいるのですが、Serviceで待機してコール時にこのような画面を表示させるやり方はありますでしょうか?
申し訳ございません。直ぐに思いつくような方法がございません。
Androidの仕様を全て把握しているわけではございませんので、確定したことは申し上げられませんが、
GCMを利用しない方法となると、仰る通り、無理やりな方法になりそうな気はします。


よろしくお願いします。



2016年5月26日木曜日 14時40分27秒 UTC+9 小西裕介:
Reply all
Reply to author
Forward
0 new messages