开发者

Cannot get a reference to my Service instance to successfully pass it a handler

I'm continuing to inch my way forward on this Service example (page 304) of Pro Android 2 Again, the Service example consists of two classes: MainActivity.java and BackgroundService.java both shown below. My latest hurdle is getting and using a reference to a Service instance to successfully pass it a handler.

From web searches I have found ugly ways to pass a handler to a Service instance that just don't work. I would appreciate some help on my next step in this process - making it work. Please have a look at my comments and code below that document my attempt to pass a handler to a Service instance in the bind button (bindBtn).

    public class MainActivity extends Activity {
        private static final String TAG = "MainActivity";

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

            Log.d(TAG, "starting service");

            Button bindBtn = (Button)findViewById(R.id.bindBtn);
            bindBtn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    Intent backgroundService = new Intent(MainActivity.this, com.marie.mainactivity.BackgroundService.class);
                    startService(backgroundService);

                    // wait until BackgroundService has started
                    while (BackgroundService.getInstance() == null);
                    // get instance of BackgroundService
                    BackgroundService sInstance = BackgroundService.getInstance();

                    // now finally pass the handler to the Service              
                    sInstance.setHandler(handler);
                }
            });

            Button unbindBtn = (Button)findViewById(R.id.unbindBtn);
            unbindBtn.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    stopService(new Intent(MainActivity.this, BackgroundService.class));
                }
            });
        }
    }

    // The handler to be passed to the Service
    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String msgObj = (String) msg.obj;
            int arg1 = msg.arg1;
            int arg2 = msg.arg2;
            int what = msg.what;
            Log.i("handleMessge", "msgObj: " + msgObj + ", " + "arg1: " + arg1 + ", " + "arg2: " + arg2 + ", " + "what: " + what);  
        }
    };

And now the BackgroundService:

    public class BackgroundService extends Service {
        private NotificationManager notificationMgr;

        private Handler mHandler;
        private static Service sInstance = null;

        @Override
        public void onCreate() {
            super.onCreate();

            notificationMgr = NotificationManager)getSystemService(NOTIFICATION_SERVICE);

            displayNotificationMessage("starting Background Service");

            Thread thr = new Thread(null, new ServiceWorker(), "BackgroundService");
            thr.start();
        }   

        class ServiceWorker implements Runnable
        {
            public void run() {
                //Use the handler to send a message
                Message msg = new Message();
                msg.obj = "msg obj";
                msg.arg1 = 1;
                msg.arg2 = 2;
                msg.what = 3;
                mHandler.sendMessage(msg);

                //stop when done
                BackgroundService.this.stopSelf();
            }
        }

        @Override
        public void onDestroy()
        {
            displayNotificationMessage("stopping Background Service");
            super.onDestroy();
        }

        @Override
        public void onStart(Intent intent, int startId) {
            super.onStart(intent, startId);
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        private void displayNotificationMessage(String message)
        {
            Notification notification = new Notification(R.drawable.note, message, System.currentTimeMillis());

            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

            notification.setLatestEventInfo(this, "Background Service", message, contentIntent);

            notificationMgr.notify(R.id.app_notification_id, notification);
        }
    }

My goal is to pass a handler to the Service after binding to it with the bind button (bindBtn) and send a message to the handler. But I get an ANR: ERROR/ActivityManager(96): ANR in com.marie.mainactivity. So clearly this seems to be the wrong way to pass a handler to a Service as it does not work.

I'm attempting to post the Logcat of the ANR below:

D/MainActivity(24622): starting service

I/ActivityManager(   96): Displayed com.marie.mainactivity/.MainActivity: +434ms

D/dalvikvm(23879): GC_EXPLICIT freed 5K, 50% free 2740K/5379K, external 1625K/2137K, paused 79ms

D/dalvikvm(18736): GC_EXPLICIT freed 28K, 49% free 2793K/5379K, external 1625K/2137K, paused 740ms

D/dalvikvm(18551): GC_EXPLICIT freed 32K, 49% free 2967K/5767K, external 1625K/2137K, paused 583ms

D/dalvikvm(  192): GC_EXPLICIT freed 42K, 53% free 3950K/8327K, external 12167K/12379K, paused 1000ms

W/ActivityManager(   96): Timeout executing service: ServiceRecord{4078d160 com.marie.mainactivity/.BackgroundService}

I/Process (   96): Sending signal. PID: 24622 SIG: 3

I/dalvikvm(24622): threadid=4: reacting to signal 3

I/dalvikvm(24622): Wrote stack traces to '/data/anr/traces.txt'

I/Process (   96): Sending signal. PID: 96 SIG: 3

I/dalvikvm(   96): threadid=4: reacting to signal 3

I/dalvikvm(   96): Wrote stack traces to '/data/anr/traces.txt'

I/Process (   96): Sending signal. PID: 184 SIG: 3

I/dalvikvm(  184): threadid=4: reacting to signal 3

I/dalvikvm(  184): Wrote stack traces to '/data/anr/traces.txt'

I/Process (   96): Sending signal. PID: 158 SIG: 3

I/dalvikvm(  158): threadid=4: reacting to signal 3

I/dalvikvm(  158): Wrote stack traces to '/data/anr/traces.txt'

D/dalvikvm(   96): GC_EXPLICIT freed 1045K, 41% free 6408K/10759K, external 2855K/3554K, paused 126ms

E/ActivityManager(   96): ANR in com.marie.mainactivity

E/ActivityManager(   96): Reason: Executing service com.marie.mainactivity/.BackgroundService

E/ActivityManager(   96): Load: 2.86 / 2.27 / 1.69

E/ActivityManager(   96): CPU usage from 20840ms to 0ms ago:

E/ActivityManager(   96):   93% 24622/com.marie.mainactivity: 93% user + 0% kernel / faults: 536 minor

E/ActivityManager(   96):   1.4% 73/akmd: 0% user + 1.4% kernel

E/ActivityManager(   96):   0.5% 96/system_server: 0.2% user + 0.2% kernel / faults: 9 minor

E/ActivityManager(   96):   0.1% 23879/com.google.android.apps.uploader: 0.1% user + 0% kernel / faults: 49 minor

E/ActivityManager(   96):   0.1% 192/com.android.launcher: 0.1% user + 0% kernel / faults: 69 minor

E/ActivityManager(   96):   0.1% 18551/android.pro开发者_JAVA百科cess.acore: 0.1% user + 0% kernel / faults: 54 minor

E/ActivityManager(   96):   0.1% 18736/android.process.media: 0.1% user + 0% kernel / faults: 49 minor

E/ActivityManager(   96):   0% 158/com.android.systemui: 0% user + 0% kernel

E/ActivityManager(   96):   0% 5/events/0: 0% user + 0% kernel

E/ActivityManager(   96):   0% 48/synaptics_wq: 0% user + 0% kernel

E/ActivityManager(   96):   0% 56/ds2784-battery: 0% user + 0% kernel

E/ActivityManager(   96): 96% TOTAL: 96% user + 0.3% kernel

E/ActivityManager(   96): CPU usage from 378ms to 893ms later:

E/ActivityManager(   96):   94% 24622/com.marie.mainactivity: 94% user + 0% kernel

E/ActivityManager(   96):     94% 24622/ie.mainactivity: 94% user + 0% kernel

E/ActivityManager(   96):   3.8% 96/system_server: 1.9% user + 1.9% kernel

E/ActivityManager(   96):     3.8% 115/ActivityManager: 1.9% user + 1.9% kernel

E/ActivityManager(   96):   1.3% 73/akmd: 0% user + 1.3% kernel

E/ActivityManager(   96):     1.3% 24209/akmd: 0% user + 1.3% kernel

E/ActivityManager(   96): 100% TOTAL: 98% user + 1.9% kernel

I/Process (   96): Sending signal. PID: 24622 SIG: 9

W/ActivityManager(   96):   Force finishing activity com.marie.mainactivity/.MainActivity

I/ActivityManager(   96): Killing com.marie.mainactivity (pid=24622): user's request

I/ActivityManager(   96): Process com.marie.mainactivity (pid 24622) has died.

W/ActivityManager(   96): Service crashed 2 times, stopping: ServiceRecord{4078d160 com.marie.mainactivity/.BackgroundService}

I/WindowManager(   96): WIN DEATH: Window{407b7a70 com.marie.mainactivity/com.marie.mainactivity.MainActivity paused=true}

V/RenderScript_jni(  192): surfaceCreated

V/RenderScript_jni(  192): surfaceChanged

W/InputManagerService(   96): Got RemoteException sending setActive(false) notification to pid 24622 uid 10081

I/ActivityManager(   96): Start proc com.amazon.mp3 for service com.amazon.mp3/.service.DownloadService: pid=24632 uid=10055 gids={3003, 1015}

I/ActivityThread(24632): Pub com.amazon.mp3.client.SearchSuggestionProvider: com.amazon.mp3.client.SearchSuggestionProvider

D/Configuration(24632): active site = local

D/FREESPACE(24632): Bytes to fill: 107900928

D/Configuration(24632): active site = remote

I/Gmail   (24587): calculateUnknownSyncRationalesAndPurgeInBackground: queueing

I/Gmail   (24587): calculateUnknownSyncRationalesAndPurgeInBackground: running

I/Gmail   (24587): MainSyncRequestProto: lowestBkwdConvoId: 0, highestHandledServerOp: 687539, normalSync: true

D/dalvikvm(24587): GC_CONCURRENT freed 1165K, 54% free 3133K/6727K, external 1625K/2137K, paused 3ms+4ms

D/dalvikvm(24587): GC_CONCURRENT freed 617K, 55% free 3081K/6727K, external 1625K/2137K, paused 11ms+2ms

D/dalvikvm(24587): GC_EXPLICIT freed 160K, 55% free 3083K/6727K, external 1625K/2137K, paused 54ms

I/Gmail   (24587): MainSyncRequestProto: lowestBkwdConvoId: 0, highestHandledServerOp: 687616, normalSync: true

D/Gmail   (24587): Inserting message 1371513932623117837. synced=true

D/dalvikvm(24587): GC_EXPLICIT freed 123K, 54% free 3127K/6727K, external 1625K/2137K, paused 63ms

I/Gmail   (24587): MainSyncRequestProto: lowestBkwdConvoId: 0, highestHandledServerOp: 687618, normalSync: true

I/Gmail   (24587): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://gmail-ls/unread/^i (has extras) }

I/AudioService(   96):  AudioFocus  requestAudioFocus() from android.media.AudioManager@4074e410

W/AudioFlinger(   68): write blocked for 167 msecs, 27 delayed writes, thread 0xea00

I/AudioService(   96):  AudioFocus  abandonAudioFocus() from android.media.AudioManager@4074e410

D/AudioHardwareQSD(   68): AudioHardware pcm playback is going to standby.

D/dalvikvm(24587): GC_EXPLICIT freed 88K, 54% free 3138K/6727K, external 1625K/2137K, paused 98ms

I/ActivityManager(   96): Start proc org.my_pod.mypod for service org.my_pod.mypod/net.robmunro.mypod.UpdateFeedsService: pid=24654 uid=10080 gids={3003, 1015}

D/dalvikvm(   67): GC_EXPLICIT freed 11K, 50% free 2717K/5379K, external 1625K/2137K, paused 68ms

D/dalvikvm(   67): GC_EXPLICIT freed <1K, 50% free 2717K/5379K, external 1625K/2137K, paused 63ms

I/ActivityThread(24654): Pub org.my_pod.mypod: net.robmunro.mypod.util.MyPodContentProvider

D/dalvikvm(   67): GC_EXPLICIT freed <1K, 50% free 2717K/5379K, external 1625K/2137K, paused 74ms

Any advice with what I am doing wrong creating a Service instance so I can pass it things like a handler would be greatly appreciated.


I would recommend passing a Messenger to the service and using it to send a Message to the Handler. Here is a sample application demonstrating this.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜