kivy python 读取oracle数据库_Kivy A to Z -- 怎样从python代码中直接訪问Android的Service...

在Kivy中,通过pyjnius扩展能够间接调用Java代码,而pyjnius利用的是Java的反射机制。可是在Python对象和Java对象中转来转去总让人感觉到十分别扭。好在android提供了binder这个进程间通信的功能,Java中的Service也是基于Binder的C++代码封装来实现进程间通信的,这也为从Python代码中绕开pyjnius直接訪问Java代码提供了可能,既然Java的Service是基于C++的封装来实现的,也相同能够在Python中封装相同的C++代码,这篇文章解说了怎样通过binder在Python代码中直接訪问Java的Service。如WifiService。

binder_wrap.h

#ifndef BINDER_WRAP_H

#define BINDER_WRAP_H

#ifdef __cplusplus

extern "C" {

#endif

typedef int (*vector_visitor)(const char16_t* str16,int length,void *data);

typedef int (*fnOnTransact)(uint32_t code,const void *data,void *reply,uint32_t flags,void *userData);

int server_create(const char *name,const char *descriptor,fnOnTransact onTrans,void *data);

void* binder_getbinder(const char *name);

int binder_releasebinder(void* binder);

int binder_listServices(vector_visitor visitor,void *data);

int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,size_t size);

int binder_transact(void* binder,int code,const void *data,void* reply,int flags);

void* parcel_new();

int parcel_destroy(void* parcel);

int parcel_writeInterfaceToken(void* parcel,const char *interface);

int parcel_writeInt32(void *parcel,int val);

int parcel_writeCString(void *parcel,const char* str);

int parcel_writeString16(void *parcel,const char16_t* str, size_t len);

int parcel_readInt32(void *parcel);

long parcel_readInt64(void *parcel);

int parcel_readString16(void *parcel,char16_t* str, size_t len);

int parcel_readInplace(void *parcel,void* data, int len);

int parcel_readExceptionCode(void *parcel);

int parcel_dataAvail(void *parcel);

#ifdef __cplusplus

}

#endif

#endif

binder_wrap.cpp

#include

#include

#include

#include

#include

#include

#include

#include

#include "binder_wrap.h"

using namespace android;

void* binder_getbinder(const char *name)

{

android::sp<:iservicemanager> sm = android::defaultServiceManager();

sp *binder = new sp();

do {

*binder = sm->getService(android::String16(name));

if (binder != 0)

{

break;

}

usleep(500000); // 0.5 s

} while(true);

return reinterpret_cast(binder);

}

int binder_releasebinder(void* binder)

{

sp *bp = reinterpret_cast *>(binder);

if(bp == 0)

{

return 0;

}

delete bp;

return 1;

}

//Vector listServices() = 0;

int binder_listServices(vector_visitor visitor,void *data)

{

android::sp<:iservicemanager> sm = android::defaultServiceManager();

Vector list = sm->listServices();

for (int i=0;i

{

visitor(list[i].string(),list[i].size(),data);

}

return list.size();

}

int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,size_t size)

{

sp *bp = reinterpret_cast *>(binder);

if(bp == 0)

{

return 0;

}

if (descriptor == NULL || size <= 0)

{

return 0;

}

String16 des = (*bp)->getInterfaceDescriptor();

if (size > des.size())

{

size = des.size();

}

memcpy(descriptor,des.string(),size*2);

return size;

}

//int binder_transact(void* binder,int code,const Parcel& data,Parcel* reply,int flags = 0)

int binder_transact(void* binder,int code,const void *data,void* reply,int flags)

{

sp *bp = reinterpret_cast *>(binder);

if(bp == 0 || data == 0 || reply == 0)

{

return 0;

}

return (*bp)->transact(code,*(Parcel*)data,(Parcel*)reply,flags);

}

void* parcel_new()

{

return (void*)new Parcel();

}

int parcel_destroy(void* parcel)

{

if(parcel == 0)

{

return 0;

}

delete (Parcel*)parcel;

return 1;

}

int parcel_writeInterfaceToken(void* parcel,const char *interface)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->writeInterfaceToken(String16(interface));

}

int parcel_writeInt32(void *parcel,int val)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->writeInt32(val);

}

int parcel_writeCString(void *parcel,const char* str)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->writeCString(str);

}

int parcel_writeString16(void *parcel,const char16_t* str, size_t len)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

if (str == 0 || len <= 0)

{

return 0;

}

return p->writeString16(str,len);

}

int parcel_readInt32(void *parcel)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->readInt32();

}

long parcel_readInt64(void *parcel)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->readInt64();

}

int parcel_readString16(void *parcel,char16_t* str, size_t len)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

if (str == NULL || len <= 0)

{

return 0;

}

String16 str16 = p->readString16();

if (len > str16.size())

{

len = str16.size();

}

memcpy(str,str16.string(),len*2);

return len;

}

int parcel_readExceptionCode(void *parcel)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->readExceptionCode();

}

int parcel_readInplace(void *parcel,void* data, int len)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

if (len >= 0 && len <= (int32_t)p->dataAvail())

{

const void *d = p->readInplace(len);

memcpy(data,d,len);

return len;

}

return 0;

}

int parcel_dataAvail(void *parcel)

{

Parcel *p = reinterpret_cast(parcel);

if(p == 0)

{

return 0;

}

return p->dataAvail();

}

正如代码中所看到的,这里对C++的IBinder和Parcel两个对象进行了封装,而Java的Service的底层实现也正是对这两个类进行封装的结果,详细的能够看

frameworks\base\core\jni\android_util_Binder.cpp

的代码。

再来看下怎样在Python中使用这些代码,这里用cython来封装这些C接口:

binder.pyx

cdef extern from "utils/Unicode.h":

ctypedef short char16_t

ctypedef unsigned int uint32_t

cdef extern from "Python.h":

ctypedef short Py_UNICODE

ctypedef size_t Py_ssize_t

object PyString_FromStringAndSize(const char *v, Py_ssize_t len)

int PyString_AsStringAndSize(object obj, char **buffer, Py_ssize_t *length)

object PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)

Py_UNICODE* PyUnicode_AS_UNICODE(object)

Py_ssize_t PyUnicode_GetSize(object)

void Py_INCREF(object)

void Py_DECREF(object)

cdef extern from "binder_wrap.h":

ctypedef int (*vector_visitor)(const char16_t* str16,int length,void *data)

int binder_listServices(vector_visitor visitor,void *data)

ctypedef int (*fnOnTransact)(uint32_t code,const void *data,void *reply,uint32_t flags,void *userData)

int server_create(const char *name,const char *descriptor,fnOnTransact onTrans,void *data)

void* binder_getbinder(const char *name)

int binder_releasebinder(void* binder)

int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,int size)

int binder_transact(void* binder,int code,const void *data,void* reply,int flags)

void* parcel_new()

int parcel_destroy(void* parcel)

int parcel_writeInterfaceToken(void* parcel,const char *interface)

int parcel_writeInt32(void *parcel,int val)

int parcel_writeCString(void *parcel,const char* str)

int parcel_writeString16(void *parcel,const char16_t* str, size_t len)

int parcel_readInt32(void *parcel)

int parcel_readInt64(void *parcel)

int parcel_readString16(void *parcel,char16_t* str, size_t len)

int parcel_readExceptionCode(void *parcel)

int parcel_readInplace(void *parcel,void* data, int len)

int parcel_dataAvail(void *parcel)

cdef int visitor(const char16_t* str16,int length,void *data):

arr = data

o = PyUnicode_FromUnicode(str16,length)

arr.append(o)

def listServices():

arr = []

Py_INCREF(arr)

binder_listServices(visitor,arr)

Py_DECREF(arr)

return arr

cdef class Binder:

cdef void *ptr

def __cinit__(self,char *name): #, sp[IBinder] service):

self.ptr = binder_getbinder(name)

def __dealloc__(self):

binder_releasebinder(self.ptr)

def getInterfaceDescriptor(self):

cdef char16_t descriptor[256]

cdef int ret

ret = binder_getInterfaceDescriptor(self.ptr,descriptor,sizeof(descriptor))

if not ret:

return None

return PyUnicode_FromUnicode(descriptor,ret)

def transact(self,int code,data,reply,int flags):

cdef int dataPtr = data.getNativePtr()

cdef int replyPtr = reply.getNativePtr()

binder_transact(self.ptr,code,dataPtr,replyPtr,flags)

return reply

cdef class Parcel:

cdef void *ptr

cdef int nativePtr

def __cinit__(self,unsigned int nativePtr=0): #, sp[IBinder] service):

self.nativePtr = nativePtr

if not nativePtr:

self.ptr = parcel_new()

else:

self.ptr = nativePtr

def __dealloc__(self):

if not self.nativePtr:

parcel_destroy(self.ptr)

def getNativePtr(self):

return self.ptr

def writeInterfaceToken(self,const char *interface):

return parcel_writeInterfaceToken(self.ptr,interface)

def writeInt(self,int val):

self.writeInt32(val)

def writeInt32(self,int val):

return parcel_writeInt32(self.ptr,val)

def writeCString(self,const char* cstr):

return parcel_writeCString(self.ptr,cstr)

def writeString16(self,ustr):

cdef char16_t *un

cdef int size

if isinstance(ustr,unicode):

un = PyUnicode_AS_UNICODE(ustr)

size = PyUnicode_GetSize(ustr)

return parcel_writeString16(self.ptr,un,size)

def readInt32(self):

return parcel_readInt32(self.ptr)

def readInt(self):

return self.readInt32()

def readInt64(self):

return parcel_readInt64(self.ptr)

def readExceptionCode(self):

return parcel_readExceptionCode(self.ptr)

def readString16(self):

cdef char16_t str16[256]

cdef int ret

ret = parcel_readString16(self.ptr,str16,sizeof(str16))

if not ret:

return None

return PyUnicode_FromUnicode(str16,ret)

def readByteArray(self):

return self.createByteArray()

def createByteArray(self):

length = self.readInt()

print 'createByteArray:',length

return self.readInplace(length)

# int parcel_readInplace(void *parcel,void* data, size_t len)

def readInplace(self,length):

cdef char arr[512]

ret = parcel_readInplace(self.ptr,arr,length)

if ret == length:

return PyString_FromStringAndSize(arr,length)

else:

return None

# int parcel_dataAvail(void *parcel)

def dataAvail(self):

return parcel_dataAvail(self.ptr)

def createTypedArrayList(self,creator):

N = self.readInt()

if N <= 0:

return None

arr = []

for i in range(N):

if self.readInt() == 0:

continue

else:

result = creator.createFromParcel(self)

arr.append(result)

return arr

@classmethod

def obtain(cls):

return Parcel()

@classmethod

def recycle(cls):

pass

好,再来看看怎样来实现訪问WifiService的功能:

WifiService.py

from binder import Binder,Parcel

WIFI_SERVICE = "wifi";

DESCRIPTOR = "android.net.wifi.IWifiManager";

FIRST_CALL_TRANSACTION = 1

TRANSACTION_getConfiguredNetworks = (FIRST_CALL_TRANSACTION + 0);

TRANSACTION_addOrUpdateNetwork = (FIRST_CALL_TRANSACTION + 1);

TRANSACTION_removeNetwork = (FIRST_CALL_TRANSACTION + 2);

TRANSACTION_enableNetwork = (FIRST_CALL_TRANSACTION + 3);

TRANSACTION_disableNetwork = (FIRST_CALL_TRANSACTION + 4);

TRANSACTION_pingSupplicant = (FIRST_CALL_TRANSACTION + 5);

TRANSACTION_startScan = (FIRST_CALL_TRANSACTION + 6);

TRANSACTION_getScanResults = (FIRST_CALL_TRANSACTION + 7);

TRANSACTION_disconnect = (FIRST_CALL_TRANSACTION + 8);

TRANSACTION_reconnect = (FIRST_CALL_TRANSACTION + 9);

TRANSACTION_reassociate = (FIRST_CALL_TRANSACTION + 10);

TRANSACTION_getConnectionInfo = (FIRST_CALL_TRANSACTION + 11);

TRANSACTION_setWifiEnabled = (FIRST_CALL_TRANSACTION + 12);

TRANSACTION_getWifiEnabledState = (FIRST_CALL_TRANSACTION + 13);

TRANSACTION_setCountryCode = (FIRST_CALL_TRANSACTION + 14);

TRANSACTION_setFrequencyBand = (FIRST_CALL_TRANSACTION + 15);

TRANSACTION_getFrequencyBand = (FIRST_CALL_TRANSACTION + 16);

TRANSACTION_isDualBandSupported = (FIRST_CALL_TRANSACTION + 17);

TRANSACTION_saveConfiguration = (FIRST_CALL_TRANSACTION + 18);

TRANSACTION_getDhcpInfo = (FIRST_CALL_TRANSACTION + 19);

TRANSACTION_acquireWifiLock = (FIRST_CALL_TRANSACTION + 20);

TRANSACTION_updateWifiLockWorkSource = (FIRST_CALL_TRANSACTION + 21);

TRANSACTION_releaseWifiLock = (FIRST_CALL_TRANSACTION + 22);

TRANSACTION_initializeMulticastFiltering = (FIRST_CALL_TRANSACTION + 23);

TRANSACTION_isMulticastEnabled = (FIRST_CALL_TRANSACTION + 24);

TRANSACTION_acquireMulticastLock = (FIRST_CALL_TRANSACTION + 25);

TRANSACTION_releaseMulticastLock = (FIRST_CALL_TRANSACTION + 26);

TRANSACTION_setWifiApEnabled = (FIRST_CALL_TRANSACTION + 27);

TRANSACTION_getWifiApEnabledState = (FIRST_CALL_TRANSACTION + 28);

TRANSACTION_getWifiApConfiguration = (FIRST_CALL_TRANSACTION + 29);

TRANSACTION_setWifiApConfiguration = (FIRST_CALL_TRANSACTION + 30);

TRANSACTION_startWifi = (FIRST_CALL_TRANSACTION + 31);

TRANSACTION_stopWifi = (FIRST_CALL_TRANSACTION + 32);

TRANSACTION_addToBlacklist = (FIRST_CALL_TRANSACTION + 33);

TRANSACTION_clearBlacklist = (FIRST_CALL_TRANSACTION + 34);

TRANSACTION_getWifiServiceMessenger = (FIRST_CALL_TRANSACTION + 35);

TRANSACTION_getWifiStateMachineMessenger = (FIRST_CALL_TRANSACTION + 36);

TRANSACTION_getConfigFile = (FIRST_CALL_TRANSACTION + 37);

TRANSACTION_captivePortalCheckComplete = (FIRST_CALL_TRANSACTION + 38);

mRemote = Binder(WIFI_SERVICE)

def transact(TRANSACTION):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

mRemote.transact(TRANSACTION, _data, _reply, 0)

_reply.readExceptionCode()

return _reply.readInt32()

def getConfiguredNetworks():

pass

def addOrUpdateNetwork():

pass

def removeNetwork():

pass

def enableNetwork(netId,disableOthers):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

_data.writeInt32(netId)

if disableOthers:

_data.writeInt32(1)

else:

_data.writeInt32(0)

mRemote.transact(TRANSACTION_enableNetwork, _data, _reply, 0)

_reply.readExceptionCode()

return _reply.readInt32() != 0

def disableNetwork(netId):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

_data.writeInt32(netId)

mRemote.transact(TRANSACTION_disableNetwork, _data, _reply, 0)

_reply.readExceptionCode()

return _reply.readInt32() != 0

def pingSupplicant():

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

mRemote.transact(TRANSACTION_pingSupplicant, _data, _reply, 0)

_reply.readExceptionCode()

return _reply.readInt32() != 0

def startScan(forceActive):

_data = Parcel()

_reply = Parcel()

ret = 0

try:

_data.writeInterfaceToken(DESCRIPTOR)

if forceActive:

_data.writeInt(1)

else:

_data.writeInt(0)

mRemote.transact(TRANSACTION_startScan, _data, _reply, 0)

ret = _reply.readExceptionCode()

finally:

_reply.recycle()

_data.recycle()

return ret == 0

class ScanResult:

def __init__(self,ssid,bssid,caps,level,frequency,timestamp):

self.ssid = ssid

self.bssid = bssid

self.caps = caps

self.level = level

self.frequency = frequency

self.timestamp = timestamp

@classmethod

def createFromParcel(cls,reply):

has_ssid = reply.readInt32()

ssid = None

if has_ssid:

ssid_lengt = reply.readInt()

ssid = reply.readByteArray()

BSSID = reply.readString16()

caps = reply.readString16()

level = reply.readInt()

frequency = reply.readInt()

timestamp = reply.readInt64()

print 'BSSID:',BSSID

print 'caps:',caps

print 'level:',level

print 'frequency:',frequency

print 'timestamp:',timestamp

return ScanResult(ssid,BSSID,caps,level,frequency,timestamp)

def getScanResults():

_data = Parcel.obtain()

_reply = Parcel.obtain()

_result = None

try:

_data.writeInterfaceToken(DESCRIPTOR)

mRemote.transact(TRANSACTION_getScanResults, _data, _reply, 0)

if 0 != _reply.readExceptionCode():

return None

_result = _reply.createTypedArrayList(ScanResult)

finally:

_reply.recycle()

_data.recycle()

return _result

def disconnect():

return transact(TRANSACTION_disconnect) != 0

def reconnect():

return transact(TRANSACTION_reconnect) != 0

def reassociate():

return transact(TRANSACTION_reassociate) != 0

"""

class WifiInfo:

def __init__():

pass

@classmethod

def createFromParcel(cls,r):

info = WifiInfo();

info.networkId = r.readInt32()

info.rssi = r.readInt32()

info.linkSpeed = r.readInt32()

if r.readByte() == 1:

info.setInetAddress(InetAddress.getByAddress(in.createByteArray()))

if r.readInt() == 1:

info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(r)

info.mBSSID = r.readString16()

info.mMacAddress = r.readString16()

info.mMeteredHint = r.readInt32() != 0

"""

def getConnectionInfo():

pass

def setWifiEnabled(enable):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

if enable:

_data.writeInt32(1)

else:

_data.writeInt32(0)

mRemote.transact(TRANSACTION_setWifiEnabled, _data,_reply,0)

_reply.readExceptionCode()

_result = (0!=_reply.readInt32())

return _result;

def getWifiEnabledState():

return transact(TRANSACTION_getWifiEnabledState)

def setCountryCode(country,persist):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

if isinstance(country,str):

country = unicode(contry)

_data.writeString16(country)

if persist:

_data.writeInt32(1)

else:

_data.writeInt32(0)

mRemote.transact(TRANSACTION_setCountryCode, _data,_reply,0)

_reply.readExceptionCode()

_result = (0!=_reply.readInt32())

return _result;

def setFrequencyBand(band, persist):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

if isinstance(country,str):

country = unicode(contry)

_data.writeInt32(band)

if persist:

_data.writeInt32(1)

else:

_data.writeInt32(0)

mRemote.transact(TRANSACTION_setFrequencyBand, _data,_reply,0)

_reply.readExceptionCode()

_result = (0!=_reply.readInt32())

return _result;

def getFrequencyBand():

return transact(TRANSACTION_getFrequencyBand)

def isDualBandSupported():

return transact(TRANSACTION_isDualBandSupported) != 0

def saveConfiguration():

pass

def get_readable_address(addr):

return "%d:%d:%d:%d"%(addr&0xff,(addr>>8)&0xff,(addr>>16)&0xff,(addr>>24)&0xff)

def getDhcpInfo():

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

mRemote.transact(TRANSACTION_getDhcpInfo, _data,_reply,0)

_reply.readExceptionCode()

if 0 == _reply.readInt32():

return None

ipAddress = get_readable_address(reply.readInt32());

gateway = get_readable_address(reply.readInt32());

netmask = get_readable_address(reply.readInt32());

dns1 = get_readable_address(reply.readInt32());

dns2 = get_readable_address(reply.readInt32());

serverAddress = get_readable_address(reply.readInt32());

leaseDuration = get_readable_address(reply.readInt32());

info = (ipAddress,gateway,netmask,dns1,dns2,serverAddress,leaseDuration)

print "ipAddress %s,\ngateway %s,\nnetmask %s,\ndns1 %s,\ndns2 %s,\nserverAddress %s,\nleaseDuration %s"%info

return info

def acquireWifiLock():

pass

def updateWifiLockWorkSource():

pass

def releaseWifiLock():

pass

def initializeMulticastFiltering():

pass

def isMulticastEnabled():

pass

def acquireMulticastLock():

pass

def releaseMulticastLock():

pass

def setWifiApEnabled(wifiConfig,enable):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

if wifiConfig:

_data.writeInt32(1)

wifiConfig.writeToParcel(_data)

else:

_data.writeInt32(0)

if enable:

_data.writeInt32(1)

else:

_data.writeInt32(0)

mRemote.transact(TRANSACTION_setWifiApEnabled, _data,_reply,0)

_reply.readExceptionCode()

def getWifiApEnabledState():

return transact(TRANSACTION_getWifiApEnabledState)

def getWifiApConfiguration():

pass

def setWifiApConfiguration():

pass

def startWifi():

return transact(TRANSACTION_startWifi)

def stopWifi():

return transact(TRANSACTION_stopWifi)

def addToBlacklist(bssid):

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

if isinstance(bssid,str):

bssid = unicode(bssid)

_data.writeString16(bssid)

mRemote.transact(TRANSACTION_addToBlacklist, _data,_reply,0)

_reply.readExceptionCode()

def clearBlacklist():

return transact(TRANSACTION_clearBlacklist)

def getWifiServiceMessenger():

pass

def getWifiStateMachineMessenger():

pass

def getConfigFile():

_data = Parcel()

_reply = Parcel()

_data.writeInterfaceToken(DESCRIPTOR)

mRemote.transact(TRANSACTION_getConfigFile, _data,_reply,0)

_reply.readExceptionCode()

return _reply.readString16()

def captivePortalCheckComplete():

return transact(TRANSACTION_captivePortalCheckComplete) != 0

眼下并没有实现全部的WifiService的功能,可是像startScan。getScanResults,setWifiEnabled,getWifiEnabledState,getDhcpInfo,setWifiApEnabled这些基本的接口已经实现了,其他接口没有实现并不是是由于不能实现,而是比較繁琐,临时未实现而己,后面会不断的完好。

再来看下測试代码:

test.py

import WifiService

WifiService.setWifiEnabled(True)

WifiService.startScan(True)

print WifiService.pingSupplicant()

print WifiService.getConfigFile()

for i in range(10):

time.sleep(1.0)

result = WifiService.getScanResults()

if result:

print result

break

运行后将会打印出搜索到的Wifi信息。

另外就是代码的编译问题了。

代码必须在android的源码下进行编译。我试过在ndk上进行编译,经过一番努力,通过链接事先编译好的C++ binder库。也成功编译通过,可是程序不能正常执行。这应该是预先编译出来的库和ndk的库存在兼容性问题造成的。也许通过在ndk上编译binder库能够避免这个问题。可是眼下还没有作过尝试。 可是编译出来的代码应该能够执行在各个不同的版本号,我在4.0和4.2版本号的设备上作了简单的測试,事实证明在4.2上编译的代码能够在4.0上执行,可是考虑到android的诸多版本号,各个版本号多多少少有些兼容性问题,更具体的还必须比較各个版本号的binder代码。并通过測试才干得到结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,可以实现从 A 数据库读取表数据分批插入到 B 数据库: ```python import cx_Oracle import threading # A 数据库连接信息 A_HOST = 'localhost' A_PORT = 1521 A_SID = 'ORCL' A_USER = 'user' A_PASSWORD = 'password' # B 数据库连接信息 B_HOST = 'localhost' B_PORT = 1521 B_SID = 'ORCL' B_USER = 'user' B_PASSWORD = 'password' # 分批读取的大小 BATCH_SIZE = 1000 def read_from_a(start): try: conn_a = cx_Oracle.connect(f'{A_USER}/{A_PASSWORD}@{A_HOST}:{A_PORT}/{A_SID}') cursor_a = conn_a.cursor() cursor_a.execute(f"SELECT * FROM table_a WHERE id >= {start} ORDER BY id ASC") rows = cursor_a.fetchmany(BATCH_SIZE) while rows: insert_to_b(rows) start += BATCH_SIZE rows = cursor_a.fetchmany(BATCH_SIZE) except cx_Oracle.Error as error: print('Error:', error) finally: cursor_a.close() conn_a.close() def insert_to_b(rows): try: conn_b = cx_Oracle.connect(f'{B_USER}/{B_PASSWORD}@{B_HOST}:{B_PORT}/{B_SID}') cursor_b = conn_b.cursor() cursor_b.executemany("INSERT INTO table_b VALUES (:1, :2, :3)", rows) conn_b.commit() except cx_Oracle.Error as error: print('Error:', error) finally: cursor_b.close() conn_b.close() if __name__ == '__main__': start = 0 threads = [] for i in range(10): t = threading.Thread(target=read_from_a, args=(start,)) threads.append(t) t.start() start += BATCH_SIZE for t in threads: t.join() ``` 这个示例代码定义了两个函数,`read_from_a()` 和 `insert_to_b()`,分别用于从 A 数据库读取数据和向 B 数据库插入数据。在 `read_from_a()` 函数使用 `fetchmany()` 方法分批读取数据,并调用 `insert_to_b()` 函数插入到 B 数据库。在主函数创建 10 个线程,每个线程从 A 数据库读取一批数据并插入到 B 数据库。 需要注意的是,这个示例代码仅作为参考,具体实现还需要根据实际场景进行调整,例如需要根据数据量大小和系统资源等情况确定分批大小,还需要进行线程间同步和互斥等处理。同时,对于数据库连接等资源,也需要进行合理的管理和释放,以避免资源浪费和泄漏等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值