简体   繁体   English

循环线程

[英]Looping a Thread

In my android application I would like to continuously read incoming data (using Telnet protocol). 在我的Android应用程序中,我想连续读取传入的数据(使用Telnet协议)。 I am able to read one line (and then the app runs at idle), and I'm wondering how to create a simple endless main loop. 我能够读取一行(然后该应用程序在空闲状态下运行),并且我想知道如何创建一个简单的无尽主循环。

I think it would make sense to put a loop around this line: 我认为绕这条线循环是有意义的:

telnetThread.start();

I already tried to implement a looper, but without any success. 我已经尝试实现一个循环程序,但没有成功。

This is my code: 这是我的代码:

package com.example.clienttel;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;

import org.apache.commons.net.telnet.TelnetClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainActivity extends ActionBarActivity {
    // Variables
    public final String ADDRESS = "194.66.82.11";
    public final int PORT = 50100;
    public String NMEA = null;
    public final String TAG = "TestApp";
    public boolean first = true;
    public MyTelnetClass mtc;
    public Thread telnetThread;

    // Handler in mainthread
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            String dataString = "";
            Bundle bundle = msg.getData();

            Log.d("handleMessage", bundle.toString());
            if (bundle.containsKey("outgoingString")) {
                dataString = bundle.getString("outgoingString");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        createThread();
    }

    private void createThread() {
        final Runnable runnable = new Runnable() {
            public void run() {
                try {
                    mtc = new MyTelnetClass();
                    mtc.mhandler = handler;
                    mtc.run();

                    Bundle b = new Bundle();
                    b.putString("TCPThread", "visible");
                    Message m = handler.obtainMessage();
                    m.setData(b);
                    handler.sendMessage(m);
                } catch (Exception e) {
                    Log.e("createTCPThread", "exception: " + e.getMessage());
                    Bundle b = new Bundle();
                    b.putString("TCPThread", "unvisible");
                    Message m = handler.obtainMessage();
                    m.setData(b);
                    handler.sendMessage(m);
                }
            }
        };
        // create the thread needed and run it, LOOP HERE?
        telnetThread = new Thread(runnable);
        telnetThread.start();
    }

    // catch NMEA-sentences and send them using mhandler
    class MyTelnetClass {
        public Handler mhandler = null;

        public void run() {
            TelnetClient telnet = new TelnetClient();
            Log.i(TAG, "telnetThread active");
            if (first) {
                // Connect To Server in 1st Iteration
                try {
                    telnet.connect(ADDRESS, PORT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                first = false;
            }

            // Process NMEA-sentences
            InputStream inStream = telnet.getInputStream();
            BufferedReader r = new BufferedReader(new InputStreamReader(inStream));

            try {
                NMEA = r.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            // Handler in MyTelnetClass to send back
            Bundle b = new Bundle();
            b.putString("outgoingString", NMEA);

            Message m = mhandler.obtainMessage();
            m.setData(b);
            mhandler.sendMessage(m);
        }
    }
}

What would be an efficient way to handle that? 什么是处理该问题的有效方法?

EDIT: 编辑:

I put the looper "around" the run(), but it just executes once (I'm not sure if the loop can work this way): 我将循环程序放在run()周围,但是它只执行一次(我不确定循环是否可以这种方式工作):

public void run() {
                try {
                    Looper.prepare(); // HERE...

                    Log.d(TAG,"executing run");
                    mtc = new MyTelnetClass();
                    mtc.mhandler = handler;
                    mtc.run();

                    Bundle b = new Bundle();
                    b.putString("TCPThread", "visible");
                    Message m = handler.obtainMessage();
                    m.setData(b);
                    handler.sendMessage(m);

                    Looper.loop(); // ...AND HERE
                } catch (Exception e) {
                    Log.e("createTCPThread", "exception: " + e.getMessage());
                    Bundle b = new Bundle();
                    b.putString("TCPThread", "unvisible");
                    Message m = handler.obtainMessage();
                    m.setData(b);
                    handler.sendMessage(m);
                }
            }

you have created a thread, this is the start for you but it will run once. 您已经创建了一个线程,这是您的开始,但是它将运行一次。 if you want him to run in a loop you need to put loop. 如果您希望他循环运行,则需要放置循环。 the loop need to be in the run() method, from the start to it's end, or as much as you need of it. 循环需要从头到尾都在run()方法中,也可以根据需要使用。

if you write a loop where you commended it will be a waste of time(/memory) and not effective, it will create the same thread over and over. 如果您在一个值得赞扬的地方写了一个循环,那会浪费时间(/内存),而且效果不好,它将一遍又一遍地创建相同的线程。 if you do it where the telnetThread.start(); 如果您在telnetThread.start(); is, it will cause to tons of thread and they all will run in about the same time. 是,这将导致大量线程,并且它们都将在大约同一时间运行。

if you do it in the run() function it will run infinite times (unless you have a condition) and will run only after the last run of the loop ended. 如果在run()函数中执行此操作,它将无限次运行(除非有条件),并且仅在循环的最后一次运行结束后才运行。

try the follow code: 尝试以下代码:

   {
                new Thread () {
                    public void run() {
                        Message msg = Message.obtain();
                        msg.what=1;         
                        try {
                            openTelnetConnection(url, mmsgH); 
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();                        }                                                                                       
                            }
                }.start();         
            }
        private void openTelnetConnection(String urlStr, Handler mhandler) throws IOException {
            ProtocolConnection protConn = null;
            String line = null;
            try {

                // Get your CONNECTION
                BufferedReader is =
                        new BufferedReader(new InputStreamReader(protConn.getInputStream()));                   

                while ((line = is.readLine( )) != null) {

                        Message msg = Message.obtain();
                        msg.what=1;  
                        msg.obj=line;                       
                        mhandler.sendMessage(msg);
                }               
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch( SocketTimeoutException e){
                e.printStackTrace();
            } catch (IOException e) {
                Log.d(TAG, "IOERR " +e);
                e.printStackTrace();
                Message msg = Message.obtain();
                    msg.what=2;
                    BufferedInputStream in = new BufferedInputStream(httpConn.getErrorStream());            
                    line =new String(readStream(in));
                    msg.obj=line;
                    mhandler.sendMessage(msg);                
            }
            finally {protConn.disconnect();}
        }

As @ChrisStratton and @amitfarag said, a simple while() -loop did exactly what I required. 正如@ChrisStratton和@amitfarag所说,一个简单的while() loop确实满足了我的要求。 No need for loopers in my case: 在我的情况下,不需要弯针:

while (true) {
                    try {
                        mtc = new MyTelnetClass();
                        mtc.mhandler = handler;
                        mtc.run();

                        Bundle b = new Bundle();
                        b.putString("TCPThread", "visible");
                        Message m = handler.obtainMessage();
                        m.setData(b);
                        handler.sendMessage(m);
                    } catch (Exception e) {
                        Log.e("createTCPThread", "exception: " + e.getMessage());
                        Bundle b = new Bundle();
                        b.putString("TCPThread", "unvisible");
                        Message m = handler.obtainMessage();
                        m.setData(b);
                        handler.sendMessage(m);
                        e.printStackTrace();
                    }

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

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