2016-03-15 61 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

相关问题