Android Service AIDL remote call Service [simple music playback instance]

Source: Internet
Author: User

Android Service is divided into two types:

  • Local Service: called in the same apk
  • Remote Service: called by another apk

Remote services must be completed using AIDL.

What is AIDL?

AIDL (Android Interface Definition Language) is an IDL Language used to generate code for interprocess communication (IPC) between two processes on the Android device. If you want to call operations on objects in another process (such as Service) in a process (such as Activity), you can use AIDL to generate serializable parameters.

The aidl ipc Mechanism is interface-oriented, like COM or Corba, but more lightweight. It uses a proxy class to transmit data on the client and the implementation end.

Role of AIDL

Because each application runs in its own process space and can run another service process from the application UI, objects are often transferred between different processes. On the Android platform, one process usually cannot access the memory space of another process. Therefore, to perform a conversation, you need to break down the object into basic units that the operating system can understand and orderly pass through the process boundary.

It is tedious to implement this data transmission process through code. Android provides the AIDL tool to handle this task.

Select AIDL application scenarios

The official documentation reminds us when to use AIDL is necessary: Only you allow the client to access your service from different applications for inter-process communication, and want to process multithreading in your service.

If you do not need to perform concurrent communication (IPC) between different applications, you can create your interface by implementing a Binder; or if you want to implement IPC, but do not need to process multiple threads, then implement your interface using a Messenger. Before using AIDL, you must understand how to bind service -- bindService.

The following example uses a client Activity to operate the server Service to play music to demonstrate the use of AIDL.

Development tools: eclipse 3.7 (indigo) + android sdk 4.1 + adt 00000.2

Server code structure

Client code structure

The marked items need to be started.

Server

Create an android application project named PlayerServer. Put a music file in the raw folder under res. Here I put the "Lost Without You" clip of Delta Goodrem. If the raw Folder does not exist, create one and name it raw. This folder is in the raw folder, which is the same as the layout folder. Files in raw must follow the naming rules of the mark. do not contain Chinese characters or spaces. Multiple words can be connected by underscores.

Create an IRemoteServiice. aidl file and add the following code:

package pandafang.demo.playerserver;  interface IRemoteService {      void play();      void stop();  }

It can be seen that the code of the aidl file is the same as that of the java interface, but the public modifier cannot be added in aidl. After Ctrl + S is saved, ADT will automatically generate the IRemoteService. java File Based on the IRemoteService. aidl file. As with the R. java file, the code is automatically generated under "gen/package name". Do not modify it manually.

The next step is the knowledge of the bound service (refer to the official documentation. IRemoteService. java has a Stub static abstract class extends Binder implements IRemoteService. You can manually write a PlayerService to play the music. You need to use the android. media. MediaPlayer class to play the music. The Code is as follows:

Package pandafang. demo. playerserver; import java. io. fileDescriptor; import java. io. IOException; import android. app. service; import android. content. intent; import android. media. mediaPlayer; import android. OS. IBinder; import android. OS. remoteException; import android. util. log;/*** the music playing Service * @ author Panda Fang * @ date 2012-10-22 10:15:33 */public class PlayerService extends Service {public static Final String TAG = "PlayerService"; private MediaPlayer mplayer; // implement the interface defined in the aidl file private IBinder mBinder = new IRemoteService. stub () {@ Override public void stop () throws RemoteException {try {if (mplayer. isPlaying () {mplayer. stop () ;}} catch (Exception e) {// TODO: handle exception e. printStackTrace () ;}@ Override public void play () throws RemoteException {try {if (mplayer. isPlaying ()) {Return;} // prepare is required before start. // If method 1 is used in the previous instantiation of mplayer, start directly on the first play without prepare. // But after the stop operation, play again requires prepare before start. // The preceding method 2 is easy to use. You do not need to judge various conditions of mplayer. prepare (); mplayer. start ();} catch (Exception e) {// TODO: handle exception e. printStackTrace () ;}};@ Override public IBinder onBind (Intent intent) {Log. I (TAG, "service onbind"); if (mplayer = null) {// method 1 Description // This method instantiates the player and specifies the music data source, if you use this method in, mplayer. you do not need to call mplayer before start. prepare () // The official documents are described as follows: On success, prepare () will already have been called and must not be Called again. // translated. The source code shows that the create method has called the prepare method internally. // Method 1 start // mplayer = MediaPlayer. create (this, R. raw. lost); // method 1 end // method 2 Description // if this method is used. before start (), you must call mplayer. prepare () // method 2 start mplayer = new MediaPlayer (); try {FileDescriptor fd = getResources (). openRawResourceFd (R. raw. lost ). getFileDescriptor (); // obtain the music data source mplayer. setDataSource (fd); // you can specify mplayer as the data source. setLooping (true); // set to loop playback} catch (IOException e) {// TODO Auto-generated catch bloc K e. printStackTrace ();} // method 2 end Log. I (TAG, "player created") ;}return mBinder ;}@ Override public boolean onUnbind (Intent intent) {if (mplayer! = Null) {mplayer. release ();} Log. I (TAG, "service onUnbind"); return super. onUnbind (intent );}}

After the service is compiled, add the Declaration in AndroidManifest. xml according to the Convention. The Code is as follows:

 

Note that android: process = ": remote" and intent-filter must be added.

Run the server on the device and prepare to call it to the client.

Client

Create an android application project named PlayerClient. Copy the packages with aidl files on the server side to the src directory of the client side, retain the aidl files in the package, and delete other files.

Edit the activity_main.xml layout file in layout and add two buttons. The Code is as follows:

 

Compile MainActivity. java code as follows:

Package pandafang. demo. playerclient; import pandafang. demo. playerserver. IRemoteService; import android. app. activity; import android. content. componentName; import android. content. context; import android. content. intent; import android. content. serviceConnection; import android. OS. bundle; import android. OS. IBinder; import android. OS. remoteException; import android. util. log; import android. view. menu; import android. view. view; import android. view. view. onClickListener; import android. widget. button;/*** client control interface * @ author Panda Fang * @ date 2012-10-22 10:36:44 */public class MainActivity extends Activity {public static final String TAG = "MainActivity "; // server AndroidManifest. the String declared by intent-filter action in xml is public static final String ACTION = "com. example. playerserver. playerService "; private Button playbtn, stopbtn; private IRemoteService mService; private boolean isBinded = false; private ServiceConnection conn = new ServiceConnection () {@ Override public void onServiceDisconnected (ComponentName) {isBinded = false; mService = null;} @ Override public void onServiceConnected (ComponentName, IBinder service) {mService = IRemoteService. stub. asInterface (service); isBinded = true ;};@ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); doBind (); initViews ();} private void initViews () {playbtn = (Button) findViewById (R. id. button1); stopbtn = (Button) findViewById (R. id. button2); playbtn. setOnClickListener (clickListener); stopbtn. setOnClickListener (clickListener);} @ Override public boolean onCreateOptionsMenu (Menu menu) {getMenuInflater (). inflate (R. menu. activity_main, menu); return true ;}@ Override protected void onDestroy () {doUnbind (); super. onDestroy ();} public void doBind () {Intent intent = new Intent (ACTION); bindService (intent, conn, Context. BIND_AUTO_CREATE);} public void doUnbind () {if (isBinded) {unbindService (conn); mService = null; isBinded = false;} private OnClickListener clickListener = new OnClickListener () {@ Override public void onClick (View v) {if (v. getId () = playbtn. getId () {// play Log. I (TAG, "play button clicked"); try {mService. play ();} catch (RemoteException e) {// TODO Auto-generated catch block e. printStackTrace () ;}} else {// stop Log. I (TAG, "stop button clicked"); try {mService. stop ();} catch (RemoteException e) {// TODO Auto-generated catch block e. printStackTrace ();}}}};}

MainActivity is automatically generated according to the wizard and does not need to be registered and declared in AndroidManifest. xml.

Run the client to the device, and press the button to play/stop the effect

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.