ICSでcom.sun.jdi.InvocationException例外が発生する
XPERIA mini ProをGB(v2.3.4)からICS(v4.0.4)にアップデイトしたところ、順調に動作していたSaridaが突然落ちるようになってしまいました。
原因を調べてみると、下記のサーバソケットを生成しているところで、com.sun.jdi.InvocationException例外が発生していました。
ServerSocket ss = new ServerSocket(60082, 1);
例外が発生している様子。この例外が発生するとhostnameがnullになります。
そして、下記のような接続待ちのコードでアプリが強制終了します。
Socket socket = ss.accept();
原因は例外処理が追加されたことのようです
この例外発生の原因はHC(v3.0)以降、NetworkOnMainThreadExceptionという例外が新たに追加されたからのようです。見た目は「com.sun.jdi.InvocationException」が発生しているようですが、実はNetworkOnMainThreadExceptionが発生しているようです。
この例外が発生するのは、UIスレッドでスレッドを長時間止めるようなソケット命令が実行されたときのようです。例えば、上の例では、UIスレッドをServerSocketを生成したため、この例外が発生したようです。
対策1
NetworkOnMainThreadExceptionを発生させない対策としては、UIスレッドでスレッドを長時間止めるようなソケット命令を書かないことです。AsyncTaskクラスを使ってソケット命令を別スレッドとして書くことです。
UIスレッドに書かなければ例外は発生しません。参考程度にSaridaのServerSocket#acceptをAsyncTaskスレッドに書き直したものを書いておきます。
public class AcceptLuaVMasync extends AsyncTask<Integer, Integer, Integer >{ private SaridaSurfaceView prMainThred; public AcceptLuaVMasync(SaridaSurfaceView mainThred) { prMainThred = mainThred; } @Override protected void onPostExecute(Integer result){ prMainThred.postAcceptLuaVMasync(result); } @Override protected Integer doInBackground(Integer... arg0) { try{ SaridaActivity.puserversocket = new ServerSocket(SaridaActivity.puportnumber, 1); //LuaVMクラスに接続準備OKを伝える SaridaActivity.puReadyFlg = 1; //LuaVMの接続待ち SaridaActivity.puclientSocket = SaridaActivity.puserversocket.accept(); InetAddress iadd = SaridaActivity.puclientSocket.getInetAddress(); // 設定したIPアドレスからの接続かどうかチェックする if (iadd.toString().indexOf( SaridaActivity.puhostIP ) == -1) { SaridaActivity.puclientSocket.close(); return(0); } SaridaActivity.pudata_in = new DataInputStream(SaridaActivity.puclientSocket.getInputStream()); SaridaActivity.pudata_out = new DataOutputStream(SaridaActivity.puclientSocket.getOutputStream()); //LuaVMと接続したら立つフラグ SaridaActivity.isAcceptFlg = true; } catch(IOException e) { System.out.println(e); return(0); } return(1); } }