我想知道我取消后是否可以再次安排计时器。这里陈述http://www.coderanch.com/t/452066/java/java/Exception-timer-IllegalStateException,一旦你取消了计时器,就不可能在同一个计时器上安排任何东西,除非我创建一个新的计时器。而且,我遇到以下错误, java.lang.IllegalStateException:计时器被取消。 我试图推出一个定期执行Wifi扫描的定时器。但我希望“暂停”或者如果没有,则在扫描后执行某些计算时取消定时器。只有在完成计算并返回一些结果后,我才会恢复计时器。谁能告诉我如何解决这个问题呢?
忘了提到只有在我完成加载我使用AsyncTask这样做的图像后我才会启动计时器。
我试图让这个人成为一个单独的线程,以免它阻碍UI线程。
这是程序和启动计时器的粗略骨架,只有在图像完全加载后才会执行wifi扫描(在 load.execute(context); “):
public class LargeImageScroller extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {...}
@Override
public boolean onOptionsItemSelected(MenuItem item) {...}
//this is the class where the program would do all the UI and display images
private static class SampleView extends View {
public SampleView(Context context) {
:
loadMap load = new loadMap();
load.execute(context);
scanTask = new TimerTask(){
@Override
public void run() {
// TODO Auto-generated method stub
handler.post(new Runnable() {
public void run() {
wifi = (WifiManager)context.getSystemService(WIFI_SERVICE);
context.registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
wifi.startScan();
Log.d("TIMER", "Timer set off");
}
});
}
};
scanTimer.schedule(scanTask, refreshRate);
}
public class wifiReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
List<ScanResult> sc = wifi.getScanResults();
for(int i=0; i<sc.size(); i++){
Log.e("AndroidRuntime", sc.get(i).SSID);
}
}
}
public boolean onTouchEvent(MotionEvent event) {...}
protected void onDraw(Canvas canvas) {...}
private static Drawable LoadImageFromWebOperations(String url){...}
private static Bitmap decodeFile(File f, int requiredSize){...}
private class loadMap extends AsyncTask<Context, Void, ArrayList<Bitmap>>{...}
}
使用包含的权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.DELETE_CACHE_FILES"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
广播接收器遇到错误:
10-25 05:53:04.903: ERROR/ActivityThread(1551): Activity android.wps.LargeImageScroller has leaked IntentReceiver android.wps.LargeImageScroller$SampleView$wifiReceiver@43d1bca0 that was originally registered here. Are you missing a call to unregisterReceiver()?
10-25 05:53:04.903: ERROR/ActivityThread(1551): android.app.IntentReceiverLeaked: Activity android.wps.LargeImageScroller has leaked IntentReceiver android.wps.LargeImageScroller$SampleView$wifiReceiver@43d1bca0 that was originally registered here. Are you missing a call to unregisterReceiver()?
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:797)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:608)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ApplicationContext.registerReceiverInternal(ApplicationContext.java:724)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:711)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ApplicationContext.registerReceiver(ApplicationContext.java:705)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:308)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.wps.LargeImageScroller$SampleView$1$1.run(LargeImageScroller.java:187)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.os.Handler.handleCallback(Handler.java:587)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.os.Handler.dispatchMessage(Handler.java:92)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.os.Looper.loop(Looper.java:123)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at android.app.ActivityThread.main(ActivityThread.java:4363)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at java.lang.reflect.Method.invokeNative(Native Method)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at java.lang.reflect.Method.invoke(Method.java:521)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-25 05:53:04.903: ERROR/ActivityThread(1551): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:13)
是的,取消计时器会终止其线程,因此您无法再次使用它。计时器没有任何内置的暂停方法。当您想要“暂停”时可以取消定时器,并在想要“恢复”时再创建一个新定时器。
答案 1 :(得分:3)
最后我解决了这个问题:D 我没有时间解释它,但我想与你分享。
import java.util.Timer; import java.util.TimerTask; import sociatag.view.main_frame; public class devices_pinger implements Runnable {
// PROPERTIES:
private int delay = 1000; // delay for 1 seconds.
private int period = 6000; // repeat every 6 seconds.
private boolean stop_timer = false;
// CONSTRACTOR:
public devices_pinger() {
}
// METHODES:
/*
* because we implements Runnable in this class,
* this methode run() has to run this class on a seperate thread.
* - call the start pinger methode
*
* @param: event occured on the serial
*/
@Override
public void run() {
run_pinger();
}
/*
* this is the start point of this class
* - create a scheduler to run every x seconds
* - call the run methode every x seconds to:
* - send 'P' through the serial
* - wait x seconds
* - call the ping analyser to get all the replyed pings and analyse them
*/
private void run_pinger() {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// 1) ping the connected device
serial_connection.serial_write('P');
System.out.println("> PING (Send P)");//<------TESTING--------------------------------------------
// pause for 3 seonds to give time for all the devices to response
try {
Thread.sleep(3000); // call the analyser after 3 seconds
} catch (InterruptedException ex) {
System.out.println("Error: while pausing the thread");
} // 2) get the result of the ping to analyze it
serial_listener.ping_analyser();
if (stop_timer == true) {
this.cancel();
}
}
}, delay, period);
}
/*
* stop the timer before pairing the devices or do other activities
*/
public void stop_pinger() {
stop_timer = true;
main_frame.display_notification("Device Pinger is paused.");
}
/*
* restart the pinger by creating new instance of timer
*/
public void start_pinger() {
stop_timer = false;
run_pinger();
main_frame.display_notification("Device Pinger is running..");
}
}
答案 2 :(得分:0)
您是否尝试过使用Runnable处理程序并将其设置为常规间隔?像这样:
private Handler mUpdateHandler = new Handler();
private Runnable mUpdateRunnable = new Runnable() {
public void run() {
mUpdateHandler.postDelayed(this, delay);
}
};
mUpdateHandler.postDelayed(mUpdateRunnable, delay);
您可以根据需要指定延迟,并且可以在run()中执行任何操作。
答案 3 :(得分:0)