getOutputStream在一个空套接字上?

问题描述:

我是新来的,我在这里问一个关于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,我从一本安卓手册中拿出了这个例子,所以我不排除这种错误的可能性:/你如何解决它? –

实现这一目标的最好的(也是最正确的)的方法是使用一个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 **里面。 –