Android-android 如何优雅的主动终止并等待线程的结束?
这段代码用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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
首先,不是有问题,是有很大的问题。。。你确定你的程序没有挂掉?
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()
是不一样的,前面的会清除打扰标志位,具体使用的时候要 考虑一下。
不要依赖 interrupt 方法,线程能够被 interrupt 前提是线程处于可以被中断的状态,比如:sleep,wait 等等,如果线程处于其他状态,interrupt 是没有用的
当然上面提到的很多设置 boolean 变量的方法,是可取的,但是需要注意的是,往往设置 boolean 变量是在其他线程里面进行设置,建议使用 volatile boolean
还有一种方法就是,throw exception 方式,比如:代码正在跟流打交道,或给网络打交道,或者读取数据库,此时可以通过关闭流,关闭网络,或者关闭数据库,这样会很快的抛出异常,通过对异常的捕获,来完成线程的工作
Java线程的常见的几种状态1.new(新建)。2.runnable(就绪)。3.Running(正在运行)。4.Block(阻塞)。5.sleep(睡眠)6.Dead(死亡)。
当run()方法或main()方法结束后,线程就进入终止状态,也就是结束啦。
你想办法让run()执行到最后就可以了, 发出中断信息是API中所推荐的 Thread.interrupt(),
简单的还可以设置一个BOOLEAN 值去控制, 一般你需要控制结束大多都是线程里面会是一个循环机制,每一次循环检测这个BOOLEAN 值变量即可。
按照上述,就是finish() 之后改变BOOLEAN 之后就行了。
interrupt 方法有些“除暴”,我一般使用设置标志位的方法!
线程一般用Thread.interrupt()来终止
线程run方法中使用while(!Thread.interrupted()){ 具体代码}
关于具体代码部分,如果是阻塞代码,有些是可终止,有些是不可终止
在可终止的时候,处理interruptedException
阻塞不可停止的时候,就要适当的加上标志
具体阅读Think in Java 并发那一章
下载地址:http://115.com/file/bhu6ih4t