Should onHandleIntent be called when IntentService is started with bindService?

喜欢而已 提交于 2019-12-21 18:56:09

问题


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 an Intent extra in the command sent by startService(), 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 a Notification 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!