2016-03-15 94 views
0

我想在android中實現一個REST接口,我需要一個線程在後臺發送「我活着」消息到一個IP地址。要做到這一點,我創建了一個線程調用RestPostThread在後臺運行,而我在我的UI線程中做東西。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

對不起,我寫了可以,我的意思是不能在「我不能退出活套或用另一個IP或其他東西發送不同的消息。」 – Hart

+0

對不起,如果它的題外話,但它很容易學習如何使用像Retrofit,http://square.github.io/retrofit庫比處理網絡與後臺任務。 – Shailesh

回答

0

我設法解決了這個問題。問題是,我是包裝紙這裏面的一切:

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

我都這個線程和UI線程執行的處理程序,現在我有通信來回在兩者之間,我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更改布爾循環:

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的工作,以處理髮送到Handler的新的傳入MessageRunnable對象,該對象綁定到Looper

無論如何,你應該仔細看看使用Loader來處理REST類型的API;或者,探索第三方庫,如改造,以處理REST。

+0

我認爲Loader不是最好的方法REST。它旨在從內容提供商加載數據。 –

+0

不是,它實際上是用於加載數據的任何異步類型操作。但是,框架只提供'CursorLoader'。您可以基於'AsyncLoader'基類來創建您自己的REST加載器。它們實際上工作得很好,因爲它們具有生命週期感知能力,與'AsyncTask'不同,它們在後臺線程上運行。 –

+0

我看着HandlerThread,但我無法弄清楚如何在UI線程和HandlerThread之間進行通信,也需要POST線程在後臺不斷髮布,我不知道如何在沒有循環的情況下這樣做。 – Hart