Таймер не выключается при нажатии кнопки назад. Ошибка принудительного закрытия при нажатии кнопки - PullRequest
1 голос
/ 06 июля 2011

ОК, все, вы супер гуру Java / Android. Я знаю, что вы посмотрите на это и посмеетесь, но мне действительно нужна помощь. Я супер новичок и прочитал все документы по разработке Google (и многие другие) и просто не могу понять концепцию. Можно узнать намного больше, увидев рабочий код, а не ссылку на то, что я уже прочитал и, очевидно, не понял, поэтому, если кто-то может мне помочь, это было бы замечательно.

Основная деятельность

 import java.util.Timer;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.webkit.WebView;

 public class Quotes extends Activity implements OnClickListener {

 ProgressDialog dialog;
private WebView webview;
private Timer timer;

 @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");

    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(){
   timer.cancel(); 
   super.onPause();
 }

 @Override
 public void onResume(){
  webview.reload();
      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;

 }



 }   

CatLog

 07-05 17:28:51.001: DEBUG/AndroidRuntime(11446): Shutting down VM
 07-05 17:28:51.001: WARN/dalvikvm(11446): threadid=1: thread exiting with uncaught exception (group=0x40018560)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446): FATAL EXCEPTION: main
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446): java.lang.RuntimeException: Unable to pause activity {com.dge.quotes/com.dge.quotes.Quotes}: java.lang.NullPointerException
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2477)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2424)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2404)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.access$1700(ActivityThread.java:124)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:979)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.os.Handler.dispatchMessage(Handler.java:99)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.os.Looper.loop(Looper.java:123)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.main(ActivityThread.java:3806)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at java.lang.reflect.Method.invokeNative(Native Method)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at java.lang.reflect.Method.invoke(Method.java:507)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at dalvik.system.NativeStart.main(Native Method)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446): Caused by: java.lang.NullPointerException
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at com.dge.quotes.Quotes.onPause(Quotes.java:72)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.Activity.performPause(Activity.java:3901)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1191)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2459)
 07-05 17:28:51.017: ERROR/AndroidRuntime(11446):     ... 12 more
 07-05 17:28:51.509: WARN/ActivityManager(1319): Activity pause timeout for HistoryRecord{40ba7e20 com.dge.quotes/.Quotes}

Любая помощь будет принята с благодарностью.

В этот момент я чувствую себя совершенно сумасшедшей женщиной, которой действительно нужно завершить этот проект, чтобы моя жизнь могла двигаться вперед. Если у кого-нибудь (ЛЮБОГО) есть ответ на этот вопрос, я бы ДЕЙСТВИТЕЛЬНО оценил его.

Ответы [ 3 ]

1 голос
/ 08 июля 2011

У вас есть личный таймер, называемый таймером в действии, однако, похоже, он не был инициализирован, так как в вашей активности есть другой таймер, называемый таймером.Ваш таймер таймера, определенный в веб-представлении, имеет значение null, поэтому вы получаете nullpointexception при вызове onPause.

Удалите класс из onCreate (), вам может потребоваться определить Timer как singlethreadscheduledexecutor.

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

Ваш код с предложенным ответом:

import java.util.Timer;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.webkit.WebView;

 public class Quotes extends Activity implements OnClickListener {

 ProgressDialog dialog;
private WebView webview;
private Timer timer;

 @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");

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



    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(){
   timer.cancel(); 
   super.onPause();
 }

 @Override
 public void onResume(){
  webview.reload();
      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;

 }



 }   
0 голосов
/ 06 июля 2011

onStop () - более надежное место для размещения timer.cancel () (или обоих мест, если вы хотите охватить почти каждую ситуацию, например, обстоятельства, указанные в конце здесь ).

onPause () вызывается не в каждой ситуации, она используется, когда onResume () имеет достаточную вероятность, например, когда вы переходите к другому действию и затем возвращаетесь.Обратите внимание на отступ в схеме жизненного цикла .Может не вызываться при нажатии кнопки «назад».

РЕДАКТ. 1: это предварительный ответ, поэтому он может не охватывать проблему принудительного закрытия.

РЕДАКТ. 2:

@Override
public void onStop(){
    super.onStop();
    try {
        timer.cancel();
    } catch (Exception ex) {
        Log.e("MY APP ERROR", ex.getMessage());
    }
}

I всегда ставил вызов super первым в этих методах жизненного цикла.Я не уверен, если это имеет значение.Вы, вероятно, захотите установить оператор try / catch, особенно если вы решите включить timer.cancel () в onStop () И onPause ().

РЕДАКТИРОВАТЬ 3: О готовности признать поражение,Я не очень знаком с особенностями ScheduledExecutorService, и, поскольку вы заявили, что готовы переписать, вот как я добился того же в своих приложениях.Handler - это реализация для Android, поэтому, возможно, именно поэтому у меня не было таких проблем, как у вас.

Handler timer;
Runnable runner;

@Override
onCreate(...) {
    ...

    //EDIT 4: (reading time from preferences)
    SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

    final int c = Integer.parseInt(SP.getString("appRefreshRate","20"));

    ...

    runner = new Runnable() {
        @Override
        public void run() {
            timer.postDelayed(runner, c * 1000);
            webview.reload();
        }
    };
    timer = new Handler();
    timer.postDelayed(runner, c * 1000);

    ...
}

@Override
public void onPause(){
    super.onPause();
    try {
        timer.removeCallbacks(runner);
    } catch (Exception ex) {
        Log.e("MY APP ERROR", ex.getMessage());
    }
}

@Override
public void onStop(){
    super.onStop();
    try {
        timer.removeCallbacks(runner);
    } catch (Exception ex) {
        Log.e("MY APP ERROR", ex.getMessage());
    }
}
0 голосов
/ 06 июля 2011

Вы можете попытаться перехватить onBackPressed в своей деятельности, а затем выполнить timer.cancel (). Что-то вроде

@Override
public void onBackPressed() {
    timer.cancel();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...