服务问题中的Android线程
Posted
技术标签:
【中文标题】服务问题中的Android线程【英文标题】:Android thread in service issue 【发布时间】:2011-07-30 15:45:31 【问题描述】:我正在运行一个远程服务,其中我正在生成一个新线程以继续轮询通过套接字传入的消息,然后每隔一段时间我想停止套接字并稍后重新启动...停止工作正常(stopUARTConnection( )) 但重新启动(startUARTConnection) 不会再次导致 while 循环。有人可以告诉我有什么问题吗?
public class BackgroundService extends Service
ServerSocket server = null;
Socket socketClient = null;
InputStream is = null;
BufferedReader br = null;
char[] buff = null;
boolean threadRunning = true;
private static final String TAG = BackgroundService.class.getSimpleName();
private Thread socketThread = null;
int temp = 0;
@Override
public IBinder onBind(Intent intent)
if (BackgroundService.class.getName().equals(intent.getAction()))
Log.d(TAG, "Bound by intent " + intent);
return apiEndpoint;
else
return null;
private final Object latestIncomingMessage = new Object();
private List<MessageCollectorListener> listeners = new ArrayList<MessageCollectorListener>();
private Message message = new Message(" ");
private MessageCollectorApi.Stub apiEndpoint = new MessageCollectorApi.Stub()
@Override
public void removeListener(MessageCollectorListener listener) throws RemoteException
synchronized (listener)
listeners.remove(listener);
@Override
public Message getValue() throws RemoteException
synchronized (latestIncomingMessage)
return message;
@Override
public void addListener(MessageCollectorListener listener) throws RemoteException
synchronized (listener)
listeners.add(listener);
@Override
public void startBroadCastConn() throws RemoteException
try
startUARTConnection();
catch (IOException e)
Log.d("B Service", "Stop UART CONNECTION");
@Override
public void stopBroadCastConn() throws RemoteException
try
stopUARTConnection();
catch (IOException e)
Log.d("B Service", "Stop UART CONNECTION");
;
public boolean createSocket(int port)
try
server = new ServerSocket(port);
catch (IOException e)
return false;
return true;
public boolean listenSocket()
try
socketClient = server.accept();
catch (IOException e)
return false;
return true;
@Override
public void onCreate()
super.onCreate();
socketThread = new Thread()
@Override
public void run()
while(threadRunning)
boolean socketCreated = createSocket(8080);
boolean socketListen = listenSocket();
if(socketListen == true && socketCreated == true)
//To add code for processing data..
threadRunning = true;
try
recycle();
catch (IOException e)
//e.printStackTrace();
;
socketThread.start();
public void stopUARTConnection() throws IOException
recycle();
threadRunning = false;
public void startUARTConnection() throws IOException
recycle();
threadRunning = true;
private void recycle() throws IOException
if(socketClient != null)
socketClient.close();
socketClient = null;
if(is != null)
is.close();
if(server != null)
server.close();
server = null;
@Override
public void onDestroy()
super.onDestroy();
try
recycle();
catch (IOException e)
Log.d("B Service", "Failed to recycle all values");
socketThread = null;
【问题讨论】:
【参考方案1】:当您调用 stopUARTConnection 时,您正在设置 threadRunning=false...此时,您的 while 循环正在退出...在 startUARTConnection 中,您将 threadRunning 设置为 true,但您没有重新启动线程。
正如@Marvin 指出的,you can't just call start on the thread object,您需要重新创建它。
【讨论】:
-1 因为您无法启动已经启动过一次的线程。第二次调用 startUARTConnection 时会抛出 IllegalThreadStateException。 听说我必须在重新开始之前销毁该线程..我们可以通过分配 thread = null 来销毁吗? ??? @Arun Abraham:请参阅 Marvin 的回复。您不必销毁线程(它会退出),您可以在现有引用上创建一个新的 @MarvinLabs:感谢您的指点。我不知道您无法重新启动线程对象,我假设它进入退出状态就可以了。我想这不是我需要做的事情,通常如果我启动一个线程,我不希望在应用程序准备退出之前将其关闭。 始终明确关闭您启动的线程,否则它们将继续在后台运行,您会泄漏内存...【参考方案2】:您只创建一次线程。因此,循环只运行一次,直到被指示退出。
public void startUARTConnection() throws IOException
recycle();
socketThread = new SocketThread();
socketThread.start();
public void stopUARTConnection() throws IOException
recycle();
socketThread = null;
private class SocketThread extends Thread
@Override
public void run()
// Loop until socketThread is assigned something else
// (a new Thread instance or simply null)
while (socketThread==this)
boolean socketCreated = createSocket(8080);
boolean socketListen = listenSocket();
if(socketListen == true && socketCreated == true)
// To add code for processing data..
try
recycle();
catch (IOException e)
//e.printStackTrace();
;
【讨论】:
hmmm...看起来不错...但是我们是否应该在重新开始之前销毁线程...我应该将线程分配给 null 来执行它吗?socketThread==this
会检测到你创建了一个新的 SocketThread,然后旧的 Thread 会退出。如果您需要确保没有同时运行 2 个线程,则需要基于 join()
实施检查。
嘿....非常感谢...您的解决方案是正确的..非常感谢..对线程真的很陌生...:)
@Arun Abraham:如果马文解决了你的问题,你真的应该接受这个答案......【参考方案3】:
我认为最好使用 TimerTask 而不是 thread/while 和 ConditionVariable 而不是布尔变量 threadRunning
【讨论】:
以上是关于服务问题中的Android线程的主要内容,如果未能解决你的问题,请参考以下文章