官方aidl 自我理解

来源:互联网 发布:淘宝品牌信息怎么写 编辑:程序博客网 时间:2024/05/17 06:21


官方指导:http://developer.android.com/guide/developing/tools/aidl.html、http://developer.android.com/guide/topics/fundamentals/bound-services.html#Messenger

官方提示aidl的应用场景:

Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Servicesbefore implementing an AIDL.

google翻译:

注意:如果你允许来自不同应用程序客户端来访问您的服务为IPC和要处理多线程在你的服务,使用AIDL必要的如果你不需要执行并发的IPC在不同的应用,你应该创建你的界面,通过粘合剂或,如果你想执行IPC,但并不需要处理多线程,实现你的接口使用的Messenger。无论如何,要确保您了解在实施一个AIDL绑定服务


根据上面的提示,我们可以建一个服务端,一个客户端,需要注意下结构,如下:

                                                      


根据官方文档提示的aidl我们需要做如下一些事:

You must define your AIDL interface in an .aidl file using the Java programming language syntax, then save it in the source code (in the src/ directory) of both the application hosting the service and any other application that binds to the service.
When you build each application that contains the .aidl file, the Android SDK tools generate an IBinder interface based on the .aidl file and save it in the project's gen/ directory. The service must implement the IBinder interface as appropriate. The client applications can then bind to the service and call methods from the IBinder to perform IPC.

To create a bounded service using AIDL, follow these steps:

  1. Create the .aidl file

    This file defines the programming interface with method signatures.

  2. Implement the interface

    The Android SDK tools generate an interface in the Java programming language, based on your .aidl file. This interface has an inner abstract class named Stub that extends Binder and implements methods from your AIDL interface. You must extend the Stub class and implement the methods.

  3. Expose the interface to clients

    Implement a Service and override onBind() to return your implementation of the Stub class.

package com.teleca.aidl;interface IMyService {int add(int a,int b);}

package com.teleca.service;import com.teleca.aidl.IMyService;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class AidlService extends Service{private static final String TAG="AIDLService";@Overridepublic void onStart(Intent intent, int startId) {Log("onStart");super.onStart(intent, startId);}private void Log(String str) {  android.util.Log.d(TAG, "------ " + str + "------");    }@Overridepublic IBinder onBind(Intent intent) {Log("OnBind()");return remoteBinder;}@Override      public void onDestroy() {          Log("service on destroy");          super.onDestroy();      }      @Override      public boolean onUnbind(Intent intent) {          Log("service on unbind");          return super.onUnbind(intent);      }      public void onRebind(Intent intent) {          Log("service on rebind");          super.onRebind(intent);      } private IMyService.Stub remoteBinder = new IMyService.Stub() {public int add(int a, int b) throws RemoteException {return a+b;}};}

package com.teleca;import com.teleca.aidl.IMyService;import com.teleca.service.AidlService;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.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class AIDLActivity extends Activity {TextView tv;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        tv = (TextView) findViewById(R.id.tv);        Button btn =  (Button) findViewById(R.id.startBtn);        btn.setOnClickListener(new OnClickListener() {public void onClick(View v) {Intent intent = new Intent(AIDLActivity.this,AidlService.class);bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);}});    }    private static final String TAG = "AIDLActivity";     IMyService myservice ;    int result ;    private ServiceConnection serviceConnection = new ServiceConnection() {public void onServiceDisconnected(ComponentName name) {Log("disconnect service");  myservice = null;  }public void onServiceConnected(ComponentName name, IBinder service) {myservice = IMyService.Stub.asInterface(service);try {result = myservice.add(10, 20);tv.setText(result+"");} catch (RemoteException e) {e.printStackTrace();}}};@Overrideprotected void onDestroy() {unbindService(serviceConnection);super.onDestroy();}private void Log(String str) {      android.util.Log.d(TAG, "------ " + str + "------");  }  }
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.teleca"      android:versionCode="1"      android:versionName="1.0">    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity android:label="@string/app_name" android:name="AIDLActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity> <service android:name=".service.AidlService" android:process=":remote"> </service>    </application></manifest> 


我们需要好好看那个官方文档,正常你在网上看到的帖子都是基于理解了官方了然后在自己测试的和总结的,所以我们还是看官方避免理解的偏差,官方中说道了很多比如那个aidl文件会生成java的文件在Eclipse下面,等等,再比如上面服务对象的获取,都是有官方提示,见下面,所以我们需要好好琢磨官方的文字:

Now, when a client (such as an activity) calls bindService() to connect to this service, the client's onServiceConnected() callback receives the mBinder instance returned by the service's onBind() method.
The client must also have access to the interface class, so if the client and service are in separate applications, then the client's application must have a copy of the .aidl file in its src/ directory (which generates the android.os.Binder interface—providing the client access to the AIDL methods).
When the client receives the IBinder in the onServiceConnected() callback, it must call YourServiceInterface.Stub.asInterface(service) to cast the returned parameter to YourServiceInterface type. 


上面涉及到的服务知识复习下:startService与bindService有什么区别?

具体见官方说明:http://developer.android.com/guide/topics/fundamentals/services.html  官方的意思在google翻译不是太好,下面是网上的朋友的说明基本上是按官方的说明来理解的,共享给大家。

Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy 
我们有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。
1 通过startService 
    Service会经历 onCreate --> onStart 
    stopService的时候直接onDestroy 
   如果是 调用者 直接退出而没有调用stopService的话,Service会一直在后台运行。 
   下次调用者再起来仍然可以stopService。
2 通过bindService    
    Service只会运行onCreate, 这个时候 调用者和Service绑定在一起 
   调用者退出了,Srevice就会调用onUnbind-->onDestroyed 

   所谓绑定在一起就共存亡了。 


注意:Service的onCreate的方法只会被调用一次,
就是你无论多少次的startService又 bindService,Service只被创建一次。
如果先是bind了,那么start的时候就直接运行Service的onStart方法,
如果先是start,那么bind的时候就直接运行onBind方法。如果你先bind上了,就stop不掉了,
只能先UnbindService, 再StopService,所以是先start还是先bind行为是有区别的。 
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。
这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,
即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,
接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,
但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,
接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,
接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,
多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。
如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法.


原创粉丝点击