2016-03-15 3 views
0

Я пытаюсь реализовать интерфейс REST в android, и мне нужен поток в фоновом режиме, отправляющий сообщения «Я жив» на ip-адрес. Для этого я создал вызванный поток RestPostThread, который работает в фоновом режиме, пока я делаю что-то в своем потоке пользовательского интерфейса.Android-обработчик отправляет только одно сообщение

Проблема в том, что после отправки первого сообщения в RestPostThread я не могу выйти из петлителя или отправить ему другое сообщение с другим IP-адресом или чем-то другим.

Вот код как для пользовательского интерфейса и RestPostThread:

public class MainActivity extends AppCompatActivity{ 

Handler workerThreadHandler; 


protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    final TextView text1 = (TextView) findViewById(R.id.text1); 
    final TextView text2 = (TextView) findViewById(R.id.text2); 
    setSupportActionBar(toolbar); 


    final RestPostThread RPT = new RestPostThread(); 
    RPT.start(); 

    while(workerThreadHandler == null) { 
     workerThreadHandler = RPT.getThreadHandler(); 
    } 

    Button buttonStop = (Button) findViewById(R.id.buttonStop); 
    buttonStop.setOnClickListener(new View.OnClickListener(){ 
     public void onClick(View view) { 
      try { 



       workerThreadHandler.getLooper().quit(); 
      }catch(Exception e){ 
       text1.setText(e.getMessage()); 
       text2.setText("Exception!"); 
      } 

     } 
    }); 

    Button buttonSend = (Button) findViewById(R.id.buttonSend); 
    buttonSend.setOnClickListener(new View.OnClickListener(){ 
     public void onClick(View view) { 
      try { 
       text1.setText(new RestGet().execute(editText.getText().toString()).get()); 
       text2.setText("everything went well!"); 
      }catch(Exception e){ 
       text1.setText(e.getMessage()); 
       text2.setText("Exception!"); 
      } 

     } 
    }); 
} 

А вот код для RestPostThread:

public class RestPostThread extends Thread { 
public Handler mHandler; 

@Override 
public void run(){ 

    Looper.prepare(); 
    mHandler = new Handler() { 
     public void handleMessage(Message msg) { 
      Log.d("MYASDASDPOASODAPO", "dentro mensaje"); 
      while (!msg.obj.equals(null)) { 
       try { 
        Thread.sleep(1000); 
        URL url = new URL(msg.obj.toString()); 
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
        conn.setDoOutput(true); 
        conn.setRequestMethod("POST"); 
        String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>"; 

        OutputStream os = conn.getOutputStream(); 
        os.write(input.getBytes()); 
        os.flush(); 

        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) { 
         // throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); 
        } 
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); 
        String output; 
        String aux = new String(); 
        while ((output = br.readLine()) != null) { 
         aux = aux + output; 
        } 
        conn.disconnect(); 
        //return aux; 
       } catch(MalformedURLException e) { 
        e.printStackTrace(); 
        //return null; 
       } catch(IOException e) { 
        e.printStackTrace(); 
        //return null; 
       } catch(Exception e) { 
       } 
      } 
      Log.d("CLOSING MESSAGE", "Closing thread"); 
     } 
    }; 
    Looper.loop(); 
} 

public Handler getThreadHandler() { 
    return this.mHandler; 
} 
+0

Так что конкретно вопрос? –

+0

Извините, я написал can и я имел в виду, что не могу: «Я не могу выйти из петлителя или отправить ему другое сообщение с другим IP-адресом или что-то в этом роде». – Hart

+0

Извините, если его отключить, но очень легко узнать, как использовать библиотеку, например «Дооснащение», http://square.github.io/retrofit, чем работать с сетью с помощью фоновых задач. – Shailesh

ответ

0

Мне удалось решить проблему. Проблема заключалась в том, что я обмотать все внутри этого:

while (!msg.obj.equals(null)) {} 

Я реализовал обработчик как в этом потоке и в потоке пользовательского интерфейса, и теперь у меня есть связь назад и вперед между обеими, моим RestPostThread будет выглядеть так:

public class RestPostThread extends Thread { 

public Handler mHandler,uiHandler; 


public RestPostThread(Handler handler) { 
    uiHandler = handler; 
} 

@Override 
public void run(){ 
    Looper.prepare(); 
    mHandler = new Handler() { 
     public void handleMessage(Message msg) { 
       try { 
        //Thread.sleep(1000); 
        URL url = new URL(msg.obj.toString()); 
        HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
        conn.setDoOutput(true); 
        conn.setRequestMethod("POST"); 
        String input = "<Instruction><type>put_me_in</type><room>Room 1</room></Instruction>"; 

        OutputStream os = conn.getOutputStream(); 
        os.write(input.getBytes()); 
        os.flush(); 

        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) { 
         // throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); 
        } 
        BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); 
        String output; 
        String aux = new String(); 
        while ((output = br.readLine()) != null) { 
         aux = aux + output; 
        } 
        conn.disconnect(); 
        Message msg2 = uiHandler.obtainMessage(); 
        msg2.obj = aux; 
        uiHandler.sendMessage(msg2); 
       }catch(MalformedURLException e){ 
        e.printStackTrace(); 
       }catch(IOException e){ 
        e.printStackTrace(); 
       }catch(Exception e){ 
       } 
      } 
    }; 
    Looper.loop(); 
} 


public Handler getThreadHandler() { 
    return this.mHandler; 
} 

}

и в моем MainActivity у меня есть этот обработчик, который позволяет мне «петля» (в основном только собирается туда и обратно между RestPostThread и UIThread) мое сообщение сообщение, пока я не решу, чтобы остановить от MainActivity меняет boolean loop:

public Handler uiHandler = new Handler() { 
    public void handleMessage(Message inputMessage) { 
     Log.d("FROM UI THREAD",inputMessage.obj.toString()); 
     if(loop) { 
      Message msg = workerThreadHandler.obtainMessage(); 
      String url = "http://192.168.1.224:9000/xml/android_reply"; 
      msg.obj = url; 
      workerThreadHandler.sendMessageDelayed(msg,1000); 
     } 
    } 
}; 
0

Посмотрите HandlerThread для борьбы с потоком до обрабатывать только сообщения. Ваш Handler не должен зацикливаться на таком сообщении, это не сработает. Это работа Looper, чтобы иметь дело с новыми, входящими Message или Runnable объектами, отправленными на Handler, который связан с Looper.

Независимо от этого, вы должны более подробно рассмотреть использование Loader для обработки API типа REST; или, изучите стороннюю библиотеку, такую ​​как модификация, для работы с REST.

+0

Я думаю, что Loader не лучший подход для REST. Он предназначался для загрузки данных из поставщиков контента. –

+0

Нет, это фактически предназначено для любой операции асинхронного типа, когда вы загружаете данные. Однако инфраструктура предоставляется только «CursorLoader». Вы можете использовать базовый класс «AsyncLoader» для создания ваших собственных загрузчиков REST. Они на самом деле работают достаточно хорошо, потому что они знают жизненный цикл, в отличие от «AsyncTask», и они запускаются в фоновом потоке. –

+0

Я посмотрел на HandlerThread, но не могу понять, как взаимодействовать между потоком пользовательского интерфейса и HandlerThread, также мне нужен поток POST, который будет постоянно размещаться в фоновом режиме, и я не знаю, как это сделать без цикла. – Hart

Смежные вопросы