Java 如何停止或销毁Android线程

Java 如何停止或销毁Android线程,java,android,multithreading,Java,Android,Multithreading,我知道stop方法已被弃用,我现在正在使用destroy,但我遇到了以下错误: 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() 11-09 11:42:28.740: E/AndroidRuntime(1538): at jav

我知道
stop
方法已被弃用,我现在正在使用
destroy
,但我遇到了以下错误:

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()
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.Thread.destroy(Thread.java:600)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.rathbones.src.NewslettersActivity.onKeyDown(NewslettersActivity.java:144)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.os.Looper.loop(Looper.java:123)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.app.ActivityThread.main(ActivityThread.java:4627)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.reflect.Method.invokeNative(Native Method)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.reflect.Method.invoke(Method.java:521)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at dalvik.system.NativeStart.main(Native Method)
11-09 11:42:28.760: W/ActivityManager(59):   Force finishing activity com.rathbones.src/.NewslettersActivity
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();

        // Utilities.List(getApplicationContext().getFilesDir().getPath());
        // Utilities.List(getApplicationContext().getDir("files", Context.MODE_WORLD_WRITEABLE).getAbsolutePath());
        // Utilities.DeleteDirectory(getApplicationContext().getDir("files", Context.MODE_WORLD_WRITEABLE).getAbsolutePath());

    }

    private void viewPDF(File file) {

        //DEBUG DEBUG DEBUG
        //Log.d(Constants.APP_NAME, "ViewPDF: showing " + file.getName());
        //Log.d(Constants.APP_NAME, "Path: " + file.getPath());
        //Log.d(Constants.APP_NAME, "Exists: " + file.exists());
        //Log.d(Constants.APP_NAME, "Length: " + file.length());
        //DEBUG DEBUG DEBUG

        // Now it's all safe and sound and local, open it
        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);
    }
应用程序没有崩溃,只是我在logcat中得到了这个错误

事实上,我有一个通讯模块,使用户可以查看PDF文件。当他们按下查看按钮时,它会打开一个进度条,同时,如果有人按下后退按钮,它会停止线程并优雅地退出。它会这样做,但在日志中我得到了上面的错误

以下是导致此错误的代码段:

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()
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.Thread.destroy(Thread.java:600)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.rathbones.src.NewslettersActivity.onKeyDown(NewslettersActivity.java:144)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.os.Looper.loop(Looper.java:123)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at android.app.ActivityThread.main(ActivityThread.java:4627)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.reflect.Method.invokeNative(Native Method)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at java.lang.reflect.Method.invoke(Method.java:521)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-09 11:42:28.740: E/AndroidRuntime(1538):     at dalvik.system.NativeStart.main(Native Method)
11-09 11:42:28.760: W/ActivityManager(59):   Force finishing activity com.rathbones.src/.NewslettersActivity
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();

        // Utilities.List(getApplicationContext().getFilesDir().getPath());
        // Utilities.List(getApplicationContext().getDir("files", Context.MODE_WORLD_WRITEABLE).getAbsolutePath());
        // Utilities.DeleteDirectory(getApplicationContext().getDir("files", Context.MODE_WORLD_WRITEABLE).getAbsolutePath());

    }

    private void viewPDF(File file) {

        //DEBUG DEBUG DEBUG
        //Log.d(Constants.APP_NAME, "ViewPDF: showing " + file.getName());
        //Log.d(Constants.APP_NAME, "Path: " + file.getPath());
        //Log.d(Constants.APP_NAME, "Exists: " + file.exists());
        //Log.d(Constants.APP_NAME, "Length: " + file.length());
        //DEBUG DEBUG DEBUG

        // Now it's all safe and sound and local, open it
        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);
    }

使用
interrupt()
而不是
destroy()

使用
interrupt()
而不是
destroy()

如果线程中有
while
循环,则可以通过while条件的布尔标志来控制该线程。当您将标志设置为false时,线程就完成了它的任务

这里有一个小例子:

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);
}

我将在SO中找到此代码,它也适用于我。

如果您有一个线程,其中包含
while
循环,您可以通过while条件的布尔标志来控制此线程。当您将标志设置为false时,线程就完成了它的任务

这里有一个小例子:

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);
}

我将在SO中找到这段代码,它也适用于我。

对于用户370305的回答,可能有两个更改可以帮助:

  • 使用
    AtomicBoolean
    而不是boolean,如果线程在另一个内核中运行,则标记的更改将不可见

  • 删除catch中的
    抛出新运行时异常(e)
    。当您抛出异常时,它将崩溃


  • 对于用户370305的回答,可能有两个更改可以帮助您:

  • 使用
    AtomicBoolean
    而不是boolean,如果线程在另一个内核中运行,则标记的更改将不可见

  • 删除catch中的
    抛出新运行时异常(e)
    。当您抛出异常时,它将崩溃


  • destroy也不推荐使用。请点击此链接:@VineetShukla感谢您让我知道。destroy也不推荐使用。点击这个链接:@VineetShukla谢谢你让我知道。你能告诉我更多的细节吗。嗯..这看起来是一个非常合理的解决方案..现在就试试..会让你满意的know@DipakKeshariya-如果没有看到你尝试了什么,你是如何在你的应用程序中实现这些代码的,我们什么都不能说。请看我的问题,你能告诉我更详细的情况吗?好吧,这看起来是一个非常合理的解决方案。现在就试试吧。我会让你满意的know@DipakKeshariya-如果没有看到你尝试了什么,你是如何在你的应用程序中实现这些代码的,我们什么都不能说。把你的问题作为一个新的问题,除了你得到了什么。请看我的问题,然后按照这个:然后按照这个: