Это выглядит просто, но я думаю, у вас есть интересная и сложная проблема. Если вы хотите сохранить сокет открытым после отправки сообщений через него, вам нужно будет поддерживать один или несколько потоков для использования этого сокета, потому что, как вы знаете, Android не разрешает создавать сети в основном потоке.
Многопоточное программирование редко бывает простым и часто существует несколько способов сделать это. Например. в Android вы можете использовать Handler
s с Looper
s от HandlerThread
s или классической Java Thread
. А также AsyncTask
, но я думаю, что это не подходит для этого случая.
Как вы собираетесь управлять жизненным циклом сокета (т. Е. Когда он открыт или закрыт), и в каких моментах данные считываются/записываются из/в сокет? Пожалуйста, объясните лучше, поэтому я могу предложить реализацию.
EDIT
Вот пример Activity
с двумя кнопками. Одна кнопка запускает AsyncTask
, которая создает сокет и его потоки, а другая кнопка запускает еще один AsyncTask
, который записывает данные в сокет. Это упрощенное решение, но оно должно работать. Обратите внимание, что для этого кода требуется синхронизации, для разных потоков доступ к сокету.
public class MainActivity extends Activity {
private SocketContainer mSocketContainer;
private final Object mSocketContainerLock = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// onClick attribute of one button.
public void onClickPushMe(View view) {
String serverAddress;
int serverPort;
new CreateSocketAsyncTask(serverAddress, serverPort).execute();
}
// onClick attribute of other button.
public void onClickPushMeToo(View view) {
String text;
new WriteSocketAsyncTask(text).execute();
}
// Class that contains the socket and its streams,
// so they can be passed from one thread to another.
private class SocketContainer {
private Socket mSocket;
private InputStream mSocketInputStream;
private OutputStream mSocketOutputStream;
private SocketContainer(Socket socket, InputStream socketInputStream, OutputStream socketOutputStream) {
mSocket = socket;
mSocketInputStream = socketInputStream;
mSocketOutputStream = socketOutputStream;
}
private Socket getSocket() {
return mSocket;
}
private InputStream getSocketInputStream() {
return mSocketInputStream;
}
private OutputStream getSocketOutputStream() {
return mSocketOutputStream;
}
}
// AsyncTask that creates a SocketContainer and sets in into MainActivity.
private class CreateSocketAsyncTask extends AsyncTask<Void, Void, SocketContainer> {
private final String mServerAddress;
private final int mServerPort;
private CreateSocketAsyncTask(String serverAddress, int serverPort) {
mServerAddress = serverAddress;
mServerPort = serverPort;
}
protected SocketContainer doInBackground(Void... params) {
try {
Socket socket = new Socket(mServerAddress, mServerPort);
return new SocketContainer(socket, socket.getInputStream(), socket.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void onPostExecute(SocketContainer socketContainer) {
super.onPostExecute(socketContainer);
synchronized (mSocketContainerLock) {
mSocketContainer = socketContainer;
}
}
}
private class WriteSocketAsyncTask extends AsyncTask<Void, Void, Void> {
private final String mText;
private WriteSocketAsyncTask(String text) {
mText = text;
}
@Override
protected Void doInBackground(Void... params) {
synchronized (mSocketContainerLock) {
try {
mSocketContainer.getSocketOutputStream().write(mText.getBytes(Charset.forName("UTF-8")));
mSocketContainer.getSocketOutputStream().flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return null;
}
}
}
я обновил свой ответ, пожалуйста, посмотрите – nandsito