A remote service is not the way to solve an ANR -- you are just moving the ANR into another process (and hiding it because if that process isn't doing UI, it can still ANR when background requests are being made of it and in that case we just kill it rather than bothering the user).
A Service is basically to tell the system that your process would like to be running. It doesn't do anything magical -- it is just an object that is instantiated to represent this "hey I'm doing something" state with the system and perform interactions with the system around that. It doesn't do anything more than that. It is created on the main thread and callbacks to it happen there. The same rules apply as elsewhere -- if you do some long-running work in one of these callbacks, you will block your main thread and ANR. If you are fine with your process being killed if you are doing this work and the user is no longer in one of your activities, then you actually do not want to use a Service, because the core thing a Service is doing is telling the system you do -not- want to be killed. On Wed, Jan 20, 2010 at 3:41 PM, Natalie <[email protected]> wrote: > Hi Dianne, > I initially had the service as a local service, but my application was > getting Application Not Responding messages. Since I'll never have > more than one application binding to my service, I think I'm just > going to abandon the service approach and try the approach in the > example jotobjects posted - I can't see any reason that having it as a > service is useful, but am I missing something? > Thanks!! > > > On Jan 20, 3:32 pm, Natalie <[email protected]> wrote: > > Thanks so much for the response. But if the long loop (which updates > > the field that needs to find its way to the activity) is in a > > different thread from the one that processes the showMessage call, > > won't I have to switch to doing the communication through the > > Handler? And at that point I'm beginning to wonder if it makes sense > > to bother with the service or if I should just be doing the work on > > different threads and communicating through the Handlers? Or am I > > missing something? Maybe the example you posted will clear all this > > up though, I'll look at that now. :) > > > > On Jan 20, 3:24 pm, jotobjects <[email protected]> wrote: > > > > > > > > > Hi Natalie - > > > > > Not sure what you mean by service you "spawned onto its own thread". > > > > > In any case, it looks like the Service is going to be pretty busy in > > > that while(1) loop so it is not too surprising that it is not > > > available to process the showMessage call. :) Yes they are two > > > different threads. The Activity is blocking on the call to the > > > service that is forever busy in the for loop. > > > > > I think you need to put that loop in a thread and then you need a > > > different Runnable for the handler post(). Here is an example - > > > > >http://developer.android.com/resources/faq/commontasks.html#threading > > > > > Also the serviceHandler.post(myProcess) in onCreate is a duplicate. > > > This is where you need something like startLongWhileLoop() that > > > creates a thread instead. > > > > > On Jan 20, 2:49 pm, Natalie <[email protected]> wrote: > > > > > > Thanks for the response. > > > > I'm pretty sure that's not it because I've put a debug statement > first > > > > off in the broadcast receiver's onReceive method and that isn't > > > > appearing either. It almost seems that the activity's thread just > > > > isn't getting switched to - so far I've only tested in the emulator, > > > > could the emulator not be switching back to the activity's thread? > > > > I've posted the seemingly relevant chunks of code below if that > helps. > > > > > > ACTIVITY ... > > > > public class AudioProcessor extends Activity { > > > > private AudioInterface service; > > > > private ServiceConnection svcConn = new ServiceConnection(){ > > > > public void onServiceConnected(ComponentName > className, IBinder > > > > binder){ > > > > service = > AudioInterface.Stub.asInterface(binder); > > > > } > > > > public void onServiceDisconnected(ComponentName > className){ > > > > service = null;//NL = probably do more in > onService methods > > > > } > > > > }; > > > > private BroadcastReceiver receiver = new BroadcastReceiver(){ > > > > public void onReceive(Context context, Intent > intent){ > > > > Log.d("SHOWING!!!!!!!!!!!", > "!!!!!!!!!!!!!!!!!!!"); > > > > showMessage(context, intent); > > > > } > > > > }; > > > > @Override > > > > public void onCreate(Bundle savedInstanceState) { > > > > super.onCreate(savedInstanceState); > > > > setContentView(R.layout.main); > > > > Intent serviceIntent = new Intent(this, > AudioService.class); > > > > bindService(serviceIntent, svcConn, > BIND_AUTO_CREATE); > > > > registerReceiver(receiver, new IntentFilter > > > > (AudioService.BROADCAST_ACTION)); > > > > serviceIntent.setAction > > > > ("com.linnell.audioprocessor.AudioService"); > > > > startService(serviceIntent);*/ > > > > } > > > > public void showMessage(Context context, Intent intent){ > > > > Log.d("SHOWING!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!"); > > > > try{ > > > > String message = service.showMessage(); > > > > new > AlertDialog.Builder(this).setTitle("Suggestion") > > > > .setMessage(message) > > > > .setNeutralButton("Close", new > DialogInterface.OnClickListener(){ > > > > public void onClick(DialogInterface > dlg, int sumthin){ > > > > //do nothing - it will close > on its own > > > > } > > > > }) > > > > .show(); > > > > } > > > > catch(final Throwable t){ > > > > Log.e("ERROR", "ERROR IN CODE"); > > > > svcConn.onServiceDisconnected(null); > > > > }}} > > > > > > SERVICE ... > > > > public static final String BROADCAST_ACTION = "new_message"; > > > > private Intent broadcast = new Intent(BROADCAST_ACTION); > > > > private Handler serviceHandler; > > > > private Process myProcess; > > > > public IBinder onBind(Intent intent) { > > > > return mBinder; > > > > } > > > > > > @Override public void onCreate() { > > > > super.onCreate(); > > > > myProcess = new Process(); > > > > serviceHandler = new Handler(); > > > > serviceHandler.post(myProcess); > > > > } > > > > @Override public void onDestroy() { > > > > super.onDestroy(); > > > > shutdownService(); > > > > } > > > > private final AudioInterface.Stub mBinder = new > AudioInterface.Stub() > > > > { > > > > public String showMessage(){ > > > > serviceHandler.post(myProcess); > > > > return message; > > > > } > > > > public void stopService(){} > > > > > > }; > > > > class Process implements Runnable{ > > > > public void run(){ > > > > //run then sits on a while(1), occasionally doing a sendBroadcast > > > > (broadcast); > > > > > > I know a lot of the stuff in onCreate would be better in onResume, > etc > > > > - I'm planning on cleaning all this up once the functionality is > > > > there. :) > > > > > > On Jan 20, 2:21 pm, Kevin Duffey <[email protected]> wrote: > > > > > > > I am not entirely sure if I understand.. but is it possible when > you raise > > > > > the alert dialog, it's a different activity and that may be why it > seems > > > > > it's not working? Maybe you have to do something in the alert > dialog... or > > > > > maybe it blocks the main activity thread and that is why? > > > > > > > On Wed, Jan 20, 2010 at 2:10 PM, Natalie <[email protected]> > wrote: > > > > > > Hi everyone, > > > > > > I'm hoping to do some audio processing in a remote service > (service > > > > > > I've spawned onto its own thread); this will basically occur in a > while > > > > > > (1) loop - so constant processing. Occasionally I want to > provide > > > > > > some information back to the activity that is bound to the > service; > > > > > > I'm doing this by sending a broadcast from the service, that is > > > > > > received by a broadcast receiver on the activity, which then uses > the > > > > > > activity's service connection to call into the service and get > the > > > > > > information needed; at this point the broadcast receiver makes an > > > > > > alert dialog presenting the information to the user. > > > > > > If I stay in my while(1) loop after raising the broadcast, the > action > > > > > > in the broadcast receiver never seems to occur. This is > confusing to > > > > > > me since the activity and service are in separate threads. If I > end > > > > > > the loop after raising the broadcast, the desired behavior on the > > > > > > activity side occurs, but of course this isn't acceptable since I > need > > > > > > to be doing constant processing. Anyone have any suggestions of > what > > > > > > the probelm might be? > > > > > > Thanks! > > > > > > Natalie > > > > > > > > -- > > > > > > You received this message because you are subscribed to the > Google > > > > > > Groups "Android Developers" group. > > > > > > To post to this group, send email to > [email protected] > > > > > > To unsubscribe from this group, send email to > > > > > > [email protected]<android-developers%[email protected]><android-developers%2Bunsubs > [email protected]> > > > > > > For more options, visit this group at > > > > > >http://groups.google.com/group/android-developers?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected]<android-developers%[email protected]> > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en > -- Dianne Hackborn Android framework engineer [email protected] Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them.
-- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

