Я запутался в том, как я могу что-то добиться и как это сделать, поскольку я считаю, что существует более одного метода;
У меня есть приложение, и в начале он устанавливает TCP-соединение с сервером, а затем время от времени делает вид, что вы нажимаете кнопку и отправляете строку на сервер. На самом деле соединение (я использовал java.net.Socket) должно запускаться в отдельном потоке из основного потока пользовательского интерфейса (который находится там, где он в настоящее время).
У меня есть общедоступный метод, поэтому, когда нажимается кнопка, вызывается метод и данные отправляются, но снова это выполняется из основного потока пользовательского интерфейса. Поскольку соединение является постоянным на протяжении всего жизненного цикла приложения, оно должно, вероятно, быть услугой намерения, но можете ли вы использовать метод вызова в службе намерения для отправки данных на заднюю землю по обратному соединению?
Или служба, которая соединяет сокет в методе onStart(), а затем внутри службы реализует asynctask? Я потерян!
Вы можете использовать synchronized
для выполнения, например (и это просто царапина, конечно, без обработки каких-либо исключений):
public class SyncedTcpClient extends Thread{
synchronized boolean new_data_available = false;
String _data = null;
public void run()
{
Socket s = new Socket("127.0.0.1", 3000);
while(1)
{
synchronized(this)
{
if(new_data_available)
{
// send data
new_data_available = false;
}
else
{
wait();
}
}
}
}
public void setData(String data)
{
_date = data;
new_data_available = true;
}
}
И в вашей активности (MyActivity.java) вы добавляете:
OnClickListener myListener = new OnClickListener(){
public void onClick(View v) {
tcpThread.setData(data_to_send);
tcpThread.notify();
}
};
после установления соединения клиент проверяет наличие новых данных для отправки, а если нет, он будет ждать уведомления. Кроме того, вы можете найти этот вопрос полезным
EDIT: Поскольку это слишком много для комментария, я отредактировал свой ответ.
Вам нужно запустить поток tcpClient откуда-то, правильно? Так сделайте это от вашей деятельности. Таким образом, у вас будет объект потока (как мы его использовали в myListener
). в отношении notify()
- это бессмысленно, когда мы не говорим о потоках (если я ошибаюсь, пожалуйста, меня кто-то исправит), и цель - "освободить" потоки, которые ждут из-за того, что один и тот же объект продолжит выполнение, в этом случае это сам клиентский поток (synchronized(this)
), поэтому мы говорим ему продолжить, и как раз перед этим мы меняем условие в цикле как true (в методе setData(String)
), чтобы он теперь отправил данные, и снова войдите в режим ожидания.
Вы можете использовать AsyncTask. Внутри вашей функции doInBackground вы будете отправлять свои данные, получать ответ и т.д. Это освободит поток пользовательского интерфейса. В onPostExecute вы можете обновить поток пользовательского интерфейса с результатами фоновой задачи.