Autore Topic: Problema Android Studio con Nougat  (Letto 629 volte)

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Problema Android Studio con Nougat
« il: 13 Giugno 2017, 12:43:23 CEST »
0
Salve a tutti. Ho sviluppato un app per controllare un robottino con Arduino. App e Arduino comunicano tramite wifi e si scambiano i dati tramite porte (socket). Mentre sviluppavo l'app avevo installato nel mio Galaxy S6 android 6.0.1 e l'app ha sempre funzionato correttamente. Dopo aver ricevuto l'aggiornamento ad Android 7, l'app ha smesso di funzionare. O meglio: si apre, i pulsanti si possono cliccare e riesco ad aprire la socket. Quando provo però a cliccare i bottoni avanti, indietro, ferma ecc, non invia alcun dato e di conseguenza il robottino non fa movimenti. Ho anche provato a fare il debug dell'app e mi appare l'eccezione Android.Os.NetworkOnMainThreadException quando provo ad inviare il coando. Devo dare qualche permesso speciale all'app per poter inviare dati tramite socket con android 7? Grazie in anticipo.

Post unito: [time]13 Giugno 2017, 12:43:31 CEST[/time]
« Ultima modifica: 13 Giugno 2017, 20:23:36 CEST da simo_scarponi »

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Problema Android Studio con Nougat
« Risposta #1 il: 14 Giugno 2017, 09:28:26 CEST »
0
L'errore indica che stai facendo una chiamata di rete dal Main Thread, e questo non è consentito per motivi di performance. Devi fare le chiamate WiFi su un thread a parte.

Prova con gli AsyncTask.

In pratica se hai un metodo "sendCommand(String command)" che fa la chiamata di rete, devi creare una classe che estende AsyncTask:

Codice (Java): [Seleziona]
private class SendCommandTask extends AsyncTask<String, Void, Void> {
  protected Void doInBackground(String... commands) {
    for (String command : commands) {
      sendCommand(command);
    }
  }
}

e invece di fare una chiamata diretta fai così:

Codice (Java): [Seleziona]
//sendCommand(command); //Vecchia chiamata
new SendCommandTask().execute(command); //Nuova chiamata
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Re:Problema Android Studio con Nougat
« Risposta #2 il: 14 Giugno 2017, 10:55:17 CEST »
0
Ma la cosa strana è che con le versioni precedenti ad Android 7 funziona tutto correttamente. Questa cosa di non fare una chiamata di rete sul Main Thread è stata aggiunta con Android 7? Comunque io utilizzo già una classe AsyncTask dove all'interno creo la socket che in effetti funziona. Poi al di fuori di questa classe, ho implementato i cinque metodi per il movimento del robot (avanti indietro ecc) in cui vengono inviate le stringhe che saranno poi lette e interpretate da Arduino. Ho provato a spostare questi metodi dentro la classe AsyncTask ma quando vado poi a cliccare i pulsanti di movimento l'app crasha, cosa che non accada quando stanno fuori dalla classe. Non so come risolvere.

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Problema Android Studio con Nougat
« Risposta #3 il: 14 Giugno 2017, 11:16:33 CEST »
0
Citazione
Due to a bug in previous versions of Android, the system did not flag writing to a TCP socket on the main thread as a strict-mode violation. Android 7.0 fixes this bug. Apps that exhibit this behavior now throw an android.os.NetworkOnMainThreadException. Generally, performing network operations on the main thread is a bad idea because these operations usually have a high latency that causes ANRs and jank.

Rif. qui: https://developer.android.com/about/versions/nougat/android-7.0-changes.html#other

Probabilmente anche se usi un AsyncTask stai facendo delle chiamate dal main thread. Ma senza vedere il codice non so dirti di più.
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Re:Problema Android Studio con Nougat
« Risposta #4 il: 14 Giugno 2017, 11:21:49 CEST »
+1
Codice (Java): [Seleziona]
public class Main extends AppCompatActivity {

    Socket socket = null;
    OutputStream oos = null;
    String ip = "", str = "";
    int port = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btAvanti = (Button)findViewById(R.id.btAvanti);
        Button btDestra = (Button)findViewById(R.id.btDestra);
        Button btSinistra = (Button)findViewById(R.id.btSinistra);
        Button btIndietro = (Button)findViewById(R.id.btIndietro);
        Button btStop = (Button)findViewById(R.id.btStop);
        Button btConnect = (Button)findViewById(R.id.btConnect);
        ImageButton btSettings = (ImageButton)findViewById(R.id.btSetting);
        WebView ipcam = (WebView)findViewById(R.id.ipcam);
        ipcam.loadUrl("http://192.168.192.222");
    }

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

        String dstAddress;
        int dstPort;

        MyClientTask(String addr, int port) {
            dstAddress = addr;
            dstPort = port;
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            socket = null;
            try {
                socket = new Socket(dstAddress, dstPort);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
                byte[] buffer = new byte[1024];
                int bytesRead;
                InputStream inputStream = socket.getInputStream();
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }
            }  catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    public void connect(View v) {
        Bundle extras = getIntent().getExtras();
        if(extras != null) {
            ip = extras.getString("address");
            port = extras.getInt("port");
        }
        try {
            MyClientTask myClientTask = new MyClientTask(ip, port);
            myClientTask.execute();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void setting(View v){
        Intent openSetting = new Intent(getApplicationContext(), Setting.class);
        startActivity(openSetting);
    }

    public void avanti(View v){
        try{
            str = "a";
            oos = socket.getOutputStream();
            byte[] arrayOutput = str.getBytes("ASCII");
            int nLen = arrayOutput.length;
            oos.write(arrayOutput, 0, nLen);
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void sinistra(View v){
        try{
            str = "s";
            oos = socket.getOutputStream();
            byte[] arrayOutput = str.getBytes("ASCII");
            int nLen = arrayOutput.length;
            oos.write(arrayOutput, 0, nLen);
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void destra(View v){
        try{
            str = "d";
            oos = socket.getOutputStream();
            byte[] arrayOutput = str.getBytes("ASCII");
            int nLen = arrayOutput.length;
            oos.write(arrayOutput, 0, nLen);
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void indietro(View v){
        try{
            str = "i";
            oos = socket.getOutputStream();
            byte[] arrayOutput = str.getBytes("ASCII");
            int nLen = arrayOutput.length;
            oos.write(arrayOutput, 0, nLen);
        } catch(Exception e){
            e.printStackTrace();
        }
    }

    public void stop(View v){
        try{
            str = "f";
            oos = socket.getOutputStream();
            byte[] arrayOutput = str.getBytes("ASCII");
            int nLen = arrayOutput.length;
            oos.write(arrayOutput, 0, nLen);
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

Questo è il codice del Main. I metodi setting, connect, avanti, indietro ecc sono tutti collegati ai rispettivi pulsanti sull'activity_main.xml nella proprietà onClick

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Problema Android Studio con Nougat
« Risposta #5 il: 14 Giugno 2017, 11:43:56 CEST »
+2
Anche se hai aperto la soket in modo asincrono, ci stai scrivendo (oos.write(arrayOutput, 0, nLen);) dal main thread.

Per risolvere aggiungi la classe che segue:

Codice (Java): [Seleziona]
private class SendCommandTask extends AsyncTask<String, Void, Void> {
        protected Void doInBackground(String... commands) {
                try {
                        OutputStream oos = socket.getOutputStream();
                        for (String command : commands) {
                                byte[] arrayOutput = command.getBytes("ASCII");
                                int nLen = arrayOutput.length;
                                oos.write(arrayOutput, 0, nLen);
                        }
                } catch(Exception e){
                        e.printStackTrace();
                }
        }
}

e modifica tutti i metodi di invio comandi (avanti, indietro, ecc.) come segue:

Codice (Java): [Seleziona]
public void avanti() {
  new SendCommandTask.execute("a");
}
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Re:Problema Android Studio con Nougat
« Risposta #6 il: 14 Giugno 2017, 12:02:25 CEST »
0
Per quanto riguarda la il doInBackground dentro la classe MyClientTask posso lasciaro così o devo apportare modifiche?

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Problema Android Studio con Nougat
« Risposta #7 il: 14 Giugno 2017, 12:17:54 CEST »
0
Dovrebbe andare bene anche così
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Re:Problema Android Studio con Nougat
« Risposta #8 il: 14 Giugno 2017, 12:20:17 CEST »
0
Ho provato la tua soluzione ma quando clicco i bottoni per il movimento l'app mi crasha.

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 804
  • Respect: +168
    • Github
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Huawei P9 Lite
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 10 x64
Re:Problema Android Studio con Nougat
« Risposta #9 il: 14 Giugno 2017, 12:23:52 CEST »
+1
Il log cosa dice? Che errore si verifica, e dove?
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline simo_scarponi

  • Nuovo arrivato
  • *
  • Post: 12
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Sistema operativo:
    Android Nougat 7.0
Re:Problema Android Studio con Nougat
« Risposta #10 il: 14 Giugno 2017, 12:31:19 CEST »
0
Trovato l'errore, manca la View nei parametri di ingresso dei metodi (avanti(View v)). Ora funziona correttamente. Grazie mille!!