2017-06-12 48 views
0

我是新來的,我在這裏問一個關於Sockets和Thread的問題。我有這樣的代碼,它給了我下面的錯誤:getOutputStream在一個空套接字上?

public class Conferma extends AppCompatActivity { 

    private final String TAG = "Conferma"; 
    public Socket socket; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.conferma); 

     final EditText etTavolo = (EditText) findViewById(R.id.etTavolo); 
     final RadioButton rbSi = (RadioButton) findViewById(R.id.rbSi); 
     RadioButton rbNo = (RadioButton) findViewById(R.id.rbNo); 
     Button bInvia = (Button) findViewById(R.id.bInvia); 

     Thread t = new Thread(new ClientThread()); 
     t.start(); 

     bInvia.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       String ordine = getIntent().getExtras().getString("ordine"); 
       if(etTavolo.getText().toString().equals("")){ 
        AlertDialog.Builder builder = new AlertDialog.Builder(Conferma.this); 
        builder.setMessage("Inserire il numero del tavolo!").setNegativeButton("Riprova!", null).create().show(); 
       } 
       ordine = ordine + "Tavolo: " + etTavolo.getText().toString() + "/"; 
       if(rbSi.isChecked()) { 
        ordine = ordine + "Coperto: Sì/"; 
       } 
       else{ 
        ordine = ordine + "Coperto: No/"; 
       } 
       Log.d(TAG, ordine); 

       //invio informazione 
       inviaStringa(view, ordine); 
      } 
     }); 
    } 

    private void inviaStringa(View view, String ordine) { 

     try{ 
      OutputStream s = socket.getOutputStream(); 
      OutputStreamWriter outputStreamWriter = new OutputStreamWriter(s); 
      BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter); 
      PrintWriter out = new PrintWriter(bufferedWriter, true); 
      out.println(ordine); 
     } catch (Exception e) { 
      Log.e(TAG, "Errore: " + e); 
     } 
    } 

    private class ClientThread implements Runnable { 

     private static final int SERVER_PORT = 6000; 
     private static final String SERVER_IP = "109.115.84.90"; 
     private static final String TAG = "ClientThread"; 

     @Override 
     public void run() { 
      try { 
       InetAddress serverAddress = InetAddress.getByName(SERVER_IP); 
       Log.d(TAG, "creato"); 
       socket = new Socket(serverAddress, SERVER_PORT); 
      } catch (UnknownHostException e) { 
       Log.e(TAG, "Errore: " + e); 
      } catch (IOException e) { 
       Log.e(TAG, "Errore: " + e); 
      } 
     } 
    } 
} 

錯誤:現在

java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.OutputStream java.net.Socket.getOutputStream()' on a null object reference

,從錯誤中我認爲這個問題是在插座,這意味着未初始化。但是如果我在創建簡單線程的時候調用ClientThread方法,爲什麼不初始化呢?感謝您的幫助,並且抱歉,如果我不能比這更清楚! :((

+0

貌似插座後會產生比你所謂的getOutputStream() – Jens

+0

插座不會被實例化,也許你誤解插座你在可運行類上創建另一個類?編輯:沒關係,我看到你做了什麼 – Thecave3

+0

它不給我的線,只是我粘貼在報價(NullPointerException事情)的東西。 Jens,我從一本安卓手冊中拿出了這個例子,所以我不排除這種錯誤的可能性:/你如何解決它? –

回答

0

實現這一目標的最好的(也是最正確的)的方法是使用一個AsyncTask(正如我在評論中寫道)

如果你想使用這個類,然後有很多種解決方案,在這裏。我只是建議一個我認爲是更清潔,在另一個文件中創建類ClientThread並添加到該方法inviaStringa:

ClientThread:

private class ClientThread implements Runnable {  
    private static final int SERVER_PORT = 6000; 
     private static final String SERVER_IP = "109.115.84.90"; 
      private static final String TAG = "ClientThread"; 
     private Socket socket; 

    public ClientThread(){ 
       try { 
        InetAddress serverAddress = InetAddress.getByName(SERVER_IP); 
        Log.d(TAG, "creato"); 
        socket = new Socket(serverAddress, SERVER_PORT); 
       } catch (UnknownHostException e) { 
        Log.e(TAG, "Errore: " + e); 
       } catch (IOException e) { 
        Log.e(TAG, "Errore: " + e); 
       } 
      } 

    } 

      @Override 
      public void run() { 
    } 
      private void inviaStringa(View view, String ordine) { 

      try{ 
       OutputStream s = socket.getOutputStream(); 
       OutputStreamWriter outputStreamWriter = new OutputStreamWriter(s); 
       BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter); 
       PrintWriter out = new PrintWriter(bufferedWriter, true); 
       out.println(ordine); 
      } catch (Exception e) { 
       Log.e(TAG, "Errore: " + e); 
      } 
     } 

     } 

然後裏面Conferma你不需要更多的申報插座,但只做到這一點

Thread t = new Thread(new ClientThread()); 
     t.start(); 

...//when you've to send the String 

t.inviaStringa(view, ordine); 
+0

當我嘗試調用線程上的inviaStringa方法時,它給了我一個錯誤,它說我必須把它作爲** final **,即使我這樣做,也無法在ClientThread類上找到該方法。 –

+0

這是因爲你在Listener裏面使用它,試着把最後的Thread放到最後。 – Thecave3

+0

如果我把線程t final,它給了我方法** inviaStringa **不能被解析,即使我聲明它在Listener內部或外部。我認爲是這樣的,因爲對象是一個Thread類型,而Thread類沒有方法調用** inviaStringa **裏面。 –

相關問題