循环线程
Looping a Thread
在我的 android 应用程序中,我想连续读取传入数据(使用 Telnet 协议)。我能够读取一行(然后应用程序在空闲时运行),我想知道如何创建一个简单的无限主循环。
我认为围绕这一行设置一个循环是有意义的:
telnetThread.start();
我已经尝试实现一个循环器,但没有成功。
这是我的代码:
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);
}
}
}
处理该问题的有效方法是什么?
编辑:
我把循环程序 "around" 放在 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);
}
}
您已经创建了一个线程,这是您的开始,但它会 运行 一次。
如果你想让他 运行 循环,你需要放循环。
循环需要在 run()
方法中,从开始到结束,或者你需要多少就多少。
如果你在你推荐的地方写一个循环,那将是浪费时间(/内存)并且没有效果,它会一遍又一遍地创建相同的线程。
如果你在 telnetThread.start();
所在的位置执行此操作,它会导致大量线程,并且它们都会在大约同一时间 运行。
如果你在 run()
函数中这样做,它会 运行 无限次(除非你有条件)并且 运行 只有在最后一个 运行循环结束。
试试下面的代码:
{
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();}
}
正如@ChrisStratton 和@amitfarag 所说,一个简单的while()
循环完全满足了我的要求。在我的情况下不需要循环器:
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();
}
在我的 android 应用程序中,我想连续读取传入数据(使用 Telnet 协议)。我能够读取一行(然后应用程序在空闲时运行),我想知道如何创建一个简单的无限主循环。
我认为围绕这一行设置一个循环是有意义的:
telnetThread.start();
我已经尝试实现一个循环器,但没有成功。
这是我的代码:
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);
}
}
}
处理该问题的有效方法是什么?
编辑:
我把循环程序 "around" 放在 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);
}
}
您已经创建了一个线程,这是您的开始,但它会 运行 一次。
如果你想让他 运行 循环,你需要放循环。
循环需要在 run()
方法中,从开始到结束,或者你需要多少就多少。
如果你在你推荐的地方写一个循环,那将是浪费时间(/内存)并且没有效果,它会一遍又一遍地创建相同的线程。
如果你在 telnetThread.start();
所在的位置执行此操作,它会导致大量线程,并且它们都会在大约同一时间 运行。
如果你在 run()
函数中这样做,它会 运行 无限次(除非你有条件)并且 运行 只有在最后一个 运行循环结束。
试试下面的代码:
{
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();}
}
正如@ChrisStratton 和@amitfarag 所说,一个简单的while()
循环完全满足了我的要求。在我的情况下不需要循环器:
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();
}