Android-android 如何优雅的主动终止并等待线程的结束?

发布于 2016-10-26 17:04:45 字数 1588 浏览 1877 评论 6

这段代码用destroy终止线程,也能用,貌似还是有问题的:

private void viewOnline() {

if (currentNewsletter == null) {
Log.e(Constants.APP_NAME, "No newsletter selected");
return;
}

final ProgressDialog d = new ProgressDialog(this);
d.setMessage("Downloading...");
d.show();

final Context context = getApplicationContext();
t = new Thread(new Runnable() {
public void run() {

String fileName = currentNewsletter.mFilename;

Log.d(Constants.APP_NAME, "Downloading/showing: " + fileName);
final File file = Utilities.getFileFromURL(context, currentNewsletter.mUrl, currentNewsletter.mExpectedSizeInBytes, fileName, false);

d.dismiss();
// Now we can show the file
viewPDF(file);
}
});
t.start();

Context.MODE_WORLD_WRITEABLE).getAbsolutePath());

}

private void viewPDF(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");

try {
startActivity(intent);
} catch (Exception e) {
Toast.makeText(this, "No Application Available to View PDF", Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onStop() {
finish();
super.onStop();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
t.destroy();
Intent i = new Intent(NewslettersActivity.this,MainMenuActivity.class);

startActivity(i);
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

晚风撩人 2017-11-02 19:33:22

首先,不是有问题,是有很大的问题。。。你确定你的程序没有挂掉?
log里可见:
11-09 11:42:28.740: E/AndroidRuntime(1538): FATAL EXCEPTION: main
11-09 11:42:28.740: E/AndroidRuntime(1538): java.lang.NoSuchMethodError: Thread.destroy()

注意这个NoSuchMethodError,另外见Java API:
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#destroy%28%29
Thread.destroy()方法根本从来就没有实现过!

你在 main 线程里 调用thread1.destroy(), thread1安然无恙,你的main线程会拿到一个NoSuchMethodError(注意是Error!),除非你在main里特别去catch了这个error(一般不会有人这么干吧),main线程会直接挂掉。

用Thread.stop()也是不靠谱的,有多线程问题。

解决方法就是大家说的,1)使用volatile的标志位;2)用线程打扰机制,程序中 while(!thread.interrupted())检查;在sleep,wait的地方catch interruptedException。

《Java Concurrency in Practice》推荐线程打扰机制,见:
Interruption is usually the most sensible way to implement cancellation

另外注意,Thread里:
public static boolean interrupted()
public boolean isInterrupted()
是不一样的,前面的会清除打扰标志位,具体使用的时候要 考虑一下。

想挽留 2017-10-18 23:27:44
boolean flag = true;
Thread secondary = new Thread(new Runnable() {

@Override
public void run() {
while (flag) {
// do something
}
}
});

secondary.start(); //start the thread
flag = false; // this will force secondary to finish its execution
try {
secondary.join(); // wait for secondary to finish
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
甜柠檬 2017-06-29 12:02:55

不要依赖 interrupt 方法,线程能够被 interrupt 前提是线程处于可以被中断的状态,比如:sleep,wait 等等,如果线程处于其他状态,interrupt 是没有用的

当然上面提到的很多设置 boolean 变量的方法,是可取的,但是需要注意的是,往往设置 boolean 变量是在其他线程里面进行设置,建议使用 volatile boolean

还有一种方法就是,throw exception 方式,比如:代码正在跟流打交道,或给网络打交道,或者读取数据库,此时可以通过关闭流,关闭网络,或者关闭数据库,这样会很快的抛出异常,通过对异常的捕获,来完成线程的工作

泛泛之交 2017-03-19 07:11:54

Java线程的常见的几种状态1.new(新建)。2.runnable(就绪)。3.Running(正在运行)。4.Block(阻塞)。5.sleep(睡眠)6.Dead(死亡)。
当run()方法或main()方法结束后,线程就进入终止状态,也就是结束啦。
你想办法让run()执行到最后就可以了, 发出中断信息是API中所推荐的 Thread.interrupt(),
简单的还可以设置一个BOOLEAN 值去控制, 一般你需要控制结束大多都是线程里面会是一个循环机制,每一次循环检测这个BOOLEAN 值变量即可。
按照上述,就是finish() 之后改变BOOLEAN 之后就行了。

灵芸 2017-01-08 20:12:19

interrupt 方法有些“除暴”,我一般使用设置标志位的方法!

想挽留 2016-12-04 07:47:00

线程一般用Thread.interrupt()来终止
线程run方法中使用while(!Thread.interrupted()){ 具体代码}
关于具体代码部分,如果是阻塞代码,有些是可终止,有些是不可终止
在可终止的时候,处理interruptedException

阻塞不可停止的时候,就要适当的加上标志

具体阅读Think in Java 并发那一章

下载地址:http://115.com/file/bhu6ih4t

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文