活动崩溃后android停止后台服务

时间:2012-11-08 10:28:30

标签: android android-service ondestroy uncaught-exception uncaughtexceptionhandler

一开始,我想为糟糕的英语道歉。

有我的问题:

我在android中有一个服务,它在运行时运行在后台运行。 (此服务使用指定的时间间隔与服务器同步用户数据。)

public class CService extends Service
{
   private Boolean isDestroyed;



@Override
    public int onStartCommand (Intent intent, int flags, int startId)
    {
            if (intent != null)
            {
                   new Thread(new Runnable()
                   {
                   //run new thread to disable flush memory for android and destroy this service
                           @Override
                           public void run ()
                           {
                                     this.isDestroyed = Boolean.FALSE
                                     while(!this.isDestroyed)
                                     {
                                     //loop until service isn't destroyed
                                     }
                            }

                    }).start();
            }
            return Service.START_NOT_STICKY;

    }

    @Override
    public void onDestroy ()
    {
           //THIS ISNT CALLED FROM uncaughtException IN ACTIVITY BUT from onDestroy method is this called.

           //when is service destroyed then onDestroy is called and loop finish
           this.isDestroyed = Boolean.TRUE;
    }

}

从onCreateMethod中的活动开始。此活动实现Thread.UncaughtExceptionHandler并在onCreate方法中注册以捕获活动中的所有意外异常。当活动中的某些东西抛出异常方法时,会调用uncaughtException,并且服务应该以stopService(serviceIntent)停止;但onDestoy在服务中没有被调用。但是当调用的活动中的onDestroy方法(用户推送然后返回按钮)服务成功停止并且调用CService中的onDestoroy时。

    public class CActivity extends Activity implements Thread.UncaughtExceptionHandler
    {
            private Thread.UncaughtExceptionHandler defaultUEH;

        @Override
        protected void onCreate (Bundle savedInstanceState)
        {

            this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();

            // create intent for service
            Intent serviceIntent = new Intent(this, CService.class);
            // run service
            startService(serviceIntent);

            //set default handler when application crash
            Thread.setDefaultUncaughtExceptionHandler(this);
            super.onCreate(savedInstanceState);
        }

        @Override
        public void uncaughtException (Thread thread, Throwable ex)
        {
            //THIS DOESN'T WORK

            //when global exception in activity is throws then this method is called. 
            Intent serviceIntent = new Intent(this, CService.class);
            //method to service stop is called. BUT THIS METHOD DON'T CALL onDestroy in CService
            stopService(serviceIntent);
            defaultUEH.uncaughtException(thread, ex);       
        }

        @Override
        public void onDestroy ()
        {
            //this work fine
            Intent serviceIntent = new Intent(this, CService.class);
            stopService(serviceIntent);
            super.onDestroy();
            }


    }

活动崩溃时我需要停止后台服务。当android关闭活动并在堆栈中启动上一个活动时(因为登录屏幕),现在没有用户登录。

感谢您的建议。

2 个答案:

答案 0 :(得分:2)

试试这个

    Thread.currentThread().setUncaughtExceptionHandler(this);

<强> UPD
这是默认的android异常处理程序

private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) {
            try {
                // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
                if (mCrashing) return;
                mCrashing = true;

                if (mApplicationObject == null) {
                    Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
                } else {
                    Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e);
                }

                // Bring up crash dialog, wait for it to be dismissed
                ActivityManagerNative.getDefault().handleApplicationCrash(
                        mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
            } catch (Throwable t2) {
                try {
                    Slog.e(TAG, "Error reporting crash", t2);
                } catch (Throwable t3) {
                    // Even Slog.e() fails!  Oh well.
                }
            } finally {
                // Try everything to make sure this process goes away.
                Process.killProcess(Process.myPid());
                System.exit(10);
            }
        }
    }

我相信你没有得到onDestroy()调用,因为默认的android异常处理程序只是破坏了整个进程System.exit()。你可以尝试不调用defaultUEH.uncaughtException(thread,ex);或者(如果)您的服务被破坏后稍后再打电话。

答案 1 :(得分:1)

老兄,顺便问一下你为什么要在onCreate方法中执行你的行动? 正如文档说这个方法是从主线程调用的,我实际上想知道它是如何工作的。你应该从另一个Thread做任何繁重的计算。

http://developer.android.com/reference/android/app/Service.html

  

实际创建服务组件时,对于其中任何一个   原因,系统实际做的就是实例化   组件并调用其onCreate()和任何其他适当的回调   在主线程上。由服务部门来实现这些   适当的行为,例如创建其中的辅助线程   它做了它的工作。