为 Android 添加 Java 层服务(三)
16lz
2021-01-23
每一个应用程序都有自己的进程,进程之间不能互相访问,这叫做应用程序沙漏(application sandboxing)
为了能用使应用程序能互相访问,Android提供IPC(interprocess communication protocol)
IPC protocol因为需要整理封装(marshaling/un marshaling数据)而变得复杂。
因此.Android提供 AIDL(Android Interface Definition Language),它对使用了类似于java的语法,对IPC轻量级实现,并有AIDL工具自动实现stub的创建
实现步骤:
1.定义 the AIDL interface
2.为remote service实现Stub
加入后会自动在aidl_service/src/com.tcwzy.aidl/下生成IstockQuoteService.java文件
AndroidManifest.xml为
第三步:将remote service提供给本地 local client
利用servcie实现onBind(),就可以连接到remote service
AndroidManifest.xml为:
为了能用使应用程序能互相访问,Android提供IPC(interprocess communication protocol)
IPC protocol因为需要整理封装(marshaling/un marshaling数据)而变得复杂。
因此.Android提供 AIDL(Android Interface Definition Language),它对使用了类似于java的语法,对IPC轻量级实现,并有AIDL工具自动实现stub的创建
实现步骤:
1.定义 the AIDL interface
2.为remote service实现Stub
3.将remote service提供给本地 local client
第一步:定义 the AIDL interface
在项目工程的aidl_service/src/com.tcwzy.aidl/
package com.tcwzy.aidl;interface IStockQuoteService { double getQuote(String ticker);}
加入后会自动在aidl_service/src/com.tcwzy.aidl/下生成IstockQuoteService.java文件
第二步:为remote service实现Stub
在aidl_service/src/com.tcwzy.service/
package com.tcwzy.service;import com.tcwzy.aidl.IStockQuoteService;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class StockQuoteService extends Service{ private static final String TAG = "wzy";public class StockQuoteServiceImpl extends IStockQuoteService.Stub { @Override public double getQuote(String ticker) throws RemoteException { // TODO Auto-generated method stub Log.v(TAG,"service getQuote() call for " + ticker); return 20.0; } } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.v(TAG,"service Create"); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.v(TAG,"service Destory"); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); Log.v(TAG,"service Start"); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.v(TAG,"service Bind"); return new StockQuoteServiceImpl(); }}
AndroidManifest.xml为
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tcwzy.service" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <service android:name="StockQuoteService"> <intent-filter > <action android:name="hahaha"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service> </application></manifest>
第三步:将remote service提供给本地 local client
利用servcie实现onBind(),就可以连接到remote service
在aidl_client/src/com.tcwzy.aidl下将刚才在服务端创建的aidl文件复制过来
在aidl_client/src/com.tcwzy.client/下声明activity
package com.tcwzy.client;import com.tcwzy.aidl.IStockQuoteService;import android.app.Activity;import android.os.Bundle;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class Aidl_clientActivity extends Activity { private static final String TAG = "wzy"; private IStockQuoteService stockService = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button b1 = (Button)findViewById(R.id.bind); final Button b2 = (Button)findViewById(R.id.call); final Button b3 = (Button)findViewById(R.id.unbind); b1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.v(TAG,"client bindService called"); Intent intent = new Intent("hahaha"); //Aidl_clientActivity.this.startActivity(intent); bindService(intent,serConn,Context.BIND_AUTO_CREATE); Log.v(TAG,"client bindService called serConn: " + IStockQuoteService.class.getName()); Log.v(TAG,"client bindService called serConn: " + serConn); Log.v(TAG,"client bindService called stockService: " + stockService); b1.setEnabled(false); b2.setEnabled(true); b3.setEnabled(true); } }); b2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.v(TAG,"client callService called"); callService(); b2.setEnabled(false); } }); b3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.v(TAG,"client unbindService called"); unbindService(serConn); b1.setEnabled(true); b2.setEnabled(false); b3.setEnabled(false); } }); } private void callService() { // TODO Auto-generated method stub try { Log.v(TAG,"client callService called"); double val = stockService.getQuote("SYH"); Toast.makeText(Aidl_clientActivity.this, "Value from service is " + val, Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private ServiceConnection serConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub Log.v(TAG,"onServiceConnected called"); stockService = IStockQuoteService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub Log.v(TAG,"onServiceDisconnected called"); stockService = null; } };}
AndroidManifest.xml为:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tcwzy.client" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="9" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Aidl_clientActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
更多相关文章
- Android 自定义RadioButton的样式
- Android多进程加载资源失败问题分析:android.content.res.Resour
- gdb 远程调试android进程
- Android 如何自定义apk打包的包名
- android自定义按钮控件样式
- 一起Talk Android吧(第一百四十六回:Android自定义View之Layout三)