2017-11-10 10 views
0

私の家のLANのデスクトップPCのサーバソケットに接続するために、私のアプリ(Android 7.1.2で動作中)を取得するのに数時間お時間を割いています。リモートtcpソケットに接続するとアプリがクラッシュする

実行すると
public class MainActivity extends AppCompatActivity { 

    static final String SERVER_IP = "192.168.XXX.XXX"; // X's are replaced by actual IP 
    static final int PORT  = 30000; 

    Socket clientSocket; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     final Button btReceive = (Button) findViewById(R.id.btReceive); 

     final TextView txtReceivedText = (TextView) findViewById(R.id.txtReceivedText); 
     final TextView txtStatus  = (TextView) findViewById(R.id.txtStatus); 



     btReceive.setOnClickListener(new View.OnClickListener(){ 
      @Override 
      public void onClick(View v) { 

       txtStatus.setText("Received button pressed."); 

       try { 

        Socket s = new Socket(SERVER_IP, PORT); 


        BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); 
        final String st = input.readLine(); 

        txtReceivedText.setText(st); 

        s.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

     }); 

    } 


} 

私はAndroidのスタジオで、コンソールに出力を得る:

... 
Waiting for process to come online 
Connected to process 16980 on device samsung-gt_i9515-a72266ed 
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page. 
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView 
D/AndroidRuntime: Shutting down VM 
E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.example.jonas.network_connector, PID: 16980 
        android.os.NetworkOnMainThreadException 
         at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303) 
         at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:333) 
         at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196) 
         at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178) 
         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356) 
         at java.net.Socket.connect(Socket.java:605) 
         at java.net.Socket.connect(Socket.java:554) 
         at java.net.Socket.<init>(Socket.java:431) 
         at java.net.Socket.<init>(Socket.java:210) 
         at com.example.jonas.network_connector.MainActivity$2.onClick(MainActivity.java:88) 
         at android.view.View.performClick(View.java:5637) 
         at android.view.View$PerformClick.run(View.java:22433) 
         at android.os.Handler.handleCallback(Handler.java:751) 
         at android.os.Handler.dispatchMessage(Handler.java:95) 
         at android.os.Looper.loop(Looper.java:154) 
         at android.app.ActivityThread.main(ActivityThread.java:6186) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 
I/Process: Sending signal. PID: 16980 SIG: 9 
Application terminated. 

私は(同様とアンドロイド)プログラミングソケットに新たなんだので、私はに進む方法がわかりませんエラーを見つけます。

私のマニフェストは、許可ラインがあります。

<uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

答えて

1

にこのコードを追加します。

btReceive.setOnClickListener(new View.OnClickListener(){ 
      @Override 
      public void onClick(View v) { 
       txtStatus.setText("Received button pressed."); 
       new Thread(new Runnable() { 
        @Override 
        public void run() { 
         try { 
          Socket s = new Socket(SERVER_IP, PORT); 
          BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); 
          final String st = input.readLine(); 
          txtReceivedText.post(new Runnable(){ 

           @Override 
           public void run() { 
            txtReceivedText.setText(st); 
           } 
          }); 

          s.close(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
        } 
        } 
       }).start(); 
      }); 
1

android.os.NetworkOnMainThreadException

をこの例外は、メインスレッドでリモート呼び出ししようとしていることを示しています。 AsyncTaskを使用して呼び出すと、問題は再び表示されません。 Android OSはUIをロックできるため、メインスレッドで長時間実行される操作の実行を防ぎます。

0

android.os.NetworkOnMainThreadException

それはあなたのアプリケーションがそのメインスレッド上のネットワーク操作を実行しようとすることを意味します。 AsyncTaskでコードを実行します。

例:

class TCPTask extends AsyncTask<Void, Void, Void>{ 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
     } 
    } 

については非同期タスクを実行します。

あなたはワーカースレッドでのネットワークの作業を行う必要があり、あなたのOnCreate()メソッド

new TCPTask().execute(); 
関連する問題