2015-09-29 24 views
0

我想創建套接字連接,但我遇到了一些問題。我必須在新線程中創建它,但我不能。如何在新線程中創建套接字

public class SocketManager { 
    private static SocketManager instance; 


    private BufferedReader in; 
    private PrintWriter out; 
    private Socket mSocket = null; 

    public static SocketManager me() { 
     if (instance == null) { 
      instance = new SocketManager(); 
     } 
     return instance; 
    } 

    public void connection() { 
     new AsyncTask<Void, Void, Void>() { 

      @Override 
      protected Void doInBackground(Void... params) { 
       try { 
        mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       return null; 
      } 
     }.execute(); 
    } 

    public boolean isConnected() { 
     return mSocket.isConnected(); 
    } 

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     status = (TextView) findViewById(R.id.status); 
     button = (Button) findViewById(R.id.button); 
     button.setOnClickListener(this); 
     SocketManager.me().connection(); 
     if (SocketManager.me().isConnected()) { 
      status.setText("Connected"); 
     } else { 
      status.setText("Disconnected"); 
     } 

我有錯誤:

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

Becouse mSocket在新線程創建,當我把它叫做它== NULL;如何在新線程中創建mSocket並使用它?

+0

在我看來,'SocketManager.me()'返回 空值。您需要先添加空檢查。 –

+0

您需要等待套接字實際創建。你可以把Thread.sleep(1000)調用connection()和isConnected()來測試它嗎? – ilj

+0

我可以添加檢查null,但它沒有意義,因爲我不需要mSocket == null,我nedd mSocket不爲null – Pavel

回答

1

最好的方法是使用接口。

在Socketmanager類

public class SocketManager { 
    private static SocketManager instance; 
    private SocketListner listner; 

    public interface SocketListner { 
     void onConnectionSuccess(); 
     void onConnectionFailed(); 
    } 

    public void connection(SocketListner listner) { 
     this.listner = listner; 
     new ConnectionTask().execute(); 
    } 

創建一個接口,並從doInBackGround()方法返回一個布爾值,以檢查連接是否成功與否

class ConnectionTask new AsyncTask<Void, Void, Boolean>() { 
     @Override 
     protected Void doInBackground(Void... params) { 
      //...your code 

     } 
     @Override 
     protected void onPostExecute(Boolean result) { 
      if(result) { 
       listner.onConnectionSuccess(); 
      } else { 
       listner.onConnectionFailed(); 
      } 
     } 
    } 

而在你的活動實現的接口

public class YourActivity imlpements SocketListner { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    //your code 
     .. 
    } 
    @Override 
    void onConnectionSuccess() { 
     //your socket is connected 
     status.setText("Connected"); 
    } 

    @Override 
    void onConnectionFailed() { 
     status.setText("Disconnected"); 
    } 
} 
0

我想方法「isConnected()」正試圖訪問mSocket之前它被初始化。

嘗試將其更改爲:

public boolean isConnected() { 
    return mSocket == null ? false : mSocket.isConnected(); 
} 

這將避免這種方法的NullPointerException異常。

但是,這裏的正確方法是使用回調,以便子線程完成後可以通知主線程。

public class SocketTask extends AsyncTask<Void, Void, Void> { 

    public interface AsyncTaskListener<T> { 
     void onTaskCompleted(T t); 
    } 

    private final AsyncTaskListener<String> listener; 

    public SocketTask(AsyncTaskListener<String> listener) { 
     this.listener = listener; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     try { 
        mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       return null; 
    } 

    @Override 
    protected void onPostExecute() { 
     listener.onTaskCompleted(); 
    } 
} 

你類SocketManager需要實現回調:

public class SocketManager implements SocketTask.AsyncTaskListener { 

} 
+0

和?????我有mSocket == null並調用isConnected()並返回false,那麼接下來是什麼?我不能與mSocket一起工作,我想創建mSocket – Pavel

0

添加布爾知道你的AsyncTask完成與否。

boolean mIsSocketInstanceCreated = false; 

public void connection() { 
     new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 
       try { 
        mSocket = new Socket(Constants.CHAT_SERVER_URL, 4444); 
        mIsSocketInstanceCreated = true; 
       } catch (IOException e) { 
        e.printStackTrace(); 
        mIsSocketInstanceCreated = false; 
       } 
       return null; 
      } 
     }.execute(); 
} 

    public boolean isConnected() { 
     if (mIsSocketInstanceCreated) 
      return mSocket.isConnected(); 
     return false; 
    }