編輯:關於Android編程
Service AIDL簡述
Android系統中的進程之間不能共享內存,因此,需要提供一些機制在不同進程之間進行數據通信。Android應用程序組
件中的4個(Activity、Broadcast、 Service和Content Provider)都可以進行跨進程訪問,Service就是通過AIDL服務來
完成不同進程之間的通信。
在AIDL服務中有兩種對象:
服務程序:給調用者提供服務.將自己的服務接口暴露在外,讓用戶通過這些接口來調用自己的方法.
調用程序:使用服務者提供的服務.通過已知的服務程序的暴露接口,來調用服務程序的方法來完成自己的任務.
AIDL Service的編寫方法
步驟:
1.曝露接口(創建AIDL文件)
2.實現接口(編寫Service程序)
3.部署服務程序(在AndroidManifest.xml中設置Service的訪問屬性)
曝露接口(創建AIDL文件)
AIDL定義接口的源代碼必須以.aidl為擴展名.
AIDL接口中用到的數據類型,除基本類型\String \List\Map\CharSequence之外,其他類型全部需要導入包
Android-sdk下的platform-tools目錄下aidl.exe工具包會自動將接口文件轉化為在gen目錄下同名的java接口文件
生成的接口文件中包含一個Stub內部類,該類實現了IBinder接口和AIDL自定義的暴露接口.該類就是遠程Service的回調
類(onBind()方法的返回值)
接口文件中包含一個名為asInterface(IBinder iBinder)的重要方法,它返回接口的實例(不是本地服務bindService() 通過
getService()).
實現接口(編寫Service程序)
定義一個實現了Stub子類的對象.
在其中實現暴露接口的服務方法
給Service的onBind()方法返回這個對象
其它的生命周期方法和bindService的一樣
部署服務程序
在AndroidManifest.xml文件中配置該Service的相關屬性
如:
AIDL Service的調用者的編寫方法
將服務程序暴露的.aidl接口文件復制到調用者程序文件目錄中,該接口也回被aidl.exe工具自動轉化為gen目錄下的.java文件
創建ServiceConnection對象
建立intent對象,設置其啟動的服務類名\以及相關訪問服務的屬性
以ServiceConnection對象和intent對象為參數,調用bindService()方法綁定到遠程的Service
onServiceConnected()方法中是通過IMusicPlayer.Stub.asInterface(service)的方法獲得Service的代理,而不是象本
service中通過getService()方法直接獲得service對象
Service AIDL與bindService的區別
綁定本地Service時可以直接獲取onBind()方法的返回值;綁定遠程Service時獲取的是onBind()方法的返回對象的代理,因
此需要進行一些處理.
本地Service的onBind()方法會直接把IBinder對象本身傳給調用者的ServiceConnection中的onServiceConnected()方法
中的第二個參數,而遠程Service的onBind()方法只是將IBinder對象的代理傳遞給調用者的ServiceConnection中的
onServiceConnected()方法中的第二個參數.
AIDL Service的編寫方法源代碼實例:
創建AIDL文件:
package cn.zj.nb.wl;
interface IMusicService
{
void play();
void pause();
void stop();
}
實現接口(編寫Service程序):
package cn.zj.nb.wl;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
public class MusicService extends Service {
MediaPlayer mPlayer;
IMusicService.Stub stub=new IMusicService.Stub() {
@Override
public void stop() throws RemoteException {
mPlayer.stop();
}
@Override
public void play() throws RemoteException {
mPlayer.start();
}
@Override
public void pause() throws RemoteException {
mPlayer.pause();
}
};
@Override
public void onCreate() {
mPlayer=MediaPlayer.create(getApplicationContext(), R.raw.wind);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return stub;
}
}
部署服務程序:
AIDL Service的調用者:
創建AIDL文件:
package cn.zj.nb.wl;
interface IMusicService
{
void play();
void pause();
void stop();
}
Activity:
package cn.edu.zwu.tel;
public class PlayerActivity extends Activity {
ImageButton imageButtonStop;
ImageButton imageButtonNext;
ImageButton imageButtonPlay;
ImageButton imageButtonPre;
ImageButton imageButtonRepeat;
SeekBar musicSeekBar;
boolean isPlaying = false;
boolean isBound=false;
private IMusicService musicService;
private ServiceConnection conn=new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
musicService=IMusicService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name)
{
musicService=null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
imageButtonStop = (ImageButton) findViewById(R.id.imageButtonStop);
imageButtonNext = (ImageButton) findViewById(R.id.imageButtonNext);
imageButtonPlay = (ImageButton) findViewById(R.id.imageButtonPlay);
imageButtonPre = (ImageButton) findViewById(R.id.imageButtonPre);
imageButtonRepeat = (ImageButton) findViewById(R.id.imageButtonRepeat);
musicSeekBar = (SeekBar) findViewById(R.id.musicSeekBar);
Intent intent=new Intent();
intent.setAction("cn.zj.nb.wl.action.lgs");
startService(intent);
if(!isBound)
{
bindService(intent,conn,Context.BIND_AUTO_CREATE);
isBound=true;
}
imageButtonPlay.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
if(!isPlaying)
{
try {
musicService.play();
} catch (RemoteException e) {
e.printStackTrace();
}
imageButtonPlay.setBackgroundResource(R.drawable.pause_button);
isPlaying = true;
}else
{
try {
musicService.pause();
} catch (RemoteException e) {
e.printStackTrace();
}
imageButtonPlay.setBackgroundResource(R.drawable.play_button);
isPlaying = false;
}
}
});
imageButtonStop.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
try {
musicService.stop();
} catch (RemoteException e) {
e.printStackTrace();
}
if(isBound)
{
unbindService(conn);
isBound=false;
musicService=null;
}
PlayerActivity.this.finish();
}
});
}
}
前段時間群裡兄弟項目中有類似這樣的需求 我看到兄弟受苦受難,於心不忍。又因事不關己,打算高高掛起。正在愛恨糾結之時,日神對我說:沒事多造點輪子,你的人生會有很多
跑馬燈效果,大家可以去原作者浏覽https://github.com/sfsheng0322/MarqueeView 下面看自定義控件的代碼public class Ma
IPC為進程間通信或跨進程通信,是指兩個進程進行進程間通信的過程。在PC和移動設備上一個進程指的是一個程序或者一個應用,所以我們可以將進程間通信簡單理解為不同應用之間的通
最簡單的使用xml布局文件 Activity.javaList list = new ArrayList<>();list.add("