开发者

Back Button on exit creating a Force Close Error

I am trying to avoid using onDestroy and want to keep this as simple as possible, but when I exit the program, I get a Force Close error. Not sure why. Here is the code for the main part of the application. Any suggestions?

Main Application Code

   public class Quotes extends Activity implements OnClickListener {

   ProgressDialog dialog;
   private WebView webview;

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

          WebView adsview = (WebView) findViewById(R.id.ads);
          adsview.getSettings().setJavaScriptEnabled(true);
          adsview.loadUrl("http://www.dgdevelco.com/quotes/androidad.html");
开发者_如何学JAVA
          SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

          String q = SP.getString("appViewType","http://www.dgdevelco.com/quotes/quotesandroidtxt.html");
          String c = SP.getString("appRefreshRate","20");

          webview = (WebView) findViewById(R.id.scroll);
          webview.getSettings().setJavaScriptEnabled(true);
          webview.setWebViewClient(new QuotesWebView(this));
          webview.loadUrl(q);

          ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
          timer.scheduleAtFixedRate(new Runnable() {

 @Override
 public void run() {
          webview.reload();
          }

 }, 10, Long.parseLong(c),TimeUnit.SECONDS);

 findViewById(R.id.refresh).setOnClickListener(this);


 }

 @Override
 public void onPause(){
          super.onPause();
 }

 @Override
 public void onResume(){
          super.onResume();
 }


 public void onClick(View v){
          switch(v.getId()){
          case R.id.refresh:
               webview.reload();
               break;
          }
 }


 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
          MenuInflater inflater = getMenuInflater();
          inflater.inflate(R.menu.menu, menu);

          MenuItem about = menu.getItem(0);
          about.setIntent(new Intent(this, About.class));

          MenuItem preferences = menu.getItem(1);
          preferences.setIntent(new Intent(this, Preferences.class));

          return true;

 }

 }   

LogCat

 07-04 13:34:55.011: INFO/DevicePushListener(1415): Connection State Changed: NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true
 07-04 13:34:55.011: WARN/WindowManager(1314): Attempted to add application window with unknown token HistoryRecord{40c40f50 com.dge.quotes/.Quotes}.  Aborting.
 07-04 13:34:55.034: DEBUG/AndroidRuntime(24137): Shutting down VM
 07-04 13:34:55.034: WARN/dalvikvm(24137): threadid=1: thread exiting with uncaught exception (group=0x40018560)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137): FATAL EXCEPTION: main
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@40517fb0 is not valid; is your activity running?
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.view.ViewRoot.setView(ViewRoot.java:527)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.app.Dialog.show(Dialog.java:241)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.app.ProgressDialog.show(ProgressDialog.java:107)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.app.ProgressDialog.show(ProgressDialog.java:90)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at com.dge.quotes.QuotesWebView.onPageStarted(QuotesWebView.java:22)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:271)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.os.Handler.dispatchMessage(Handler.java:99)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.os.Looper.loop(Looper.java:123)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at android.app.ActivityThread.main(ActivityThread.java:3806)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at java.lang.reflect.Method.invokeNative(Native Method)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at java.lang.reflect.Method.invoke(Method.java:507)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
 07-04 13:34:55.058: ERROR/AndroidRuntime(24137):     at dalvik.system.NativeStart.main(Native Method)
 07-04 13:34:55.089: WARN/ActivityManager(1314):   Force finishing activity com.dge.quotes/.Quotes


Its written in your stacktrace

Unable to add window -- token android.os.BinderProxy@40517fb0 is not valid; is your activity running

You start a thread that does a reload

You then press back

Your activity finished

The thread returns and tries to draw on your activity

Oops its already finished


Take a look at the example code provided on the ScheduledExecutorService documentation page:

import static java.util.concurrent.TimeUnit.*;
 class BeeperControl {
   private final ScheduledExecutorService scheduler =
     Executors.newScheduledThreadPool(1);

   public void beepForAnHour() {
     final Runnable beeper = new Runnable() {
       public void run() { System.out.println("beep"); 
     };
     final ScheduledFuture beeperHandle =
       scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
     scheduler.schedule(new Runnable() {
       public void run() { beeperHandle.cancel(true); }
     }, 60 * 60, SECONDS);
   }
 }}

(http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html)

As others have said, the problem is that the ScheduledExecutorService keeps running and reloading the page even after the user closes that activity. To fix this, you can stop the ScheduledExecutorService in onPause.

Calling scheduleAtFixedFate() returns a ScheduledFuture object. Store this object and then call cancel(true) on it in your onPause() method.


Your activity is already stopped when it reaches that line of code. Refer to the exchange in this "bug" report in the Android forum: http://code.google.com/p/android/issues/detail?id=3953

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜