Bound Service using Intentservice

Asked

Viewed 166 times

1

I am creating an Intentservice with Binder, so I can communicate with that service from an Activity


public class MyService extends IntentService {
    private ChatManager chatManager;
    private final IBinder mBinder = new MyBinder();

    public MyService() {
        super("MyService");
    }


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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if(chatManager == null) chatManager = new ChatManager();
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if(chatManager != null) {
            chatManager.encerraChatManager();
        }
    }

      public class MyBinder extends Binder{
        public ChatManager getService() {
            return chatManager;
        }
    }
}

In my activity, in the onCreate method I call

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

And in the onServiceConnected method I get the chatManager object


    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder) {
        chatManager = ((ChatService.ChatBinder)iBinder).getService();
    }

As my chatManager method was instantiated in a background thread I expected it to continue running in the background, but it is not. When I call any chatManager method it runs in the main thread.

What I’m doing wrong or what concept I didn’t understand of Intentservice on android?


EDITION 31/07/2017 Chatmanager Class Explanation

Chatmanager opens a connection to the Realm database (Realm.io). With an open connection, I can add messages to the chat, end the chat, change status, etc. With this I want to not have to open a connection to the bank for every new change in the bank, which is very frequent and consumes many resources.

On the other hand, I can not make the recordings in the direct bank in the main thread, as it is causing slowness and even locking the app.

Chatmanager


    public class ChatManager {
    private Realm db;
    private Chat chat;

    public ChatManager() {
        db = Realm.getDefaultInstance(); // Uma instancia do banco de dados Realm
    }


    /**
     * Vários método que tem essa estrutura
     */
    public void metodoGernerico(Object param) {
        db.executeTransaction(realm -> {
            // altera o banco de dados
        });
    }

    /**
     * Fecha o banco de dados quando sai da activity
     */
    public void encerraChatManager() {
        db.close();
    }
}

1 answer

0

Ibinder should not be used with Intentservice.

The purpose of Intentservice is to perform only one task.
It is destroyed soon after the method onHandleIntent() break up.
I find it strange that the method onServiceConnected() be called.

As I don’t know the purpose of the Chatmanager little more I can advance.

One possible situation would be for Chatmanager to run each of its methods in another thread or possibly use Intentservice’s to execute them.

Another is to create one Bound Service whose methods delegate to Chatmanager the operations to be performed.
Use Ibinder to get the Service.

Anything like that:

public class LocalService extends Service {

    private final IBinder mBinder = new LocalBinder();
    private chatManager = new ChatManager();

    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }

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

    public void meuMetodo() {
      chatManager.meuMetodo();
    }
}
  • Thanks for the reply, , Chatmanager opens a connection to the Realm database (https://realm.io). With an open connection, I can add messages to the chat, end the chat, change status, etc. .

  • I was already editing the answer when I saw your comment. In this case maybe it’s best to implement Chatmanager as Singleton.

  • Hi @ramaral, I think I screwed up here, I changed something that I didn’t write. Well, about Singleton, it just doesn’t run in Background. If I try to record to the database directly in the main thread, the app hangs or slows down. As I am instantiating Chatmanager in a service and the service is Singleton I saw no need to have Chatmanager as Singleton. How then Singleton will help me in this scenario?

  • I’ve never worked with Realm but if I remember correctly he has asynchronous methods(executeTransactionAsync()) to interact with the bank.

  • Yes, there is, but then you enter the situation I’m trying to avoid, for every transaction a bank opening. In the documentation there is the recommendation to keep the connection open for a situation of many recordings. Realm also has a very important condition: a connection can only be used by the thread that created it. I cannot use method executeTransactionAsync to change any object (chat in my case) that has been created in another thread.

  • I advise you to study the documentation better because I think it is not true that "for each transaction a bank opening".

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.