2016-11-18 91 views
0

我正在开发一款android游戏。我正尝试在放置比赛的活动中创建一个套接字,但创建时应用程序崩溃。我正在寻找这个问题,我建议在Singleton类中创建一个套接字。但是当我尝试创建套接字时,应用程序仍然崩溃。Android - 在Singleton中创建套接字

public class SingletonConnection extends OnlineGame { 
private Socket socket; 
private SingletonConnection() throws IOException { 
    InetAddress serverAddr =InetAddress.getByName(hostname); 
    this.socket = new Socket(serverAddr, server_port); //CRASHA AQUI 
    this.inFromServer = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); 
    this.outToServer = new PrintWriter(this.socket.getOutputStream(),true); 

} 

public static SingletonConnection getSingletonConnection() throws IOException { 
    if (ref == null) 
     // it's ok, we can call this constructor 
     ref = new SingletonConnection(); 
    return ref; 
} 

public Object clone() 
     throws CloneNotSupportedException 
{ 
    throw new CloneNotSupportedException(); 
    // that'll teach 'em 
} 
public void WriteToSocket(String string){ 
    this.outToServer.println(string); 
} 
public String ReadFromServer() throws IOException { 
    return this.inFromServer.readLine(); 
} 
private static SingletonConnection ref; 
private static BufferedReader inFromServer; 
private static PrintWriter outToServer; 
public static final int server_port = 6000; 
public static final String hostname = "192.168.1.65"; 

}

我打电话这里的Singleton类

public void getInformationFromServer() throws IOException { 
    SingletonConnection conect = SingletonConnection.getSingletonConnection(); 

    try { 
     String playerString = conect.ReadFromServer(); 
     String[] players = playerString.split(","); 
     initPlayers(players); 
     String cardString = inFromServer.readLine(); 
     String playedCard = inFromServer.readLine(); 
     initDeck(cardString,playedCard); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

错误:

E/AndroidRuntime: FATAL EXCEPTION: main 
       Process: com.example.martins.highcards, PID: 5497 
       java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.martins.highcards/com.example.martins.highcards.OnlineGame}: android.os.NetworkOnMainThreadException 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        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) 
       Caused by: 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:586) 
        at java.net.Socket.connect(Socket.java:535) 
        at java.net.Socket.<init>(Socket.java:427) 
        at java.net.Socket.<init>(Socket.java:210) 
        at com.example.martins.highcards.SingletonConnection.<init>(SingletonConnection.java:19) 
        at com.example.martins.highcards.SingletonConnection.getSingletonConnection(SingletonConnection.java:28) 
        at com.example.martins.highcards.OnlineGame.getInformationFromServer(OnlineGame.java:93) 
        at com.example.martins.highcards.OnlineGame.onCreate(OnlineGame.java:66) 
        at android.app.Activity.performCreate(Activity.java:6664) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)  
        at android.app.ActivityThread.-wrap12(ActivityThread.java)  
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)  
        at android.os.Handler.dispatchMessage(Handler.java:102)  
        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)  
+0

对不起,StackOverflow适用于英文Q/A-s。 – Onik

+1

'由:android.os.NetworkOnMainThreadException'造成。我们从来没有Google,我们不? – greenapps

回答

0

当您尝试做在主线程上的网络操作此错误发生。该系统可防止冻结,因为某些操作可能需要大量加载时间并可能会冻结UI。

改为使用AsynkTask或在不同的线程上运行它。

public ReadingThread readThread; 
public int localPORT = 12345; 

public void startReadingThread(){ 
    if (readThread == null || (!readThread.isAlive())){ 
     try { 
      //define the socket but with null value 
      listener = new DatagramSocket(null); 
      listener.bind(new InetSocketAddress(localPORT)); 
      readThread = new ReadingThread(); 
      readThread.start(); 
     } 
     catch (Exception ex) 
     { 
      System.out.println(ex.toString()); 
      return ex.getMessage(); 
     } 
    } 
} 
public void stopReadingThread(){ 
    //stop the thread 
    if (readThread != null && (readThread.isAlive())) 
    { 
     readThread.stop(); 
     readThread = null; 
    } 
    //disconnect the socket 
    if (listener != null){ 
     listener.disconnect(); 
     listener.close(); 
    } 
} 
public class ReadingThread extends Thread { 
    public void stop(){ 
     continue = false; 
    } 
    public boolean continue = true; 
    public void run() { 
     while(continue) 
     { 
      try 
      { 
       final String readingFeed = receiveData(listener); 
       if (readingFeed != null){ 
        //execute next code on main Thread (UI update, etc) 
        runOnUiThread(new Runnable() { 
         public void run() 
         { 
          //do something with the data received 
         } 
        }); 
       } 
      } 
      catch(Exception ex) 
      { 
       //showToast("Receiving Error: " + ex.toString()); 
       //continue = false; 
      } 
     } 
    } 
} 
public String[] receiveData(DatagramSocket socket) 
{ 
    try 
    { 
     byte[] buf = new byte[padre.configAdmin.buffer_size]; 
     DatagramPacket packet = new DatagramPacket(buf, buf.length); 
     socket.receive(packet); 
     String data = new String(packet.getData()); 
     return data; 
    } catch (SocketTimeoutException e) { 
     return null; 
    } catch (IOException e) { 
     return new String[] {"IOError: " + e.getMessage()}; 
    } catch (Exception e) { 
     return new String[] {"ExError: " + e.getMessage()}; 
    } 
} 

为此,我建议线程,但AsynkTask会工作作为diferent主题为好,也AsynkTask有很多直接在主线程的工作职能,并且你不需要使用的代码runOnUiThread部分(如矿)。

+0

但是当我读取数据 最后String readingFeed = receiveData(listener); ,我怎么能把我从服务器收到的数据放在我的游戏类中? –

+0

在负责网络通信的类中,您可能想要引用GameClass,因此在本节中我编写了'//对数据做了一些事情......'将数据发送给GameClass函数'GameClass.dataArraived(readFeed)',或类似的东西。 –

+0

实际上,有很多方法可以将数据从一个对象传递到另一个对象,您可以实现一个侦听器,您可以对GameClass中的NetworkClass进行引用,您可以拥有一个具有两个类作为子对象的FatherClass并使用这个FatherClass作为对象之间的沟通手段,等等... –