4

はじめに、下手な英語でお詫び申し上げます。

私の問題があります:

アクティビティが実行されているときにバックグラウンドで実行される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 の onDestroy が呼び出されます。

    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 がアクティビティを閉じて、スタック (ログイン画面) で前のアクティビティを開始すると、ユーザーがログに記録されなくなります。

提案をありがとう。

4

2 に答える 2

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

デフォルトのAndroid例外ハンドラーはプロセスSystem.exit()全体を破棄するだけなので、onDestroy()呼び出しは取得されないと思います。defaultUEH.uncaughtException(thread、ex);を呼び出さないようにすることができます。または、サービスが破壊された後(もしあれば)後でそれを呼び出します。

于 2012-11-08T13:29:56.363 に答える
1

ところで、なぜonCreateメソッドでアクションを実行するのですか?ドキュメントには、このメソッドはメインスレッドから呼び出されると書かれているので、実際にはどのように機能するのか疑問に思っています。別のスレッドから重い計算を行う必要があります。

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

サービスコンポーネントが実際に作成されるとき、これらの理由のいずれかのために、システムが実際に行うことは、コンポーネントをインスタンス化し、そのonCreate()およびメインスレッド上の他の適切なコールバックを呼び出すことだけです。動作を行うセカンダリスレッドを作成するなど、適切な動作でこれらを実装するのはサービスの責任です。

于 2012-11-08T15:45:34.037 に答える