Android Service类中的哪里停止/销毁线程?

我通过以下方式创建了线程服务:

public class TCPClientService extends Service{  

...

@Override

public void onCreate() {

...

Measurements = new LinkedList<String>();

enableDataSending();

}

@Override

public IBinder onBind(Intent intent) {

//TODO: Replace with service binding implementation

return null;

}

@Override

public void onLowMemory() {

Measurements.clear();

super.onLowMemory();

}

@Override

public void onDestroy() {

Measurements.clear();

super.onDestroy();

try {

SendDataThread.stop();

} catch(Exception e){

...

}

}

private Runnable backgrounSendData = new Runnable() {

public void run() {

doSendData();

}

};

private void enableDataSending() {

SendDataThread = new Thread(null, backgrounSendData, "send_data");

SendDataThread.start();

}

private void addMeasurementToQueue() {

if(Measurements.size() <= 100) {

String measurement = packData();

Measurements.add(measurement);

}

}

private void doSendData() {

while(true) {

try {

if(Measurements.isEmpty()) {

Thread.sleep(1000);

continue;

}

//Log.d("TCP", "C: Connecting...");

Socket socket = new Socket();

socket.setTcpNoDelay(true);

socket.connect(new InetSocketAddress(serverAddress, portNumber), 3000);

//socket.connect(new InetSocketAddress(serverAddress, portNumber));

if(!socket.isConnected()) {

throw new Exception("Server Unavailable!");

}

try {

//Log.d("TCP", "C: Sending: '" + message + "'");

PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);

String message = Measurements.remove();

out.println(message);

Thread.sleep(200);

Log.d("TCP", "C: Sent.");

Log.d("TCP", "C: Done.");

connectionAvailable = true;

} catch(Exception e) {

Log.e("TCP", "S: Error", e);

connectionAvailable = false;

} finally {

socket.close();

announceNetworkAvailability(connectionAvailable);

}

} catch (Exception e) {

Log.e("TCP", "C: Error", e);

connectionAvailable = false;

announceNetworkAvailability(connectionAvailable);

}

}

}

...

}

关闭应用程序后,电话的工作速度非常慢,我猜这是由于线程终止失败引起的。

有谁知道在终止应用程序之前终止所有线程的最佳方法是什么?

回答:

Android框架为一次性工作,后台工作等提供了许多帮助程序,与在许多情况下尝试滚动自己的线程相比,它们可能更可取。如下面的文章所述,AsyncTask是一个很好的起点。我鼓励读者在开始考虑自己编写线程之前先研究一下框架规定。

您发布的代码示例中有几个问题,我将按顺序解决:

1)Thread.stop()已被弃用一段时间,因为在某些情况下,它可能会使因变量处于不一致状态。有关更多详细信息,请参见此Sun答案页面(编辑:该链接现在已失效,对于为何不使用Thread.stop()的信息,请参见此页面)。停止和启动线程的首选方法如下(假设您的线程将无限期地运行):

private volatile Thread runner;

public synchronized void startThread(){

if(runner == null){

runner = new Thread(this);

runner.start();

}

}

public synchronized void stopThread(){

if(runner != null){

Thread moribund = runner;

runner = null;

moribund.interrupt();

}

}

public void run(){

while(Thread.currentThread() == runner){

//do stuff which can be interrupted if necessary

}

}

这只是如何停止线程的一个示例,但总的来说,您有责任像退出其他任何方法一样退出线程。维护跨线程通信的方法(在这种情况下为易失性变量,也可以通过互斥锁等),并在线程逻辑内,使用该通信方法检查是否应及早退出,清理等。

2)您的度量值列表可以同时被多个线程(事件线程和用户线程)访问,而不会进行任何同步。看起来您不必进行自己的同步,可以使用BlockingQueue。

3)您将在发送线程的每次迭代中创建一个新的Socket。这是一项相当繁重的操作,并且只有在您希望很少进行测量(例如每小时一小时或更短)的情况下才有意义。您需要一个不会在线程的每个循环中都重新创建的持久套接字,或者想要一个可运行的快照,可以“触发并忘记”它创建一个套接字,发送所有相关数据并完成操作。(有关使用持久套接字的快速说明,阻塞的套接字方法(例如读取)不能被Thread.interrupt()中断,因此,当您要停止线程时,必须关闭套接字并调用中断)

4)从线程内引发您自己的异常没有什么意义,除非您希望将其捕获到其他地方。更好的解决方案是记录该错误,如果无法恢复,则停止线程。线程可以使用以下代码停止自身(在与上述相同的上下文中):

public void run(){

while(Thread.currentThread() == runner){

//do stuff which can be interrupted if necessary

if(/*fatal error*/){

stopThread();

return; //optional in this case since the loop will exit anyways

}

}

}

最后,如果要确保线程随应用程序的其余部分一起退出,那么不管怎样,一种好的方法是在创建线程之后和启动线程之前调用Thread.setDaemon(true)。这会将线程标记为守护程序线程,这意味着如果没有非守护程序线程正在运行(例如,如果您的应用程序退出),则VM将确保将其自动销毁。

遵循关于线程的最佳实践应确保您的应用不会挂起或降低电话速度,尽管它们可能非常复杂:)

以上是 Android Service类中的哪里停止/销毁线程? 的全部内容, 来源链接: utcz.com/qa/427266.html

回到顶部