как это должно быть сделано? (Андроид)

1

Я запутался в том, как я могу что-то добиться и как это сделать, поскольку я считаю, что существует более одного метода;

У меня есть приложение, и в начале он устанавливает TCP-соединение с сервером, а затем время от времени делает вид, что вы нажимаете кнопку и отправляете строку на сервер. На самом деле соединение (я использовал java.net.Socket) должно запускаться в отдельном потоке из основного потока пользовательского интерфейса (который находится там, где он в настоящее время).

У меня есть общедоступный метод, поэтому, когда нажимается кнопка, вызывается метод и данные отправляются, но снова это выполняется из основного потока пользовательского интерфейса. Поскольку соединение является постоянным на протяжении всего жизненного цикла приложения, оно должно, вероятно, быть услугой намерения, но можете ли вы использовать метод вызова в службе намерения для отправки данных на заднюю землю по обратному соединению?

Или служба, которая соединяет сокет в методе onStart(), а затем внутри службы реализует asynctask? Я потерян!

Теги:
asynchronous
task
service
android-intent

2 ответа

1
Лучший ответ

Вы можете использовать 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)), чтобы он теперь отправил данные, и снова войдите в режим ожидания.

  • 0
    Так что это бесконечный цикл, если есть данные, которые он будет отправлять, а если нет, он будет просто зацикливаться. Значит ли это, что при запуске моего приложения я могу запустить его, затем оно будет работать в течение всего срока службы моего приложения, постоянно проверяя, есть ли данные для отправки и, если есть, отправлять их?
  • 0
    Да. Но учтите, что если нет данных для отправки, они не будут зацикливаться, а вместо этого будут ждать продолжения уведомления.
Показать ещё 4 комментария
0

Вы можете использовать AsyncTask. Внутри вашей функции doInBackground вы будете отправлять свои данные, получать ответ и т.д. Это освободит поток пользовательского интерфейса. В onPostExecute вы можете обновить поток пользовательского интерфейса с результатами фоновой задачи.

  • 0
    Ну, как я думал об использовании AsyncTask для отправки данных, но это должен быть AsyncTask внутри службы или IntentService, возможно ли это? Кроме того, как я мог назвать это из другого класса?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню