简体   繁体   English

Android处理程序仅发送一条消息

[英]Android handler only sends one message

I am trying to implement a REST interface in android and I need a Thread in the background sending "I am alive" messages to an ip address. 我正在尝试在android中实现REST接口,并且需要在后台将“我还活着”消息发送到ip地址的线程。 To do so I created a Thread Called RestPostThread that runs in the background while I do stuff in my UI thread. 为此,我创建了一个名为RestPostThread的线程,该线程在UI线程中执行操作时在后台运行。

The problem is that after sending the first message to the RestPostThread I can't quit the looper or send a different message to it with another IP or something. 问题是,在将第一条消息发送到RestPostThread之后,我无法退出循环程序或使用其他IP或其他内容向其发送不同的消息。

Here are the code for both the UI and the RestPostThread: 这是UI和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!");
            }

        }
    });
}

And here is the code for the RestPostThread: 这是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;
}

Have a look at HandlerThread for dealing with a thread to handle just messages. 看一下HandlerThread ,它处理一个仅处理消息的线程。 Your Handler should not loop on a message like that, it won't work. 您的Handler不应在这样的消息上循环,它不会起作用。 It's the Looper 's job to deal with new, incoming Message or Runnable objects sent to the Handler which is bound to the Looper . 这是Looper的任务,以应付新的,进入的MessageRunnable发送到目标Handler被绑定到Looper

Regardless, you should take a closer look at using a Loader to handle REST type APIs; 无论如何,您都应该仔细研究如何使用Loader处理REST类型的API。 or, explore a 3rd party library, such as retrofit, for dealing with REST. 或者,探索诸如翻新之类的第三方库来处理REST。

I managed to solve the issue. 我设法解决了这个问题。 The problem was that I was wrapping everything inside this: 问题是我将所有内容包装在其中:

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

I implemented handlers in both this thread and the UI thread and now I have communication back and forth between the both, my RestPostThread looks like this now: 我在此线程和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;
}

} }

And in my MainActivity I have this handler that allows me to "loop" (basically is just going back and forth between the RestPostThread and the UIThread) my Post message until I decide to stop from the MainActivity changing the boolean loop: 在MainActivity中,我有一个处理程序,使我可以“循环”(基本上只是在RestPostThread和UIThread之间来回)我的Post消息,直到我决定停止从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);
        }
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM