• [转]aidl高级应用篇


    aidl当中回调函数的使用

    分类: android 254人阅读 评论(0) 收藏 举报

    本篇直接给代码实现在service端回调client端的方法,如对aidl还不清楚的,请参考另外一篇文章http://blog.csdn.net/tianyouyu0/article/details/7337837


    首先建立在server端建立两个aidl文件

    ITaskCallback.aidl 用于存放要回调client端的方法

    1. package com.cmcc.demo.server;   
    2.   
    3. interface ITaskCallback {   
    4.     void actionPerformed(int actionId);  
    5. }   

    ITaskBinder.aidl 用于存放供给client端调用的方法

    1. package com.cmcc.demo.server;   
    2.   
    3. import com.cmcc.demo.server.ITaskCallback;   
    4.   
    5. interface ITaskBinder {   
    6.     boolean isTaskRunning();   
    7.     void stopRunningTask();   
    8.     void registerCallback(ITaskCallback cb);   
    9.     void unregisterCallback(ITaskCallback cb);   
    10. }  

    接着建立服务端,要实现回调,需要新建RemoteCallbackList对象(一个存储回调对象的列表),通过类似发送广播的形式来实现回调

    MyService.java

    1. package com.cmcc.demo.server;   
    2.   
    3. import com.cmcc.demo.server.ITaskBinder;  
    4. import com.cmcc.demo.server.ITaskCallback;  
    5.   
    6. import android.app.Service;   
    7. import android.content.Intent;   
    8. import android.os.IBinder;   
    9. import android.os.RemoteCallbackList;   
    10. import android.os.RemoteException;   
    11. import android.util.Log;   
    12.   
    13. public class MyService extends Service {   
    14.     private static final String TAG = "aidltest";  
    15.   
    16.     @Override   
    17.     public void onCreate() {   
    18.         printf("service create");   
    19.     }  
    20.       
    21.     @Override   
    22.     public void onStart(Intent intent, int startId) {  
    23.         printf("service start id=" + startId);  
    24.         callback(startId);   
    25.     }  
    26.       
    27.     @Override  
    28.     public IBinder onBind(Intent t) {  
    29.         printf("service on bind");  
    30.         return mBinder;   
    31.     }  
    32.       
    33.     @Override  
    34.     public void onDestroy() {   
    35.         printf("service on destroy");   
    36.         super.onDestroy();   
    37.     }  
    38.       
    39.     @Override  
    40.     public boolean onUnbind(Intent intent) {   
    41.         printf("service on unbind");  
    42.         return super.onUnbind(intent);   
    43.     }  
    44.       
    45.     public void onRebind(Intent intent) {   
    46.         printf("service on rebind");  
    47.         super.onRebind(intent);   
    48.     }  
    49.       
    50.     private void printf(String str) {   
    51.         Log.v(TAG, "###################------ " + str + "------");   
    52.     }  
    53.       
    54.     void callback(int val) {   
    55.         final int N = mCallbacks.beginBroadcast();  
    56.         for (int i=0; i<N; i++) {   
    57.             try {  
    58.                 mCallbacks.getBroadcastItem(i).actionPerformed(val);   
    59.             }  
    60.             catch (RemoteException e) {   
    61.                 // The RemoteCallbackList will take care of removing   
    62.                 // the dead object for us.     
    63.             }  
    64.         }  
    65.         mCallbacks.finishBroadcast();  
    66.     }  
    67.       
    68.     private final ITaskBinder.Stub mBinder = new ITaskBinder.Stub() {  
    69.           
    70.         public void stopRunningTask() {  
    71.               
    72.         }  
    73.       
    74.         public boolean isTaskRunning() {   
    75.             return false;   
    76.         }   
    77.           
    78.         public void registerCallback(ITaskCallback cb) {   
    79.             if (cb != null) {   
    80.                 mCallbacks.register(cb);  
    81.             }  
    82.         }  
    83.           
    84.         public void unregisterCallback(ITaskCallback cb) {  
    85.             if(cb != null) {  
    86.                 mCallbacks.unregister(cb);  
    87.             }  
    88.         }  
    89.     };   
    90.       
    91.     final RemoteCallbackList <ITaskCallback>mCallbacks = new RemoteCallbackList <ITaskCallback>();  
    92.   
    93. }   

    最后建立客户端,使用aidl,实现回调方法。

    MyActivity.java

    1. package com.cmcc.demo;   
    2.   
    3. import android.app.Activity;   
    4. import android.content.ComponentName;   
    5. import android.content.Intent;   
    6. import android.content.ServiceConnection;   
    7. import android.os.Bundle;   
    8. import android.os.IBinder;   
    9. import android.os.RemoteException;   
    10. import android.util.Log;   
    11. import android.view.View;   
    12. import android.view.View.OnClickListener;   
    13. import android.widget.Button;   
    14.   
    15. import com.cmcc.demo.server.*;  
    16.   
    17. public class MyActivity extends Activity {   
    18.   
    19.     private static final String TAG = "aidltest";  
    20.     private Button btnOk;   
    21.     private Button btnCancel;  
    22.   
    23. @Override   
    24. public void onCreate(Bundle icicle) {   
    25.     super.onCreate(icicle);   
    26.     setContentView(R.layout.test_service);   
    27.       
    28.     btnOk = (Button)findViewById(R.id.btn_ok);  
    29.     btnCancel = (Button)findViewById(R.id.btn_cancel);   
    30.     btnOk.setText("Start Service");   
    31.     btnCancel.setText("Stop Service");   
    32.     btnCancel.setEnabled(false);  
    33.       
    34.     btnOk.setOnClickListener(new OnClickListener() {  
    35.             public void onClick(View v) {  
    36.                 onOkClick();  
    37.             }  
    38.         });   
    39.       
    40.     btnCancel.setOnClickListener(new OnClickListener() {  
    41.             public void onClick(View v) {  
    42.                 onCancelClick();  
    43.             }  
    44.         });  
    45.     }   
    46.   
    47.     void onOkClick() {  
    48.         printf("send intent to start");   
    49.         Bundle args = new Bundle();  
    50.         Intent intent = new Intent("com.cmcc.demo.IMyService");  
    51.         intent.putExtras(args);  
    52.         startService(intent);  
    53.         //bindService(intent, mConnection, Context.BIND_AUTO_CREATE);  
    54.         btnCancel.setEnabled(true);  
    55.     }   
    56.       
    57.     void onCancelClick() {   
    58.           
    59.         printf("send intent to stop");  
    60.         //unbindService(mConnection);  
    61.         Intent intent = new Intent("com.cmcc.demo.IMyService");  
    62.         stopService(intent);   
    63.         btnCancel.setEnabled(false);  
    64.     }   
    65.       
    66.     private void printf(String str) {   
    67.         Log.v(TAG, "###################------ " + str + "------");   
    68.     }  
    69.       
    70.     ITaskBinder mService;   
    71.       
    72.     private ServiceConnection mConnection = new ServiceConnection() {   
    73.           
    74.         public void onServiceConnected(ComponentName className, IBinder service) {  
    75.             mService = ITaskBinder.Stub.asInterface(service);   
    76.             try {   
    77.                 mService.registerCallback(mCallback);  
    78.             } catch (RemoteException e) {  
    79.                   
    80.             }  
    81.         }  
    82.           
    83.         public void onServiceDisconnected(ComponentName className) {   
    84.             mService = null;  
    85.         }   
    86.     };   
    87.       
    88.     private ITaskCallback mCallback = new ITaskCallback.Stub() {  
    89.           
    90.         public void actionPerformed(int id) {   
    91.             printf("callback id=" + id);  
    92.         }   
    93.     };   
    94.   
    95. }   

    总结一下aidl的使用

    AIDL的创建方法: 
    AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。由于远程调用的需要, 这些参数和返回值并不是任何类型.下面是些AIDL支持的数据类型: 
    1. 不需要import声明的简单Java编程语言类型(int,boolean等) 
    2. String, CharSequence不需要特殊声明 

    3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型. 
    ( 
    (另外: 我没尝试Parcelables, 在Eclipse+ADT下编译不过, 或许以后会有所支持). 
    下面是AIDL语法: 
    // 文件名: SomeClass.aidl // 文件可以有注释, 跟java的一样 // 在package以前的注释, 将会被忽略. // 函数和变量以前的注释, 都会被加入到生产java代码中. package com.cmcc.demo; 
    // import 引入语句 import com.cmcc.demo.ITaskCallback; 

    interface ITaskBinder { 
    //函数跟java一样, 可以有0到多个参数 ,可以有一个返回值 boolean isTaskRunning(); 
    void stopRunningTask(); //参数可以是另外的一个aidl定义的接口 void registerCallback(ITaskCallback cb); 
    void unregisterCallback(ITaskCallback cb); 
    //参数可以是String, 可以用in表入输入类型, out表示输出类型. 
    int getCustomerList(in String branch, out String customerList); 
    } 

    实现接口时有几个原则: 
    .抛出的异常不要返回给调用者. 跨进程抛异常处理是不可取的. 
    .IPC调用是同步的如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。 也就是IPC调用会挂起应用程序导致界面失去响应. 这种情况应该考虑单起一个线程来处理. 
    .不能在AIDL接口中声明静态属性。 

    IPC的调用步骤: 
    1. 声明一个接口类型的变量,该接口类型在.aidl文件中定义。 
    2. 实现ServiceConnection。 
    3. 调用ApplicationContext.bindService(),并在ServiceConnection实现中进行传递. 
    4. 在ServiceConnection.onServiceConnected()实现中,你会接收一个IBinder实例(被调用的Service). 调用 YourInterfaceName.Stub.asInterface((IBinder)service)将参数转换为YourInterface类 型。 
    5. 调用接口中定义的方法。 你总要检测到DeadObjectException异常,该异常在连接断开时被抛出。它只会被远程方法抛出。 
    6. 断开连接,调用接口实例中的ApplicationContext.unbindService() 

    转载地址:http://blog.csdn.net/tianyouyu0/article/details/7537281


    有些东西会,但不精通,而我现在要做的就是精通,复习回顾,整理自己的框架,举一反三。。。
  • 相关阅读:
    /etc/fstab详解
    awk的简单用法2
    awk的简单用法3
    linux+nginx+mysql+php高性能服务器搭建
    awk的简单用法1
    ip_conntrack: table full, dropping packet.解决办法
    快速获得 Google Maps 地图页中心位置的经纬度
    Google 地图 教程收集
    第一章 Google Api Key的申请
    第二章 Google 常用功能
  • 原文地址:https://www.cnblogs.com/liuzenglong/p/2837671.html
Copyright © 2020-2023  润新知