android - 如何在进入新 Activity 之前终止线程和处理程序

标签 android multithreading handler

大家好 - 在我尝试清理处理程序的过程中,这段代码可能有点困惑,因为我一直在尝试追踪崩溃发生的位置...

我有一个对话框 Activity ,它显示一个密码条目,进度条由一个线程和处理程序动画...

似乎当我试图查看进度条是否完成并试图终止线程时,我这样做的方式是在我尝试进行新 Activity 时搞砸了一些事情 - 即在调用函数并且没有任何东西返回或其他东西的方式...

public class RMO_Dialog extends Activity {
    private ProgressBar progbar;
    private Button dialogOK;
    private EditText dialogPass;
    private SharedPreferences prefs;
    private String pass;
    private int increment=10;
    private Thread background;

    private Boolean commCalled=false;

    public void callCommunications(){
        progbar.setVisibility(0);
        progbar.setProgress(0);
        background.stop();
        Toast.makeText(getApplicationContext(), "Call communication should happen once.", Toast.LENGTH_LONG).show();
//      Intent i = new Intent();
//      i.setClass(RMO_Dialog.this, RMO_Comm.class);
//      i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//      startActivity(i);
//          finish();
    }

    public void buzzUser(){

        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        int dot = 200;
        int dash = 500;
        int short_gap = 200;
        int medium_gap = 500;
        int long_gap = 1000;
        long[] pattern = {0,dot, short_gap, dot, short_gap, dot, medium_gap, dash, short_gap, dash, short_gap, dash, medium_gap, dot, short_gap, 
                dot, short_gap, dot, long_gap};

        v.vibrate(pattern, -1);


    }

    public void killCountdown(){
        progbar.setVisibility(0);
        progbar.setProgress(0);
        background.stop();
    }

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialogpassword);

        buzzUser();

        prefs = this.getSharedPreferences("RMO", MODE_WORLD_READABLE);
        pass = prefs.getString("password", "");

        dialogOK = (Button) findViewById(R.id.dialogOK);
        dialogPass = (EditText) findViewById(R.id.dialogPass);
        progbar = (ProgressBar) findViewById(R.id.progress);

        progbar.setProgress(0);

        background = new Thread(new Runnable(){
            @Override
            public void run() {
                try{
                    while(progbar.getProgress()<=progbar.getMax()){
                        Thread.sleep(300);
                        progressHandler.sendMessage(progressHandler.obtainMessage());
                    }
                }catch(java.lang.InterruptedException e){
                    Toast.makeText(getApplicationContext(), "Error thrown.", Toast.LENGTH_LONG).show();
                }

            }

        });
        background.start();

        dialogOK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(dialogPass.getText().toString().equals(pass.toString())){
                    killCountdown();
                    Toast.makeText(getApplicationContext(), "Guardian Angel next alert has been disengaged.", Toast.LENGTH_LONG).show();
                    Intent intent = new Intent();
                    intent.setClass(RMO_Dialog.this, RMO.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                    finish();
                }else{
                    callCommunications();
                }
            }
        });



    }

    Handler progressHandler = new Handler(){
        public void handleMessage(Message msg){
            progbar.incrementProgressBy(increment);
            if(progbar.getProgress()==progbar.getMax()){
                Toast.makeText(getApplicationContext(), "commcalled: "+ commCalled, Toast.LENGTH_LONG).show();
                if(commCalled==false){
                    commCalled=true;
                    callCommunications();
                }

            }
        }
    };
}

最佳答案

Thread.stop is deprecated call , 相反你应该使用 Thread.interrupt方法。

public void killCountdown(int waitTime){
    progbar.setVisibility(0);
    progbar.setProgress(0);
    // deprecated: background.stop();
    background.interrupt(); // <-- OK
    background.join(waitTime); // optionally wait for the thread to exit
}

Thread.Interrupt 将在您的线程下次阻塞或休眠时导致 ThreadInterruptedException 并且您已经在线程主体中进行处理,所以这很好。此外,您可能希望包含一个 volatile 标志,允许您在线程未阻塞或休眠时停止它,但这是可选的。

关于android - 如何在进入新 Activity 之前终止线程和处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696506/

相关文章:

Android 模拟器控制按钮(返回、主页、任务)不起作用

Android通过处理程序在单独的线程上更新TextView

c# - 跨线程属性行为

javascript - 附加事件处理程序

android - NavigationView 与 DrawerLayout setCheckedItem 不工作

滚动多个 recyclerviews 时 Android ui 滞后

c++ - unique_ptr 与多线程

java - 如何让此代码等待线程池中的线程可用?

CouchDB:批量更新最佳实践

c# - ASP.NET Web API 中的参数绑定(bind)