2016-02-22 3 views
0

I необходимо создать, чтобы создать приложение с телефоном Android в качестве сервера, в то время как клиент (python) находится в системе linux. Я в основном хочу послать сообщения между ними, через Wi-Fi.Как разрешить «Пропущенные 31 кадр! Приложение может делать слишком много работы над своей основной нитью». для Android TCP Server

У меня есть нет Опыт разработки приложений (или JAVA), поэтому я просматриваю образцы кода. Я нашел следующее, которое в основном отображается всякий раз, когда клиент подключается к серверу.

Но я получаю предупреждение, когда я пытаюсь запустить это на андроид эмулятор (Android SDK)

Пропущено 31 кадр! Приложение может делать слишком много работы над своей основной нитью.

Я еще не реализовал клиентскую сторону, но вот код, на который я имею в виду. Как мне улучшить это? Server.java

package test.server2; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.io.PrintStream; 
import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.util.Enumeration; 

public class Server { 
    MainActivity activity; 
    ServerSocket serverSocket; 
    String message = ""; 
    static final int socketServerPORT = 8080; 

    public Server(MainActivity activity) { 
     this.activity = activity; 
     Thread socketServerThread = new Thread(new  SocketServerThread()); 
     socketServerThread.start(); 
    } 

    public int getPort() { 
     return socketServerPORT; 
    } 

    public void onDestroy() { 
     if (serverSocket != null) { 
      try { 
       serverSocket.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    private class SocketServerThread extends Thread { 

     int count = 0; 

     @Override 
     public void run() { 
      try { 
       // create ServerSocket using specified port 
       serverSocket = new ServerSocket(socketServerPORT); 

       while (true) { 
        // block the call until connection is created and  return 
        // Socket object 
        Socket socket = serverSocket.accept(); 
        count++; 
        message += "#" + count + " from " 
          + socket.getInetAddress() + ":" 
          + socket.getPort() + "\n"; 

        activity.runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          activity.msg.setText(message); 
         } 
        }); 

        SocketServerReplyThread socketServerReplyThread = 
          new SocketServerReplyThread(socket, count); 
        socketServerReplyThread.run(); 

       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    private class SocketServerReplyThread extends Thread { 

     private Socket hostThreadSocket; 
     int cnt; 

     SocketServerReplyThread(Socket socket, int c) { 
      hostThreadSocket = socket; 
      cnt = c; 
     } 

     @Override 
     public void run() { 
      OutputStream outputStream; 
      String msgReply = "Hello from Server, you are #" + cnt; 

      try { 
       outputStream = hostThreadSocket.getOutputStream(); 
       PrintStream printStream = new  PrintStream(outputStream); 
       printStream.print(msgReply); 
       printStream.close(); 

       message += "replayed: " + msgReply + "\n"; 

       activity.runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         activity.msg.setText(message); 
        } 
       }); 

      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       message += "Something wrong! " + e.toString() + "\n"; 
      } 

      activity.runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        activity.msg.setText(message); 
       } 
      }); 
     } 

    } 

    public String getIpAddress() { 
     String ip = ""; 
     try { 
      Enumeration<NetworkInterface> enumNetworkInterfaces =  NetworkInterface 
       .getNetworkInterfaces(); 
      while (enumNetworkInterfaces.hasMoreElements()) { 
       NetworkInterface networkInterface = enumNetworkInterfaces 
        .nextElement(); 
       Enumeration<InetAddress> enumInetAddress = networkInterface 
         .getInetAddresses(); 
       while (enumInetAddress.hasMoreElements()) { 
        InetAddress inetAddress = enumInetAddress 
         .nextElement(); 

        if (inetAddress.isSiteLocalAddress()) { 
         ip += "Server running at : " 
           + inetAddress.getHostAddress(); 
        } 
       } 
      } 

     } catch (SocketException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      ip += "Something Wrong! " + e.toString() + "\n"; 
     } 
     return ip; 
    } 
} 

(К сожалению о некорректном отступе здесь, но код выше сделал работу в эмуляторе)

И MainActivity.java

package test.server2; 

import android.os.Bundle; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.view.View; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.widget.TextView; 

public class MainActivity extends AppCompatActivity { 
    Server server; 
    TextView infoip, msg; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FloatingActionButton fab = (FloatingActionButton)  findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action",  Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 


      } 
     }); 

     infoip = (TextView) findViewById(R.id.infoip); 
     msg = (TextView) findViewById(R.id.msg); 
     server = new Server(this); 
     infoip.setText(server.getIpAddress() + ":" + server.getPort()); 

    } 


    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     server.onDestroy(); 


    } 
} 

Любого понять, как здесь нужно изменить поток?

Я буду добавлять кнопки и сервер отправлять сообщения клиенту и получать сообщения, поэтому не пропускать «кадры», и это важно. Также важно, чтобы не произошел сбой приложения, потому что клиент на самом деле является роботом.

ответ

0

Я не запускаю ваш код, однако попытайтесь опустить вызов server.getIpAdress() в методе onCreate() вашей активности.

Метод getIpAdress() выполняет много времени, такие как NetworkInterface.getNetworkInterfaces() и InetAdress.getHostAdress().

Посмотрите механизмы вроде AsyncTask для запроса объекта Server для ipaddress в фоновом потоке и обновления представления с результатом в основном потоке.

+0

Я по-прежнему стараюсь учиться на основе ваших предложений. Будет обновляться, как только я успею. Спасибо за вашу помощь. – sj22