问题
My service extends IntentService
and when it is started with startService
, onHandleIntent
gets called. However, when the service is started with bindService
(I do need binding), onHandleIntent
does not get called.
Should onHandleIntent
be called when IntentService
is started with bindService
? Is startService
the only way IntentService
should be started?
The documentation for IntentService
says the following:
Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Currently I solve my problem by calling startService
right after bindService
but I find it ugly. I would like to know is there a way to make it work with just one call.
Code snippets follow, it might be that I am missing something obvious.
ExampleService.java
public class ExampleService extends IntentService {
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (message.replyTo != null) {
outMessenger = message.replyTo;
}
}
}
private Messenger messenger = new Messenger(new IncomingHandler());
private Messenger outMessenger = null;
public ExampleService() {
super("ExampleService");
}
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
@Override
protected void onHandleIntent(Intent arg0) {
System.out.println("Service started");
for (int i = 0; i < 5; i++) {
SystemClock.sleep(5000);
if (outMessenger != null) {
try {
outMessenger.send(Message.obtain());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Service Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.service"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="3"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".ExampleService">
<intent-filter>
<action android:name="com.example.service.ExampleService" />
</intent-filter>
</service>
</application>
</manifest>
MainActivity.java (caller)
public class MainActivity extends Activity implements ServiceConnection {
private class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Toast.makeText(getApplicationContext(), "Message received", Toast.LENGTH_SHORT).show();
System.out.println("Message received!");
super.handleMessage(msg);
}
}
private Messenger messenger = new Messenger(new IncomingHandler());
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.service.ExampleService");
bindService(intent, MainActivity.this, Context.BIND_AUTO_CREATE);
//startService(intent);
}
});
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Message message = Message.obtain();
message.replyTo = messenger;
try {
new Messenger(binder).send(message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
回答1:
Should onHandleIntent be called when IntentService is started with bindService?
No.
Is startService the only way IntentService should be started?
IMHO, yes. IMHO, IntentService
is not designed for the binding pattern.
In your case, you can:
- Pass a
Messenger
from the activity in anIntent
extra in the command sent bystartService()
, or - Use
LocalBroadcastManager
, or - Use Otto, or
- Use an ordered broadcast, if the
IntentService
might continue past the activity's life and you want to, say, display aNotification
when the work gets done in that case, - Etc.
回答2:
You must call both startService and bindService. This was worked for me.
来源:https://stackoverflow.com/questions/12498919/should-onhandleintent-be-called-when-intentservice-is-started-with-bindservice