您的位置:首页 > 大数据 > 人工智能

FM AIDL JNI 调用过程回顾

2013-10-18 16:47 465 查看
FM AIDL JNI 调用过程回顾

FMPlay.java

public class FMPlay extends Activity

implements ServiceConnection;

private RadioServiceStub mService;

public void onCreate(Bundle savedInstanceState) {

mService = new RadioServiceStub(this, this);

//-----------------6

RadioServiceStub.java

private Context mContext;

private ServiceConnection mCallback;

public RadioServiceStub(Context context, ServiceConnection callback) {

mContext = context;

mCallback = callback;

mService = null;

mBinder = null;

}

//-----------------6

}

protected void onStart() {

if (!mService.bindToService()) {

//------------------------------5

RadioServiceStub.java

private ServiceConnection mBinder;

public boolean bindToService() {

mContext.startService(new Intent(mContext, FMplayService.class)); //此时的mContext即为FMPlay.this,启动FMplayService这个Service

mBinder = new BinderCallback(mCallback); //mCallback为callback,即为从FMPlay传过来ServiceConnection

//
public void onServiceConnected(ComponentName name, IBinder service) {

// mReady = true;

// Log.d(LOGTAG, "mReady = true");

// }

// public void onServiceDisconnected(ComponentName name) {

// mReady = false;

// }

//----------------------------5

RadioServiceStub.java

private class BinderCallback implements ServiceConnection {

private ServiceConnection mCallback;

public void onServiceDisconnected(ComponentName name) {

if (mCallback != null) {

mCallback.onServiceDisconnected(name);

}

mService = null;

}

public void onServiceConnected(ComponentName name, IBinder service) {

mService = IRadioService.Stub.asInterface(service);

if (mCallback != null) {

mCallback.onServiceConnected(name, service);

}

}

public BinderCallback(ServiceConnection callback) {

mCallback = callback;

}

}

//----------------------------4

return mContext.bindService((new Intent()).setClass(mContext, FMplayService.class), mBinder,Context.BIND_AUTO_CREATE);

//当返回这句时,new Intent()).setClass(mContext, FMplayService.class) 等价于 new Intent(mContext, FMplayService.class),此时调用mBinder的onServiceConnected

//----------------------------3

正式进入关键调用AIDL:RadioServiceStub.java

private IRadioService mService;

public void onServiceConnected(ComponentName name, IBinder service) { //ComponentName name, IBinder service这2个参数还有待研究==

mService = IRadioService.Stub.asInterface(service); //对IRadioService.aidl做个解释--->1.1,之后mService就可以调用此里面的方法,比如-->1.2

//--------------------------1

在out目录下会自动生成 IRadioService.java 部分内容如下 有待研究==

public static com.thunderst.radio.IRadioService asInterface(android.os.IBinder obj)

{

if ((obj==null)) {

return null;

}

android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);

if (((iin!=null)&&(iin instanceof com.thunderst.radio.IRadioService))) {

return ((com.thunderst.radio.IRadioService)iin);

}

return new com.thunderst.radio.IRadioService.Stub.Proxy(obj);

}

public boolean isFmOn() throws android.os.RemoteException;

//--------------------------1

if (mCallback != null) { //mCallback = callback;一定不为null,即为从FMPlay传过来ServiceConnection,所以在FMPlay一定有对onServiceConnected的具体实现

mCallback.onServiceConnected(name, service);

//------------------------------2

public void onServiceConnected(ComponentName name, IBinder service) {

mReady = true;

Log.d(LOGTAG, "mReady = true");

}

//------------------------------2

}

}

//----------------------------3

}

//------------------------------4

Log.d(LOGTAG, "fail to bindToService");

mService = null;

return;

}

}

-----------------1.1-----------------------

package com.thunderst.radio;

interface IRadioService

{

boolean isMuted();

boolean setFreq(float freq);

boolean startSeek(boolean up);

boolean stopSeek();

float getFreq();

float getFreq2(boolean issech);

boolean routeAudio(int device);

boolean setVolume(int volume);

int getAudioDevice();

boolean fmOn();

boolean fmOff();

boolean isFmOn();

boolean mute();

boolean unMute();

}

----------------------1.2-----------------

FMPlay.java

public void onTuneWheelValueChanged(View v, float changedBy) {

Message msg = mHandler.obtainMessage(MSG_TUNE);

Bundle data = new Bundle();

float freq = adjustFreq(WheelConfig.format(mService.getFreq() + changedBy)); -->到1.3 //学习的出发点从对mService.getFreq()疑惑开始!!!!!

data.putFloat("freq", freq);

msg.setData(data);

mHandler.sendMessage(msg);

}}

看看mService.getFreq()怎么被调用的。

从上面分析可知:mContext.startService(new Intent(mContext, FMplayService.class));启动了 FMplayService

//-----------------------1

RadioServiceStub.java

mContext.bindService((new Intent()).setClass(mContext, FMplayService.class), mBinder,Context.BIND_AUTO_CREATE);bindService时调用了 FMplayService

public IBinder onBind(Intent intent) {

Log.d(LOGTAG,"onBind");

mBinded = true;

return mBinder;

//--------------------------2

private final IBinder mBinder = new ServiceStub(this);

//-----------------------------3

关键

static class ServiceStub extends IRadioService.Stub{

WeakReference<FMplayService> mService;

public ServiceStub(FMplayService service) {

mService = new WeakReference<FMplayService>(service);

//----------------------4

mService = new WeakReference<FMplayService>(service);大概流程,最后得到是一个T类型类,即为 FMplayService

public WeakReference(T r) {

super(r, null);

}

Reference(T r, ReferenceQueue q) {

referent = r;

queue = q;

}

//----------------------4

}

public boolean fmOn() throws RemoteException {

if(mService != null){

if(mService.get() != null){

return mService.get().fmOn();

}

}

return false;

}

public boolean fmOff() throws RemoteException {

if(mService != null){

if(mService.get() != null){

return mService.get().fmOff();

}

}

return false;

}

public boolean isFmOn() throws RemoteException {

if(mService != null){

if(mService.get() != null){

return mService.get().isFmOn();

}

}

return false;

}

public boolean mute() throws RemoteException {

return mService.get().mute();

}

public boolean unMute() throws RemoteException {

return mService.get().unMute();

}

public boolean isMuted() throws RemoteException {

return mService.get().isMuted();

}

public boolean setFreq(float freq) throws RemoteException {

if(mService != null){

if (mService.get() != null) {

return mService.get().setFreq(freq);

}

}

return false;

}

public boolean startSeek(boolean up) throws RemoteException {

return mService.get().startSeek(up);

}

public boolean stopSeek() throws RemoteException {

return mService.get().stopSeek();

}

------------------1.3--------------------------

public float getFreq() throws RemoteException {

if(mService != null){

if (mService.get() != null) {

//----------------5

public T get() {

return referent; //还是一个FMplayService

}

//----------------5

return mService.get().getFreq(); //即调用FMplayService的getFreq()方法,到此调用结束!

//------------------------6

public float getFreq() {

float freq = -1.0f;

synchronized(mReceiverLock) {

if (mReceiver != null) {

int iFreq = mReceiver.getTunedFrequency(); // -->continue

Log.d(LOGTAG, "get frequency " + iFreq);

if (iFreq > 0) {

freq = (float) iFreq / TRANS_MULT;

}

}

}

return freq;

}

//------------------------6

}

}

return FMPlaySharedPreferences.getTunedFreq();

}

public float getFreq2(boolean issech) throws RemoteException {

if(mService != null){

if(mService.get() != null){

return mService.get().getFreq2(issech);

}

}

return FMPlaySharedPreferences.getTunedFreq();

}

public boolean routeAudio(int device) {

return mService.get().routeAudio(device);

}

public boolean setVolume(int volume) {

return mService.get().setVolume(volume);

}

public int getAudioDevice() {

return mService.get().getAudioDevice();

}

}

//-----------------------------3

//--------------------------2

}

//------------------------1

==========================continue=============================

public float getFreq() {

float freq = -1.0f;

synchronized(mReceiverLock) {

if (mReceiver != null) {

//----------------------1

在getFreq()时已经有

public boolean fmOn() {

mReceiver = new FmReceiver(RADIO_DEVICE, null); //所以mReceiver != null

}

//----------------------1

int iFreq = mReceiver.getTunedFrequency();

//------------------------2

FmReceiver.java

public int getTunedFrequency () {

int frequency = FmReceiverJNI.getFreqNative(sFd);

//----------------------------3

FmReceiverJNI.java

static synchronized native int getFreqNative(int fd); //native JNI调用 --->1.4

//----------------------------3

Log.d(TAG, "getFrequency: "+frequency);

return frequency;

}

//------------------------2

Log.d(LOGTAG, "get frequency " + iFreq);

if (iFreq > 0) {

freq = (float) iFreq / TRANS_MULT;

}

}

}

return freq;

}

------------------------1.4--------------------------

android_hardware_fm.cpp

static JNINativeMethod gMethods[] = {

/* name, signature, funcPtr */

{ "acquireFdNative", "(Ljava/lang/String;)I",

(void*)android_hardware_fmradio_FmReceiverJNI_acquireFdNative},

{ "closeFdNative", "(I)I",

(void*)android_hardware_fmradio_FmReceiverJNI_closeFdNative},

{ "getFreqNative", "(I)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getFreqNative}, //函数映射

//-------------------------------1

/* native interface */

static jint android_hardware_fmradio_FmReceiverJNI_getFreqNative(JNIEnv * env, jobject thiz, jint fd)

{

int freq = -1;

fm_device_t* device = (fm_device_t *)fd;

//---------------------------2

fm.h

struct fm_device_t {

struct hw_device_t common;

/**

* Set the provided lights to the provided values.

*

* Returns: 0 on succes, error code on failure.

*/

int (*getFreq)(struct fm_device_t* dev, int* freq);

int (*setFreq)(struct fm_device_t* dev, int freq);

int (*setControl)(struct fm_device_t* dev,int id, int value);

int (*startSearch)(struct fm_device_t* dev,int freq, int dir, int timeout, int reserve);

int (*cancelSearch)(struct fm_device_t*dev);

};

//---------------------------2

int err = device->getFreq(device,&freq);

//------------------------------3

具体到FM厂商,比如 博通

libfm-brcm_hw.cpp

static int

getFreq(struct fm_device_t* dev,int* freq)

{

struct bcm4330_fm_device_t *device = (struct bcm4330_fm_device_t *)dev;

LOGD("%s, %d\n", __FUNCTION__, gfm_params.chnl_info.freq );

//*freq = gfm_params.chnl_info.freq/10;

*freq = gfm_context.cur_freq/10;

return FM_SUCCESS; ---->结束!

}

//------------------------------3

LOGE("(getFreq)result=%d freq=%d\n", err, freq);

if(err < 0){

return FM_JNI_FAILURE;

}

return freq;

}

//-------------------------------1

{ "setFreqNative", "(II)I",

(void*)android_hardware_fmradio_FmReceiverJNI_setFreqNative},

{ "getControlNative", "(II)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getControlNative},

{ "setControlNative", "(III)I",

(void*)android_hardware_fmradio_FmReceiverJNI_setControlNative},

{ "startSearchNative", "(IIIII)I",

(void*)android_hardware_fmradio_FmReceiverJNI_startSearchNative},

{ "cancelSearchNative", "(I)I",

(void*)android_hardware_fmradio_FmReceiverJNI_cancelSearchNative},

{ "getRSSINative", "(I)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getRSSINative},

{ "setBandNative", "(III)I",

(void*)android_hardware_fmradio_FmReceiverJNI_setBandNative},

{ "setRegionNative", "(II)I",

(void*)android_hardware_fmradio_FmReceiverJNI_setRegionNative},

{ "getLowerBandNative", "(I)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getLowerBandNative},

{ "getBufferNative", "(I[BI)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getBufferNative},

{ "setMonoStereoNative", "(II)I",

(void*)android_hardware_fmradio_FmReceiverJNI_setMonoStereoNative},

{ "getRawRdsNative", "(I[BI)I",

(void*)android_hardware_fmradio_FmReceiverJNI_getRawRdsNative},

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: