。。。。。。。

23:47 by ...平..淡..., ... 阅读,
BluetoothAdapter.java中有low&enery(le)的一些方法,android提供了这些方法,但源码中并未找到这些方法的调用之处。本文档主要分析这类方法的执行流程,来了解下le到底做了些什么。
本文主要就是分析下startLeScan方法(两个重载方法)。
public boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
synchronized(mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
if (DBG) Log.e(TAG, "LE Scan has already started");
return false;
//获取BluetoothGattBinder类的实例,该类的定义在GattService.java中
IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
if (iGatt == null) {
// BLE is not supported
return false;
UUID uuid = UUID.randomUUID();
GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids);
//重点分析该方法。作用是为本地设备进行注册,以及启动扫描
//wrapper是GattCallbackWrapper类的对象。该类注册了一些Gatt协议的回调方法
iGatt.registerClient(new ParcelUuid(uuid), wrapper);
if (wrapper.scanStarted()) {
mLeScanClients.put(callback, wrapper);
return true;
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
下面来分析下iGatt.registerClient(new&ParcelUuid(uuid),&wrapper)方法,路径如下:(packages/apps/Bluetooth/src/com/android/bluetooth/gatt/GattService.java::BluetoothGattBinder)
public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) {
GattService service = getService();
if (service == null) return;
service.registerClient(uuid.getUuid(), callback);
接着会调用GattService服务的同名方法
void registerClient(UUID uuid, IBluetoothGattCallback callback) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (DBG) Log.d(TAG, "registerClient() - UUID=" + uuid);
mClientMap.add(uuid, callback);
gattClientRegisterAppNative(uuid.getLeastSignificantBits(),
uuid.getMostSignificantBits());
接下来会调用jni层com_android_bluetooth_gatt.cpp文件中的gattClientRegisterAppNative方法。
static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
jlong app_uuid_lsb, jlong app_uuid_msb )
if (!sGattIf) return;
set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
sGattIf-&client-&register_client(&uuid);
分析sGattIf-&client-&register_client(&uuid);语句
(1)sGattIf是一个静态变量,定义是static&const&btgatt_interface_t&*sGattIf&=&NULL;
又是这种类型的变量。第一反应就是去找btgatt_interface_t结构体定义的头文件(一般在hardware目录),然后再搜索调用的c文件(一般在external/bluetooth/bluedroid,有时找到的c文件与头文件同名)。
btgatt_interface_t结构体的定义:hardware/libhardware/include/hardware/bt_gatt.h
/** Represents the standard Bluetooth GATT interface. */
typedef struct {
/** Set to sizeof(btgatt_interface_t) */
* Initializes the interface and provides callback routines
bt_status_t (*init)( const btgatt_callbacks_t* callbacks );
/** Closes the interface */
void (*cleanup)( void );
/** Pointer to the GATT client interface methods.*/
const btgatt_client_interface_t* client;
/** Pointer to the GATT server interface methods.*/
const btgatt_server_interface_t*
} btgatt_interface_t;
btgatt_interface_t结构体的对象:external/bluetooth/bluedroi/btif/src/btif_gatt.c
static const btgatt_interface_t btgattInterface = {
sizeof(btgattInterface),
btif_gatt_init,
btif_gatt_cleanup,
&btgattClientInterface,
&btgattServerInterface,
回到sGattIf-&client-&register_client(&uuid);语句,它调用了sGattIf结构体对象中的client对象的register_client函数,那么就是btgattClientInterface对象的register_client函数。
由结构体的定义可知client对象的类型是btgatt_client_interface_t结构体。同理分析可得以下结果,
btgatt_client_interface_t结构体的定义:hardware/libhardware/include/hardware/&bt_gatt_client.h
typedef struct {
/** Registers a GATT client application with the stack */
bt_status_t (*register_client)( bt_uuid_t *uuid );
/** Unregister a client application from the stack */
  bt_status_t (*unregister_client)(int client_if );
  ......
btgatt_client_interface_t结构体的对象:external/bluetooth/bluedroi/btif/src/btif_gatt_client.c
const btgatt_client_interface_t btgattClientInterface = {
btif_gattc_register_app,
btif_gattc_unregister_app,
btif_gattc_scan,
  ......
因此client-&register_client就是调用了btif_gattc_register_app方法[--&btif_gatt_client.c]。
static bt_status_t btif_gattc_register_app(bt_uuid_t *uuid)
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_
memcpy(&btif_cb.uuid, uuid, sizeof(bt_uuid_t));
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_REGISTER_APP,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
分析btgattc_handle_event函数
static void btgattc_handle_event(uint16_t event, char* p_param)
btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_
if (!p_cb) return;
switch (event)
case BTIF_GATTC_REGISTER_APP:
btif_to_bta_uuid(&uuid, &p_cb-&uuid);
//为uuid注册回调函数
BTA_GATTC_AppRegister(&uuid, bte_gattc_cback);
分析BTA_GATTC_AppRegister函数
-------------------------------------------------------------------------------------------------------
void BTA_GATTC_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTC_CBACK *p_client_cb)
tBTA_GATTC_API_REG
/* register with BTA system manager */
  GKI_sched_lock();
  //注册Gatt客户端主事件处理函数bta_gattc_hdl_event,在bta_gatt_reg结构体中定义。
bta_sys_register(BTA_ID_GATTC, &bta_gatt_reg);
GKI_sched_unlock();
if ((p_buf = (tBTA_GATTC_API_REG *) GKI_getbuf(sizeof(tBTA_GATTC_API_REG))) != NULL)
p_buf-&hdr.event
= BTA_GATTC_API_REG_EVT;
if (p_app_uuid != NULL)
memcpy(&p_buf-&app_uuid, p_app_uuid, sizeof(tBT_UUID));
p_buf-&p_cback
= p_client_
bta_sys_sendmsg(p_buf);
(a)通过bta_sys_register函数注册了bta_gatt_reg结构体中定义的客户端主事件处理函数bta_gattc_hdl_event;然后设置event为BTA_GATTC_API_REG_EV,触发bta_gattc_hdl_event函数。
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
tBTA_GATTC_CB *p_cb = &bta_gattc_
tBTA_GATTC_CLCB *p_clcb = NULL;
#if BTA_GATT_DEBUG == TRUE
APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg-&event));
switch (p_msg-&event)
case BTA_GATTC_API_REG_EVT:
bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
(b)调用bta_gattc_register函数。该函数用来注册一个客户端Gatt应用程序。
void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data)
/* callback with register event */
if (p_data-&api_reg.p_cback)
(*p_data-&api_reg.p_cback)(BTA_GATTC_REG_EVT,
(tBTA_GATTC *)&cb_data);
调用相关event(BTA_GATTC_REG_EVT)的回调函数。
到此,BTA_GATTC_AppRegister函数分析完毕,接下来分析BTA_GATTC_AppRegister(&uuid,&bte_gattc_cback);中的参数部分。
ps:上述的回调函数就是这里的参数:bte_gattc_cback函数。那么BTA_GATTC_REG_EVT事件就调用该函数处理了。
-------------------------------------------------------------------------------------------------------
分析回调函数bte_gattc_cback&
static void bte_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt,
(uint16_t) event, (void*)p_data, sizeof(tBTA_GATTC), NULL);
ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
分析btif_gattc_upstreams_evt函数,在该函数中会处理BTA_GATTC_REG_EVT事件。
static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
tBTA_GATTC *p_data = (tBTA_GATTC*)p_
switch (event)
case BTA_GATTC_REG_EVT:
bt_uuid_t app_
bta_to_btif_uuid(&app_uuid, &p_data-&reg_oper.app_uuid);
HAL_CBACK(bt_gatt_callbacks, client-&register_client_cb
, p_data-&reg_oper.status
, p_data-&reg_oper.client_if
, &app_uuid
    ......
bt_gatt_callbacks对象的类型是btgatt_callbacks_t,其定义在hardware/libhardware/include/hardware/bt_gatt.h文件中。现在对bt_gatt_callbacks对象从头开始分析其来源。
在GattService.java::start()方法中,调用了initializeNative方法。继而调用JNI层initializeNative方法。贴出该方法。
static const btgatt_interface_t *sGattIf = NULL;
static const bt_interface_t* btIf;
static void initializeNative(JNIEnv *env, jobject object) {
/* getBluetoothInterface 函数返回sBluetoothInterface对象,在android4.3 bt 扫描分析.docx中已说明该对象的来源*/
if ( (btIf = getBluetoothInterface()) == NULL) {
error("Bluetooth module is not loaded");
  ......
  // BT_PROFILE_GATT_ID的值是&gatt&
if ( (sGattIf = (btgatt_interface_t *)
btIf-&get_profile_interface(BT_PROFILE_GATT_ID)) == NULL) {
error("Failed to get Bluetooth GATT Interface");
  bt_status_
  /* sGattCallbacks的定义
  static const btgatt_callbacks_t sGattCallbacks = {
sizeof(btgatt_callbacks_t),
&sGattClientCallbacks,
&sGattServerCallbacks
if ( (status = sGattIf-&init(&sGattCallbacks)) != BT_STATUS_SUCCESS) {
error("Failed to initialize Bluetooth GATT, status: %d", status);
sGattIf = NULL;
mCallbacksObj = env-&NewGlobalRef(object);
static const void* get_profile_interface (const char *profile_id)
#if BTA_GATT_INCLUDED == TRUE
if (is_profile(profile_id, BT_PROFILE_GATT_ID))
return btif_gatt_get_interface();
return NULL;
分析btif_gatt_get_interface函数
const btgatt_interface_t *btif_gatt_get_interface()
return &btgattInterface;
btgattInterface对象的类型是btgatt_interface_t结构体。再贴一遍该结构体的定义,如下:
typedef struct {
/** Set to sizeof(btgatt_interface_t) */
* Initializes the interface and provides callback routines
bt_status_t (*init)( const btgatt_callbacks_t* callbacks );
/** Closes the interface */
void (*cleanup)( void );
/** Pointer to the GATT client interface methods.*/
const btgatt_client_interface_t*
/** Pointer to the GATT server interface methods.*/
const btgatt_server_interface_t*
} btgatt_interface_t;
另,btgattInterface对象定义如下:
static const btgatt_interface_t btgattInterface = {
sizeof(btgattInterface),
btif_gatt_init,
btif_gatt_cleanup,
&btgattClientInterface,
&btgattServerInterface,
所以sGattIf&就是btgattInterface对象。
(b)&接下来调用sGattIf-&init函数。由上可知,即为btif_gatt_init函数。
static bt_status_t btif_gatt_init( const btgatt_callbacks_t* callbacks )
  /*bt_gatt_callbacks由参数赋值,该参数是sGattCallbacks。
  sGattCallbacks的定义
  static const btgatt_callbacks_t sGattCallbacks = {
sizeof(btgatt_callbacks_t),
&sGattClientCallbacks,
&sGattServerCallbacks
bt_gatt_callbacks =
BTA_GATTC_Init();
BTA_GATTS_Init();
return BT_STATUS_SUCCESS;
到此为止,调用语句中bt_gatt_callbacks对象我们已经清楚了,就是sGattCallbacks对象。现在分析client-&register_client_cb。
HAL_CBACK(bt_gatt_callbacks, client-&register_client_cb
, p_data-&reg_oper.status
, p_data-&reg_oper.client_if
, &app_uuid
client对象是在btgatt_callbacks_t结构体中定义的一个变量,其初始化是在bt_gatt_callbacks对象(即sGattCallbacks对象)中。
btgatt_callbacks_t结构体如下:
typedef struct {
/** Set to sizeof(btgatt_callbacks_t) */
/** GATT Client callbacks */
const btgatt_client_callbacks_t* client;
/** GATT Server callbacks */
const btgatt_server_callbacks_t*
} btgatt_callbacks_t;
因此client对应的就是sGattCallbacks对象中的sGattClientCallbacks对象。sGattClientCallbacks对象定义如下(在JNI层的com_android_bluetooth_gatt.cpp文件中定义):
static const btgatt_client_callbacks_t sGattClientCallbacks = {
btgattc_register_app_cb,
btgattc_scan_result_cb,
而sGattClientCallbacks对象的类型是btgatt_client_callbacks_t结构体,如下
typedef struct {
register_client_callback
register_client_
scan_result_callback
scan_result_
connect_callback
disconnect_callback
} btgatt_client_callbacks_t;
因此,client-&register_client_cb就是调用了sGattClientCallbacks&对象中的btgattc_register_app_cb函数。
void btgattc_register_app_cb(int status, int clientIf, bt_uuid_t *app_uuid)
CHECK_CALLBACK_ENV
sCallbackEnv-&CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
clientIf, UUID_PARAMS(app_uuid));
checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
JNI层的method_onClientRegistered&函数对应java层的onClientRegistered方法[--&GattService.java]。
void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
throws RemoteException {
UUID uuid = new UUID(uuidMsb, uuidLsb);
if (DBG) Log.d(TAG, "onClientRegistered() - UUID=" + uuid + ", clientIf=" + clientIf);
ClientMap.App app = mClientMap.getByUuid(uuid);
if (app != null) {
app.id = clientIf;
app.linkToDeath(new ClientDeathRecipient(clientIf));
app.callback.onClientRegistered(status, clientIf);
此callback其实是GattCallbackWrapper类的对象。
分析mClientMap对象,在registerClient方法中调用了ClientMap的父类ContextMap::add方法,将GattCallbackWrapper类对象wrapper作为callback参数添加到mClientMap对象中。
接下来重新分析:
onClientRegistered方法[---&BluetoothAdapter::GattCallbackWrapper类]
public void onClientRegistered(int status, int clientIf) {
if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status +
" clientIf=" + clientIf);
synchronized(this) {
if (mLeHandle == -1) {
if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled");
if (status == BluetoothGatt.GATT_SUCCESS) {
mLeHandle = clientIf;
IBluetoothGatt iGatt = null;
BluetoothAdapter adapter = mBluetoothAdapter.get();
if (adapter != null) {
iGatt = adapter.getBluetoothManager().getBluetoothGatt();
//调用startLeScan方法时,传递过来的参数为null,执行此处
if (mScanFilter == null) {
iGatt.startScan(mLeHandle, false);
ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length];
for(int i = 0; i != uuids. ++i) {
uuids[i] = new ParcelUuid(mScanFilter[i]);
iGatt.startScanWithUuids(mLeHandle, false, uuids);
Log.e(TAG, "onClientRegistered, BluetoothAdapter null");
mLeHandle = -1;
} catch (RemoteException e) {
Log.e(TAG, "fail to start le scan: " + e);
mLeHandle = -1;
接下来分析startScan方法,在GattService.java中。
void startScan(int appIf, boolean isServer) {
if (getScanClient(appIf, isServer) == null) {
if (DBG) Log.d(TAG, "startScan() - adding client=" + appIf);
mScanQueue.add(new ScanClient(appIf, isServer));
gattClientScanNative(appIf, true);
JNI层gattClientScanNative函数
static void gattClientScanNative(JNIEnv* env, jobject object, jint clientIf, jboolean start)
if (!sGattIf) return;
sGattIf-&client-&scan(clientIf, start);
同之前分析register_client的步骤,分析的scan函数对应btif_gattc_scan函数。
static bt_status_t btif_gattc_scan( int client_if, bool start )
CHECK_BTGATT_INIT();
btif_gattc_cb_t btif_
btif_cb.client_if = (uint8_t) client_
return btif_transfer_context(btgattc_handle_event, start ? BTIF_GATTC_SCAN_START : BTIF_GATTC_SCAN_STOP,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
在btgattc_handle_event函数中处理BTIF_GATTC_SCAN_START事件
case BTIF_GATTC_SCAN_START:
btif_gattc_init_dev_cb();
// BTA_DmBleObserve发出消息,包含BTA_DM_API_BLE_OBSERVE_EVT事件
BTA_DmBleObserve(TRUE, 0, bte_scan_results_cb);
调用bte_scan_results_cb函数,
static void bte_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
btif_gattc_cb_t btif_
switch (event)
case BTA_DM_INQ_RES_EVT:
case BTA_DM_INQ_CMPL_EVT:
btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATT_OBSERVE_EVT,
(char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
在btif_gattc_upstreams_evt函数中处理BTIF_GATT_OBSERVE_EVT事件。
case BTIF_GATT_OBSERVE_EVT:
btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_
if (!btif_gattc_find_bdaddr(p_btif_cb-&bd_addr.address))
btif_gattc_add_remote_bdaddr(p_btif_cb-&bd_addr.address, p_btif_cb-&addr_type);
btif_gattc_update_properties(p_btif_cb);
HAL_CBACK(bt_gatt_callbacks, client-&scan_result_cb,
&p_btif_cb-&bd_addr, p_btif_cb-&rssi, p_btif_cb-&value);
同分析register_client_cb函数,在JNI层com_android_bluetooth_gatt.cpp文件中定义,分析得scan_result_cb对应函数btgattc_scan_result_cb。
void btgattc_scan_result_cb(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data)
sCallbackEnv-&CallVoidMethod(mCallbacksObj, method_onScanResult
, address, rssi, jb);
对应java层文件GattService类onScanResult方法。
void onScanResult(String address, int rssi, byte[] adv_data) {
for (ScanClient client : mScanQueue) {
if (!client.isServer) {
ClientMap.App app = mClientMap.getById(client.appIf);
if (app != null) {
app.callback.onScanResult(address, rssi, adv_data);
} catch (RemoteException e) {
Log.e(TAG, "Exception: " + e);
mClientMap.remove(client.appIf);
mScanQueue.remove(client);
callback为GattCallbackWrapper类的对象,因此调用GattCallbackWrapper类中的onScanResult方法。
public void onScanResult(String address, int rssi, byte[] advData) {
BluetoothAdapter adapter = mBluetoothAdapter.get();
if (adapter == null) {
Log.d(TAG, "onScanResult, BluetoothAdapter null");
mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData);
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception: " + ex);
mLeScanCb对象为LeScanCallback接口的对象,不过源码中并没有类来实现该接口,故只能分析到这里了。扫描到此结束,over~~&
-------------------------------------------------------------------------------------------------------------
贴出流程图,see see,5个步骤:
1.startLeScan(JAVA--&JNI)
-------------------------------------------------------------------------------------------------------------
2.startLeScan(蓝牙栈)
-------------------------------------------------------------------------------------------------------------
3.startLeScan(JNI--&JAVA)
-------------------------------------------------------------------------------------------------------------
4.startLeScan(蓝牙栈)
-------------------------------------------------------------------------------------------------------------
5.startLeScan(JNI--&JAVA)
-------------------------------------------------------------------------------------------------------------只看今天发布的信息
[招聘](110)
03-30 10:51
[招聘](50)
03-30 10:43
[出租](1065)
03-30 10:00
[培训](261)
03-30 08:56
[培训](109)
03-30 08:48
[培训](187)
03-30 08:44
[招聘](287)
03-30 07:25
[招聘](192)
03-29 15:27
[培训](71)
03-29 14:55
[招聘](128)
03-29 14:46
[招聘](87)
03-29 13:01
[招聘](171)
03-29 10:39
[培训](372)
03-29 10:22
[招聘](302)
03-29 09:48
[出租](199)
03-29 09:30
[转让](185)
03-29 09:19
[招聘](460)
03-29 09:19
[转让](769)
03-29 09:18
[培训](382)
03-29 09:03
[培训](333)
03-29 09:00
[出租](58)
03-29 08:53
[家教](80)
03-29 08:50
[出租](606)
03-29 08:20
[出租](519)
03-29 08:20
[招聘](202)
03-29 08:17
[招聘](128)
03-29 07:51
[招聘](415)
03-28 16:32
[招聘](157)
03-28 13:40
[招聘](713)
03-28 13:30
[招聘](418)
03-28 11:54
[招聘](1022)
03-28 11:04
[招聘](232)
03-28 09:18
[招聘](1072)
03-27 16:40
[招聘](1305)
03-27 16:39
[出租](532)
03-27 16:19
[培训](708)
03-27 15:00
[招聘](389)
03-27 14:28
[招聘](770)
03-27 14:25
[培训](55)
03-27 13:46
[招聘](396)
03-27 10:49
[招聘](370)
03-27 10:08
[培训](167)
03-27 09:44
[招聘](404)
03-27 08:58
[培训](185)
03-27 08:40
[招聘](232)
03-27 08:35
[招聘](391)
03-26 15:51
[招聘](741)
03-26 12:01
[出租](337)
03-26 09:51
[出租](128)
03-26 08:00
[转让](670)
03-25 21:14
[培训](393)
03-25 14:49
[出租](360)
03-25 14:15
[转让](534)
03-25 10:26
[出租](22171)
03-25 08:40
[招聘](666)
03-25 08:27
[培训](273)
03-24 16:27
[培训](370)
03-24 16:24
[其它](479)
03-24 16:20
[招聘](4054)
03-24 15:52
[招聘](220)
03-24 15:42
[招聘](1188)
03-24 14:02
[求职](1394)
03-24 12:06
[招聘](392)
03-24 09:41
[其它](654)
03-24 09:10
[招聘](3633)
03-24 09:09
[招聘](4258)
03-24 08:47
[招聘](1325)
03-23 15:41
[招聘](474)
03-23 14:35
[培训](1317)
03-23 14:08
[招聘](332)
03-22 10:40
[出租](558)
03-22 09:57
[招聘](231)
03-22 08:03
[招聘](475)
03-22 07:51
[出租](519)
03-21 14:47
[转让](626)
03-21 14:44
[招聘](581)
03-21 14:41
[出租](348)
03-21 11:58
[培训](205)
03-21 11:54
[培训](6591)
03-21 10:40
[招聘](381)
03-20 16:26
[招聘](759)
03-20 13:23
[家教](394)
03-20 11:11
[招聘](621)
03-20 10:24
[招聘](522)
03-20 09:21
[转让](210)
03-20 08:52
[招聘](436)
03-19 15:12
[培训](1154)
03-18 14:00
[招聘](1737)
03-18 13:57
[家教](318)
03-18 08:58
[招聘](852)
03-17 14:40
[出租](435)
03-16 16:01
[转让](453)
03-16 14:38
[转让](440)
03-16 09:42
[出租](2296)
03-15 12:44
[招聘](1459)
03-14 14:00
[出租](569)
03-14 13:23
[招聘](1367)
03-14 08:19
[招聘](853)
03-13 15:54
[招聘](1294)
03-13 08:28
[招聘](2830)
03-11 10:22
[出租](1051)
03-10 10:44
[转让](1912)
03-10 09:24
[转让](541)
03-09 10:34
[招聘](1324)
03-08 09:38
[招聘](876)
03-06 14:09
[家教](551)
03-06 08:04
[转让](503)
03-05 12:07
[出租](696)
03-05 01:24
[招聘](1035)
03-04 09:22
[招聘](1514)
03-03 13:11
[招聘](2193)
03-02 13:52
[转让](1206)
03-02 10:49
[招聘](2750)
03-01 13:54
[家教](415)
03-01 12:47
[招聘](677)
03-01 11:01
[求职](1725)
03-01 09:04
[招聘](825)
02-27 15:09
[招聘](4589)
02-25 14:50
[出租](2960)
02-11 10:40
[招聘](2323)
02-07 10:07
[培训](1177)
12-28 08:10
[招聘](57)
03-30 11:48
导购销售店长
[转让](1348)
03-30 11:30
[出租](207)
03-30 10:13
五金城店面房
[招聘](257)
03-30 09:53
[求职](20)
03-30 11:50
[求职](156)
03-30 11:36
[出租](67)
03-30 11:33
[出租](937)
03-30 11:28
[转让](29)
03-30 11:23
[出租](18)
03-30 11:16
[招聘](90)
03-30 11:12
单休年终奖社保
[转让](875)
03-30 11:11
小吃店转让
[求职](55)
03-30 11:10
[招聘](66)
03-30 11:09
[招聘](35)
03-30 11:07
[招聘](65)
03-30 11:06
[招聘](60)
03-30 11:05
[招聘](44)
03-30 11:04
[招聘](1438)
03-30 10:58
[招聘](335)
03-30 10:57
话补年底双新免费每年2次旅游
[招聘](35)
03-30 10:57
[招聘](77)
03-30 10:56
[出租](28)
03-30 10:56
二室一厅水电齐全
[招聘](87)
03-30 10:55
[出租](28)
03-30 10:55
[招聘](40)
03-30 10:55
[招聘](24)
03-30 10:55
[招聘](25)
03-30 10:54
[招聘](18)
03-30 10:54
常见问题与帮助
有图有真相
(1438)(335)(4461)(69)(27)(113)(263)(579)(382)(664)
微信号:eyuyao-com
左侧二维码扫一扫即可
官方新浪微博
&  余姚生活网·宁波网联网络有限公司 版权所有
本站法律顾问: 

我要回帖

更多关于 ....。 的文章

 

随机推荐