2015-09-29 23 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; 
    }