2016-10-31 6 views
0

У меня возникла проблема с созданием сокета и отправкой сообщений из приложения android в малиновый pi. Я использовал этот пример со следующего сайта: http://android-er.blogspot.nl/2016/05/android-client-example-2-communicate.html, чтобы понять, как работают сокеты. Но пока я использую AsyncTask, я все равно получаю android.os.NetworkOnMainThreadException. Это мой MainActivity:Ошибка: android.os.NetworkOnMainThreadException при использовании asynctask

public class MainActivity extends AppCompatActivity { 

    EditText editTextAddress, editTextPort, editTextMsg; 
    Button buttonConnect, buttonDisconnect, buttonSend; 
    TextView textViewState, textViewRx; 

    ClientHandler clientHandler; 
    ClientThread clientThread; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 
     editTextAddress = (EditText) findViewById(R.id.address); 
     editTextPort = (EditText) findViewById(R.id.port); 
     editTextMsg = (EditText) findViewById(R.id.msgtosend); 
     buttonConnect = (Button) findViewById(R.id.connect); 
     buttonDisconnect = (Button) findViewById(R.id.disconnect); 
     buttonSend = (Button)findViewById(R.id.send); 
     textViewState = (TextView)findViewById(R.id.state); 
     textViewRx = (TextView)findViewById(R.id.received); 

     buttonDisconnect.setEnabled(false); 
     buttonSend.setEnabled(false); 

     buttonConnect.setOnClickListener(buttonConnectOnClickListener); 
     buttonDisconnect.setOnClickListener(buttonDisConnectOnClickListener); 
     buttonSend.setOnClickListener(buttonSendOnClickListener); 

     clientHandler = new ClientHandler(this); 
    } 

    View.OnClickListener buttonConnectOnClickListener = new View.OnClickListener() { 

     @Override 
     public void onClick(View arg0) { 

      MainActivity.this.startService(new Intent(MainActivity.this, 
        ClientThread.class)); 

      clientThread = new ClientThread(
        editTextAddress.getText().toString(), 
        Integer.parseInt(editTextPort.getText().toString()), 
        clientHandler); 
      clientThread.execute(); 




      buttonConnect.setEnabled(false); 
      buttonDisconnect.setEnabled(true); 
      buttonSend.setEnabled(true); 
     } 
    }; 

    View.OnClickListener buttonDisConnectOnClickListener = new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if(clientThread != null){ 
       clientThread.setRunning(false); 
      } 

     } 
    }; 
    String msgToSend; 
    View.OnClickListener buttonSendOnClickListener = new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if(clientThread != null){ 
       msgToSend = editTextMsg.getText().toString(); 
       clientThread.txMsg(msgToSend); 
      } 
     } 
    }; 

    private void updateState(String state){ 
     textViewState.setText(state); 
    } 

    private void updateRxMsg(String rxmsg){ 
     textViewRx.append(rxmsg + "\n"); 
    } 

    private void clientEnd(){ 
     clientThread = null; 
     textViewState.setText("clientEnd()"); 
     buttonConnect.setEnabled(true); 
     buttonDisconnect.setEnabled(false); 
     buttonSend.setEnabled(false); 

    } 

    public static class ClientHandler extends Handler { 
     public static final int UPDATE_STATE = 0; 
     public static final int UPDATE_MSG = 1; 
     public static final int UPDATE_END = 2; 
     private MainActivity parent; 

     public ClientHandler(MainActivity parent) { 
      super(); 
      this.parent = parent; 
     } 

     @Override 
     public void handleMessage(Message msg) { 

      switch (msg.what){ 
       case UPDATE_STATE: 
        parent.updateState((String)msg.obj); 
        break; 
       case UPDATE_MSG: 
        parent.updateRxMsg((String)msg.obj); 
        break; 
       case UPDATE_END: 
        parent.clientEnd(); 
        break; 
       default: 
        super.handleMessage(msg); 
      } 

     } 

    } 
} 

Этот код ClientThread.java:

public class ClientThread extends AsyncTask<Void, Void, Void>{ 

    String dstAddress; 
    int dstPort; 
    private boolean running; 
    MainActivity.ClientHandler handler; 

    Socket socket; 
    PrintWriter printWriter; 
    BufferedReader bufferedReader; 


    public ClientThread(String addr, int port, MainActivity.ClientHandler handler) { 
     super(); 
     dstAddress = addr; 
     dstPort = port; 
     this.handler = handler; 
    } 

    public void setRunning(boolean running){ 
     this.running = running; 
    } 

    private void sendState(String state){ 
     handler.sendMessage(
       Message.obtain(handler, 
         MainActivity.ClientHandler.UPDATE_STATE, state)); 
    } 

    public void txMsg(String msgToSend){ 

     if(printWriter != null){ 
      printWriter.println(msgToSend); 
     } 
    } 



    @Override 
    protected Void doInBackground(Void... arg0) { 
     System.out.println("In doinbackground"); 

     sendState("connecting..."); 

     running = true; 

     try { 
      socket = new Socket(dstAddress, dstPort); 
      sendState("connected"); 

      OutputStream outputStream = socket.getOutputStream(); 
      printWriter = new PrintWriter(outputStream, true); 

      InputStream inputStream = socket.getInputStream(); 
      InputStreamReader inputStreamReader = 
        new InputStreamReader(inputStream); 
      bufferedReader = new BufferedReader(inputStreamReader); 

      while (running) { 

       //bufferedReader block the code 
       String line = bufferedReader.readLine(); 
       if (line != null) { 
        handler.sendMessage(
          Message.obtain(handler, 
            MainActivity.ClientHandler.UPDATE_MSG, line)); 
       } 

      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (bufferedReader != null) { 
       try { 
        bufferedReader.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      if (printWriter != null) { 
       printWriter.close(); 
      } 

      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     handler.sendEmptyMessage(MainActivity.ClientHandler.UPDATE_END); 
     return null; 
    } 

} 

Это ошибка, я получаю:

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.example.zerocj.projectsocked, PID: 2415 
        android.os.NetworkOnMainThreadException 
         at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303) 
         at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) 
         at java.net.SocketOutputStream.write(SocketOutputStream.java:157) 
         at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) 
         at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) 
         at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295) 
         at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141) 
         at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229) 
         at java.io.BufferedWriter.flush(BufferedWriter.java:254) 
         at java.io.PrintWriter.newLine(PrintWriter.java:482) 
         at java.io.PrintWriter.println(PrintWriter.java:629) 
         at java.io.PrintWriter.println(PrintWriter.java:740) 
         at com.example.zerocj.projectsocked.ClientThread.txMsg(ClientThread.java:47) 
         at com.example.zerocj.projectsocked.MainActivity$3.onClick(MainActivity.java:85) 
         at android.view.View.performClick(View.java:5610) 
         at android.view.View$PerformClick.run(View.java:22260) 
         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:6077) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

ответ

-1

Пожалуйста, проверьте трассировки стека. Он говорит, что в вашем коде используется строгий режим.

int SDK_INT = android.os.Build.VERSION.SDK_INT; 

if (SDK_INT > 8) 
{ 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 
        .permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 

    // Where you get exception write that code inside this. 
} 

Спасибо, что вам это поможет.

+0

@Jelle вы попробовали мое решение? – Saveen

+0

Да, я пробовал, и это сработало. – Jelle

+0

Отличное и другое решение, в котором вы можете использовать обработчик или любую нить для выполнения такой работы. – Saveen

0

Вы вызываете свой метод txMsg() из прослушивателя кликов, который запускается в потоке пользовательского интерфейса. И этот метод, похоже, записывает в Writer, который подключен к сокету.

Если Wanna обмениваются сообщениями вперед и назад между фоновым потоком и UI нить, может быть лучшей идеей, что AsyncTask бы Thread с Looper и обработчиков для передачи сообщений по от одного потока к другому.

Смежные вопросы