2012-07-13 202 views
1

你好,我對TCP很陌生,我想構建一個多人遊戲。但是我遇到了一個致命的錯誤,每當我打開「Client.java」類時就會崩潰我的應用程序。Android TCP客戶端/服務器崩潰

我得到一個android.os.NetworkOnMainThreadException,我在android manufest中添加了INTERNET權限。我從另一個使用Intent進入這個類,是的,我有setOnClickListener(this);那裏並且增加了對生產者的活動,所以它不會因此而崩潰。 如果這是一個好主意,即時通訊在應用程序內部建立TCP服務器和客戶端,那麼我怎樣才能讓它成爲公共主機?就像我需要支付一臺主機,然後在服務器和客戶端使用ip/port?

反正這裏的代碼:

package com.theory.game; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.Scanner; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

public class Client extends Activity { 
/** Called when the activity is first created. */ 
Scanner scanner = new Scanner(System.in); 
//StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.client); 
    //StrictMode.setThreadPolicy(policy); 
    final EditText msg = (EditText) findViewById(R.id.etMsg); 
    Button send = (Button) findViewById(R.id.bSend); 
    final TextView convo = (TextView) findViewById(R.id.tvConvo); 
    final TextView status = (TextView) findViewById(R.id.tvStatus); 

    try { 
     send.setOnClickListener(new View.OnClickListener() { 

      Socket s = new Socket("10.0.2.2", 8080); 
      String message = msg.getText().toString(); 

      @Override 
      public void onClick(View v) { 
       status.setText("..."); 
       PrintWriter outp = null; 
       BufferedReader inp = null; 
       status.setText("Established connection.."); 
       String serverMsg = null; 

       try { 
        outp = new PrintWriter(s.getOutputStream(), true); 
        inp = new BufferedReader(new InputStreamReader(s.getInputStream())); 
        serverMsg = inp.readLine(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       convo.append(serverMsg + "\n"); 

       if (message != null) { 
        if (msg.getText().toString().trim() == "QUIT") { 
         try { 
          s.close(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
         status.setText("Disconnected from server."); 

        } else { 
          try { 

           convo.append(message + "\n"); 
           outp.println(message); 
           serverMsg = inp.readLine(); 
           convo.append(serverMsg + "\n"); 
          } catch (IOException e) { 
           e.printStackTrace(); 
          } 
        } 

       } 
       else 
        status.setText("Problem in connection..!"); 
      } 
     }); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
} 


`FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity 
android.os.NetworkOnMainThreadException 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
E/AndroidRuntime(706): at android.app.ActivityThread.handleLaunchActivity 
E/AndroidRuntime(706): at android.app.ActivityThread.access$600(ActivityThread.java:123) 
E/AndroidRuntime(706): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 
07-13 22:53:18.542: E/AndroidRuntime(706): at android.os.Handler.dispatchMessage(Handler.java:99) 

E/AndroidRuntime(706): at android.os.Looper.loop(Looper.java:137) 
E/AndroidRuntime(706): at android.app.ActivityThread.main(ActivityThread.java:4424) 
E/AndroidRuntime(706): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(706): at java.lang.reflect.Method.invoke(Method.java:511) 
E/AndroidRuntime(706): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 

E/AndroidRuntime(706): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
E/AndroidRuntime(706): at dalvik.system.NativeStart.main(Native Method) 
E/AndroidRuntime(706): Caused by: android.os.NetworkOnMainThreadException 
E/AndroidRuntime(706): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099) 

E/AndroidRuntime(706): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84) 
E/AndroidRuntime(706): at libcore.io.IoBridge.connectErrno(IoBridge.java:127) 
E/AndroidRuntime(706): at libcore.io.IoBridge.connect(IoBridge.java:112) 
E/AndroidRuntime(706): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192) 
E/AndroidRuntime(706): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) 
E/AndroidRuntime(706): at java.net.Socket.startupSocket(Socket.java:566) 
E/AndroidRuntime(706): at java.net.Socket.tryAllAddresses(Socket.java:127) 
E/AndroidRuntime(706): at java.net.Socket.<init>(Socket.java:177) 
E/AndroidRuntime(706): at java.net.Socket.<init>(Socket.java:149) 
E/AndroidRuntime(706): at com.theory.game.Client$1.<init>(Client.java:35) 
E/AndroidRuntime(706): at com.theory.game.Client.onCreate(Client.java:33) 
E/AndroidRuntime(706): at android.app.Activity.performCreate(Activity.java:4465) 
E/AndroidRuntime(706): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 

E/AndroidRuntime(706): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920) 

E/AndroidRuntime(706): ... 11 more ` 
+0

你可以發佈日誌貓的呼叫跟蹤嗎? – 2012-07-13 23:44:19

+0

是TJ我修改了我的帖子,請檢查它 – 2012-07-14 00:26:39

回答

0

你瞄準SDK 11或更高版本,並有嚴格的模式?每當您嘗試在主線程上執行網絡操作時,都會引發NetworkOnMainThreadException。改爲將您的網絡代碼移到AsyncTask。您不僅會照顧例外情況,還會改善您的申請。

使用AsyncTask非常簡單,有很多很好的教程。 Android documentation和教程Lars Vogel