Android - Использование метода из службы в деятельности? - PullRequest
13 голосов
/ 16 февраля 2010

У меня в приложении есть следующий метод в Службе:

public void switchSpeaker(boolean speakerFlag){

        if(speakerFlag){
        audio_service.setSpeakerphoneOn(false);
        }
        else{
        audio_service.setSpeakerphoneOn(true);
        }

    }

Итак, мой вопрос: каков наилучший и наиболее эффективный способ использования этого метода в задании, подобном следующему

final Button speaker_Button = (Button) findViewById(R.id.widget36);

            speaker_Button.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){

                    switchSpeaker(true); //method from Service

                }

            });

Должен ли я сделать AIDL или есть более простой способ?

Ответы [ 3 ]

70 голосов
/ 29 мая 2012

Существует 3 способа привязки сервиса к вашей деятельности.

  1. Внедрение IBinder
  2. Использование Messanger
  3. Использование AIDL

Среди этих вариантов реализации IBinder - лучший вариант в вашем случае

Пример класса IBinder

1.Служба Server.java

public class Server extends Service{

    IBinder mBinder = new LocalBinder();


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

    public class LocalBinder extends Binder {
        public Server getServerInstance() {
            return Server.this;
        }
    }

    public void switchSpeaker(boolean speakerFlag){

        if(speakerFlag){
        audio_service.setSpeakerphoneOn(false);
        }
        else{
        audio_service.setSpeakerphoneOn(true);
        }

    }
}

2.Client.java Деятельность

public class Client extends Activity {

boolean mBounded;
Server mServer;
TextView text;
Button button;

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

text = (TextView)findViewById(R.id.text);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            mServer.switchSpeaker(true);
        }
    });

}

@Override
protected void onStart() {
    super.onStart();
    Intent mIntent = new Intent(this, Server.class);
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};

ServiceConnection mConnection = new ServiceConnection() {

    public void onServiceDisconnected(ComponentName name) {
        Toast.makeText(Client.this, "Service is disconnected", 1000).show();
        mBounded = false;
        mServer = null;
    }

    public void onServiceConnected(ComponentName name, IBinder service) {
        Toast.makeText(Client.this, "Service is connected", 1000).show();
        mBounded = true;
        LocalBinder mLocalBinder = (LocalBinder)service;
        mServer = mLocalBinder.getServerInstance();
    }
};

@Override
protected void onStop() {
    super.onStop();
    if(mBounded) {
        unbindService(mConnection);
        mBounded = false;
    }
};
}

Пример класса Messanger

1.Служба server.java

public class Server extends Service{

    Messenger messenger = new Messenger(new LocalHandler());
    Messenger clientMessenger;
    static final int SysterTime = 0;
    static final int AddHandler = 1;
    List<Handler> mHandlers;

    @Override
    public void onCreate() {
        super.onCreate();
        mHandlers = new ArrayList<Handler>();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }

    public class LocalHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case SysterTime:
                SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    clientMessenger.send(Message.obtain(null, SysterTime, mDateFormat.format(new Date())));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;

            case AddHandler:
                clientMessenger = new Messenger((Handler) msg.obj);
                try {
                    clientMessenger.send(Message.obtain(null, AddHandler, "Registed messanger"));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;

            default:
                break;
            }
            super.handleMessage(msg);
        }
    }
}

2.Client.java Активность

public class Client extends Activity {

    Messenger messenger;
    boolean mBounded;
    TextView text;
    Button button;
    Button register;


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

        text = (TextView)findViewById(R.id.text);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Message message = Message.obtain(null, Server.SysterTime, null);
                try {
                    messenger.send(message);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

        register = (Button) findViewById(R.id.register);
        register.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Message message = Message.obtain(null, Server.AddHandler, new ClientHandle());
                try {
                    messenger.send(message);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

    }


    public class ClientHandle extends Handler {

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case Server.SysterTime:
                text.setText(msg.obj.toString());
                break;

            case Server.AddHandler:
                text.setText(msg.obj.toString());
                break;

            default:
                break;
            }

            super.handleMessage(msg);
        }


    }

    @Override
    protected void onStart() {
        super.onStart();

        bindService(new Intent(this, Server.class), mConnection, BIND_AUTO_CREATE);
    }



    @Override
    protected void onStop() {
        super.onStop();
        if(mBounded) {
            unbindService(mConnection);
        }
    }



    ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {
            mBounded = false;
            messenger = null;
        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(Client.this, "Service is connected", 1000).show();
            messenger = new Messenger(service);
            mBounded = true;
        }
    };
}

Пример AIDL

1.IRemoteService.aidl

package com.example.bindservice.aidl;

interface IRemoteService {

    String getMessage(String msg);
}

2.Служба Server.java

public class Server extends Service{

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

    IRemoteService.Stub mStub = new IRemoteService.Stub() {

        public String getMessage(String msg) throws RemoteException {
            return msg;
        }
    };
}

3.Client.java Деятельность

public class Client extends Activity {

    Button button;
    TextView text;
    boolean mBound;
    IRemoteService mIRemoteService;
    EditText etMsg;

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

        text = (TextView)findViewById(R.id.text);
        button = (Button) findViewById(R.id.button);
        etMsg = (EditText)findViewById(R.id.etMsg);
        button.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                if(mBound) {
                    try {
                        text.setText(mIRemoteService.getMessage(etMsg.getText().toString()));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }                   
                }
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        bindService(new Intent(Client.this, Server.class), mConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mBound) {
            unbindService(mConnection);
            mBound = false; 
        }
    }

    ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceDisconnected(ComponentName name) {
            mIRemoteService = null;
            mBound = false;
        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            mIRemoteService = IRemoteService.Stub.asInterface(service);
            mBound = true;
        }
    };
}

Для получения дополнительной информации вы можете обратиться этот документ

3 голосов
/ 16 февраля 2010

Это публично, верно:)

Вы можете вызвать метод bindService (Intent).Рассмотрим ApiDemos, класс LocalServiceBinding.

В методе обратного вызова onServiceConnected вы можете увидеть:

    public void onServiceConnected(ComponentName className, IBinder service) {
        // This is called when the connection with the service has been
        // established, giving us the service object we can use to
        // interact with the service.  Because we have bound to a explicit
        // service that we know is running in our own process, we can
        // cast its IBinder to a concrete class and directly access it.
        mBoundService = ((LocalService.LocalBinder)service).getService();

        // Tell the user about this for our demo.
        Toast.makeText(LocalServiceBinding.this, R.string.local_service_connected,
                Toast.LENGTH_SHORT).show();
    }

Теперь используйте объект службы (mBoundService) для вызова метода.1008 *

Вот и все:)

3 голосов
/ 16 февраля 2010

Вы должны предоставить сервису метод switchSpeaker для клиентов. Определите ваш .aidl файл. Затем привяжите эту услугу к своей деятельности и просто позвоните switchSpeaker См. документацию

Нет другого простого способа вызвать этот метод, только если он статический)

...