嘿所有 - 这个代码在我试图清理处理程序的方式上可能有点乱,因为我一直试图追踪崩溃发生的地方......
我有一个对话框活动,显示一个密码条目,其中一个进度条由一个线程和处理程序设置动画......
似乎当我试图查看进度条是否完成,并试图杀死该线程时,我正在做的事情的方式是当我尝试去一个新的活动时弄乱一些东西 - 即在调用函数而没有任何东西返回到或其他东西......
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();
}
}
}
};
}
答案 0 :(得分:7)
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
标志,该标志允许您在线程未阻塞或休眠时停止该线程,但这是可选的。
答案 1 :(得分:2)
您可以考虑使用 AsyncTask 实例而不是runnable和处理程序。
如果需要取消AsycnTask实例,只需在AsyncTask对象引用上调用.cancel(true)
即可。这将同时处理后台方法(doInBackground()
)和进度更新程序(onProgressUpdate()
)。
我通常发现AsyncTask比我自己处理所有细节更容易使用。
因此,在RMO_Dialog中,在您创建的扩展AsyncTask的类的实例上使用调用execute()
。
public class RMO_Dialog extends Activity {
...
// Get ref to your bg task for easily cancellation if needed
PassWordEntry background = new PassWordEntry();
// Start bg task
background.execute([PARAMS]);
...
// Cancel task
background.cancel(true);
...
// AsyncTask lets you encapsulate both your runnable and handler in it
private static class PassWordEntry() extends AsyncTask<[PARAMS], [PROGRESS], [RESULT]> {
protected [RESULT] doInBackground() {
... // Runnable stuff here
return [RESULT];
}
protected void onProgressUpdate([PROGRESS]... progress) {
... // progressHandler stuff here
}
protected void onPostExecute([RESULT]) {
// Clean up return data when all done w BG here
}
}
}