博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AIDL在android系统中的作用
阅读量:5012 次
发布时间:2019-06-12

本文共 5541 字,大约阅读时间需要 18 分钟。

AIDL,Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。最近看了下AIDL在Android系统中的用法,在网上看到很多初学的朋友不太明白AIDL的实际作用,android提供了很多进程间通信的组件,像action、broadcast、contentprovide都可以实现进程间的通信,为什么还要用AIDL这个东西呢?我在android中实现了一个自己写的AIDL例子,用以简单解释下AIDL的作用。

有开发过蓝牙或者WIFI应用的朋友肯定都知道,要去操作它必须先获得一个管理类,比如WIFI的管理类是WifiManager,通过getSystemService(Context.WIFI_SERVICE)就可以得到wifi的管理权限,这个提供了很多的方法可以让用户去操作它,比如打开wifi可以调用setWifiEnabled(true)方法。那这个Manager到底做了什么工作呢?是怎样实现打开wifi的呢?其实这个Manager只是一个管理类,真正干活的另有其人,是一个叫WifiService的系统服务。在Android系统中有很多的Manager,wifi的管理类叫WifiManager,蓝牙的管理类叫BluetoothManager,但是,只要有xxxManager.java,就会有Ixxx.aidl,并且有xxxService.java。这个aidl类就是实现Manager和Service通信的桥梁。

下面看我加的一个例子:

首先在android源码中的frameworks/base/core/java/android/os/目录下加入一个IMyTestService.aidl,一般系统的AIDL文件都放在这个目录下。

 

1
2
3
4
5
6
7
8
package
android.os;
 
/** {@hide} */
interface
IMyTestService
{
    
void
open();
    
void
close();
}

 

 

关于AIDL的语言规范我就不多说了,其实和写接口差不多(它本来就是一种接口语言)。里面只定义两个简单的方法,open和close。

然后在frameworks/base/.mk中添加一句:core/java/android/os/IMyTestService.aidl。android的编译目标是通过Android.mk来指定的,在这里加上自定义的aidl文件系统才会把这个文件编译进去,最终生成一个叫IMyTestService.java的文件。这一部分用eclipse可以很直观的看到,在项目添加了aidl文件后eclipse会自动编译此aidl,生成的文件存放在gen目录下。

AIDL添加好了后,在frameworks/base/services/java/com/android/server/目录下添加一个MyTestService.java,继承IMytestService这个aidl。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package
com.android.server;
 
import
android.net.wifi.WifiManager;
import
android.content.Context;
import
android.os.IMyTestService;
import
android.util.Log;
 
public
class
MyTestService
extends
IMyTestService.Stub {
 
   
private
static
final
String TAG =
"MyTestService"
;
   
private
Context mContext;
   
private
WifiManager mWifiManager;
 
   
public
MyTestService(Context context
/*,WindowManagerService wm*/
) {
       
super
();
       
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
   
}
 
   
/* close wifi */
   
public
void
close() {
       
mWifiManager.setWifiEnabled(
false
);
   
}
 
   
/* open wifi */
   
public
void
open() {
       
mWifiManager.setWifiEnabled(
true
);
   
}
}

 

实现aidl文件中定义的open和close方法,我这里很简单,open就是去打开wifi,close就去关闭wifi,当然,你也可以实现你自定义的功能,这个没有限制。

然后在frameworks/base/core/java/android/content/Context.java文件中加入一个静态字符串:public static final String MY_TEST_SERVICE ="my_test_service";

最后把这个服务添加到系统服务中去,在frameworks/base/services/java/com/android/server/SystemServer.java中Thread的run方法中添加下面代码:

 

 

1
2
3
4
5
6
7
try
{
                
Slog.i(TAG,
"My Test Service"
);
                
myService =
new
MyTestService(context);
                
ServiceManager.addService(Context.MY_TEST_SERVICE, myService);
            
}
catch
(Throwable e) {
                
reportWtf(
"starting my test Service"
, e);
            
}

 

myService需要在前面声明一下。

SystemService是android系统跑起来之后就会调用的,这里的意思是把MyTestService添加到系统服务中去,并取名字叫Context.MY_TEST_SERVICE,也就是my_test_service。这样看起来是不是很熟悉呢?每个开发人员在开发过程中肯定会调用系统服务的,比如电源管理服务:getSystemService(Context.POWER_SERVICE),这个Service也是在这里添加进去的。android有很多的系统服务,这里就不一一例举了,有兴趣的朋友可以自行看看这个文件。

 

现在aidl添加了,service也添加了,并且添加进了系统服务,那么还少一个Manager,可以让第三方程序调用的Manager。

在frameworks/base/core/java/android/device/目录下添加MyTestManager.java文件:

 

 

1
2
3
4
5
6
7
8
9
10
package
android.device;
import
android.util.Log;
import
android.content.Context;
import
android.os.RemoteException;
import
android.os.IMyTestService;
import
android.os.ServiceManager;
 
public
class
MyTestManager {
 
private
static
final
String TAG =
"MyTestManager"
;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private
IMyTestService mTestService;
 
    
public
MyTestManager() {
        
IMyTestService mService = IMyTestService.Stub
               
.asInterface(ServiceManager.getService(Context.MY_TEST_SERVICE));
       
mTestService = mService;
    
}
   
/**
     
* Return true if open succeed
     
* @see #open my Function()
     
*/
    
public
boolean
openScanner() {
        
try
{
            
mTestService.open();
        
}
catch
(android.os.RemoteException e) {
            
return
false
;
        
}
        
return
true
;
    
}
    
/**
     
* Return true if close succeed
     
* @see #close my Function()
     
*/
     
public
boolean
closeScanner() {
         
try
{
             
mTestService.close();
         
}
catch
(android.os.RemoteException e) {
              
return
false
;
         
}
         
return
true
;
    
}
}

 

这个Manager通过aidl的Stub获取了刚才添加的那个系统级别的service,然后在这里去调用这个service的方法,以操作service,这就是aidl的作用。

然后我们可以写一个第三方程序,获取一个MyTestManager,调用这个管理类的openScanner和closeScanner方法去实现自己在service中定义的功能。

AndroidManifest中必须要添加权限,否则报错,没有研究这个权限起的什么作用,有懂得的朋友分享一下吧。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.app.Activity;
import
android.device.MyTestManager;
 
public
class
MainActivity
extends
Activity {
    
private
Button open, close;
    
private
MyTestManager mTestManager;
 
    
@Override
    
protected
void
onCreate(Bundle savedInstanceState) {
        
super
.onCreate(savedInstanceState);
        
setContentView(R.layout.activity_main);
 
        
mTestManager =
new
MyTestManager();
        
open = (Button) findViewById(R.id.btn1);
        
open.setText(
"打开Wifi"
);
        
close = (Button) findViewById(R.id.btn2);
        
close.setText(
"关闭Wifi"
);
 
        
open.setOnClickListener(
new
OnClickListener() {
 
           
@Override
            
public
void
onClick(View v) {
                
// TODO Auto-generated method stub
                
mTestManager.openScanner();
            
}
       
});
 
        
close.setOnClickListener(
new
OnClickListener() {
 
           
@Override
            
public
void
onClick(View v) {
               
// TODO Auto-generated method stub
               
mTestManager.closeScanner();
            
}
        
});
    
}
}

 

这也就实现了Android夸进程通信了。

这里只是一个很简单的例子,以便不理解这一块的朋友管中窥豹,其实AIDL和系统级服务的配合使用远没这么简单,但是大致原理是这样的,比如Android的网络服务,google定义了很多的状态,通过后台的Service不断的监听这些状态的变化去控制网络,又比如电源管理,控制屏幕的亮度等等,复杂的是其中繁多的状态变化。

文章写的比较浅显,希望大家多多指教。

 

推推族,免费得门票,游景区:www.tuituizu.com

结伴旅游,一个免费的交友网站:www.jieberu.com

 

转载于:https://www.cnblogs.com/rabbit-bunny/p/4229177.html

你可能感兴趣的文章
How to install ia32-libs in Ubuntu 14.04 LTS (Trusty Tahr)
查看>>
ACM/ICPC 之 模拟 (HNUOJ 13391-换瓶模拟)
查看>>
JavaWeb学习——JSP基础
查看>>
Eclipse tomcat server 无法添加项目
查看>>
黑寡妇黄飞鸿
查看>>
leetcode 217 Contains Duplicate 数组中是否有重复的数字
查看>>
The Ctrl & CapsLock `problem'
查看>>
MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作
查看>>
linux故障判断
查看>>
Leetcode 23. Merge k Sorted Lists(python)
查看>>
Java进阶知识点6:并发容器背后的设计理念 - 锁分段、写时复制和弱一致性
查看>>
Makefile ===> Makefile 快速学习
查看>>
face detection[HR]
查看>>
java性能调优工具
查看>>
C# 其他的Url 文件的路径转化为二进制流
查看>>
cmake使用
查看>>
ios7上隐藏status bar
查看>>
构造方法和全局变量的关系
查看>>
python3基础05(有关日期的使用1)
查看>>
ArrayList的使用方法
查看>>