Я использую AsyncTask для установления TCP-соединения и отправки / получения данных через него.
Мой текущий код выглядит сейчас так:
public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
Socket nsocket; //Network Socket
InputStream nis; //Network Input Stream
OutputStream nos; //Network Output Stream
boolean bSocketStarted = false;
byte[] buffer = new byte[4096];
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
@Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
// Connect to address
Log.i(TAG, "doInBackground: Creating socket");
SocketAddress sockaddr = new InetSocketAddress("google.de", 80);
nsocket = new Socket();
nsocket.connect(sockaddr, 5000); //10 second connection timeout
if (nsocket.isConnected()) {
bSocketStarted = true;
nis = nsocket.getInputStream();
nos = nsocket.getOutputStream();
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
int read = nis.read(buffer, 0, 4096); //This is blocking
while(bSocketStarted) {
if (read > 0){
byte[] tempdata = new byte[read];
System.arraycopy(buffer, 0, tempdata, 0, read);
publishProgress(tempdata);
Log.i(TAG, "doInBackground: Got some data");
}
}
}
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "doInBackground: IOException");
result = true;
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "doInBackground: Exception");
result = true;
} finally {
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, "doInBackground: Finished");
}
return result;
}
public boolean SendDataToNetwork(final byte[] cmd) { //You run this from the main thread.
// Wait until socket is open and ready to use
waitForSocketToConnect();
if (nsocket.isConnected()) {
Log.i(TAG, "SendDataToNetwork: Writing received message to socket");
new Thread(new Runnable() {
public void run() {
try {
nos.write(cmd);
}
catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "SendDataToNetwork: Message send failed. Caught an exception");
}
}
}
).start();
return true;
}
else
Log.i(TAG, "SendDataToNetwork: Cannot send message. Socket is closed");
return false;
}
public boolean waitForSocketToConnect() {
// immediately return if socket is already open
if (bSocketStarted)
return true;
// Wait until socket is open and ready to use
int count = 0;
while (!bSocketStarted && count < 10000) {
try {
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
count += 500;
}
return bSocketStarted;
}
@Override
protected void onProgressUpdate(byte[]... values) {
try {
if (values.length > 0) {
Log.i(TAG, "onProgressUpdate: " + values[0].length + " bytes received.");
String str = new String(buffer, "UTF8");
Log.i(TAG,str);
tv.setText(str);
tv.setMovementMethod(new ScrollingMovementMethod());
}
} catch (Exception e) {
e.printStackTrace();
}
finally {}
}
@Override
protected void onCancelled() {
Log.i(TAG, "Cancelled.");
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
Log.i(TAG, "onPostExecute: Completed with an Error.");
} else {
Log.i(TAG, "onPostExecute: Completed.");
}
}
}
Я могу создать экземплярЗадача и звонок SendDataToNetwork
из моей деятельности.Однако весь текст, который я передаю в SendDataToNetwork, например, «GET / HTTP / 1.1», постоянно отправляется на сервер.
Как я могу изменить свой код, чтобы поддерживать соединение в doInBackground
и ничего не делать, пока я не вызову SendDataToNetwork
и после отправки байтов на сервер просто подождите, пока новые данные не будут готовы к отправке?По сути, я хочу запустить AsyncTask, пока я не отменю (= закрою соединение) его.