在android中使用XML-RPC的最简单方法是什么?我试过了http://code.google.com/p/android-xmlrpc/,但它没有编译而且看起来已经废弃了。
答案 0 :(得分:6)
您可以看一下Android的WordPress客户端是如何做到的。该代码在GNU通用公共许可证下是公开的,可以在此处通过SVN进行检查:http://android.wordpress.org/development/
客户端本身在包org.xmlrpc.android
中实现,主要使用Android提供的库,例如XmlPullParser:http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html
这不像在你的项目中粘贴一个罐子那么简单,但它似乎是一个轻量级的探索之路。当然,WordPress客户端正在不断开发和使用,它确实有效。
答案 1 :(得分:2)
https://github.com/timroes/aXMLRPC
这个项目可能是XMLRPC客户端的更好选择。
答案 2 :(得分:0)
Apache的XML-RPC客户端(http://ws.apache.org/xmlrpc/client.html)是否有效?
答案 3 :(得分:0)
XMLRPC的当前库正在运行,但示例太小。你肯定需要另外几个线程来处理通信。对我来说,很容易建立与Linux-Python的连接。
这是一个在图书馆顶部的例子,用于餐馆(部分自己写):
package hha.zhongcan.communication;
import java.net.URI;
import android.os.Handler;
import android.util.Log;
import hha.zhongcan.framework.Citem;
import hha.zhongcan.framework.Configuration;
import hha.zhongcan.framework.CtimeFrame;
import hha.zhongcan.framework.Ctransaction;
import hha.zhongcan.microfood.AskTableDialog;
import hha.zhongcan.resources.Global;
import org.apache.http.conn.HttpHostConnectException;
interface XMLRPCMethodCallback
{
void callFinished(Object result);
}
/** Messages to send to the PC at high level. Receive the menu items, pages, transactions.
* Create fake data for the demo.
*
* @author mensfort
*
*/
public class Cmessage
{
static private Cmessage m_message =null;
private static URI m_uri;
public static XMLRPCClient m_client;
private final static String TAG="message";
private boolean m_connected =false;
private int m_pingId =0;
private int m_lost =0;
private int m_wait =0;
private boolean m_sendTransactions =true;
private Handler m_updateHandler = new Handler();
boolean m_getItems = false;
boolean m_getPages = false;
private static Global m_global =null;
private int m_countTransactions =10;
private int transactionMessageCount =0;
private long getValue( String s)
{
try
{
if ( s.startsWith("0x") || s.startsWith("0X"))
{
s =s.substring(2);
while (s.startsWith("0"))
{
s=s.substring(1);
}
if ( s.length() ==0)
{
return 0;
}
return Long.parseLong(s, 16);
}
if ( s=="")
{
return 0;
}
return Long.parseLong(s);
}
catch(Exception e)
{
e.printStackTrace();
return 0;
}
}
/// @brief New thread for running ask-table.
private Runnable messageTask = new Runnable()
{
//@override
public void run()
{
if ( m_getItems)
{
m_getItems =false;
getMenuItems();
}
else if ( m_getPages)
{
m_getPages =false;
getMenuPages();
}
else if ( m_sendTransactions)
{
// If I have sth to send and I'm not in page mode, then start sending items.
sendTransactions();
m_wait =2;
}
else if ( Configuration.getInstance().isDemo())
{
m_connected =true;
next();
}
else if ( m_wait>0)
{
m_wait--;
next();
}
else if ( --m_countTransactions<=0)
{
sendMessage_getTransactions();
m_countTransactions =5;
}
else
{
// Update this screen every 10 seconds.
sendConnected();
}
}
};
/** @brief At startup start the first message after a second.
*/
private Cmessage()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** @brief Set the address and port.
*
* @param address [in] Address to use.
* @param port [in] Port to use.
*/
public void setPath( String address, Integer port)
{
m_uri = URI.create("http://192.168.0.105:9876");
m_client =new XMLRPCClient( m_uri);
}
/** @brief Singleton implementation, only this instance can send messages.
*
* @return Pointer to the singleton.
*/
public static Cmessage getInstance()
{
if ( m_message ==null)
{
m_message =new Cmessage();
m_global =Global.getInstance();
}
return m_message;
}
/** @brief In a second, the next command can be send to the PC.
*/
public void next()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** @brief Check if we are connected to the PC.
*
* @return true when connected.
*/
public boolean isConnected()
{
return m_connected;
}
/** @brief Send Ping message, just to check the connection status.
*/
public void sendConnected()
{
{
XMLRPCMethod method =new XMLRPCMethod( "ping", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
String s = (String) (result);
if ( s.equals("bart"))
{
m_lost =0;
m_connected =true;
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
m_lost++;
}
}
});
Object[] params ={ m_pingId++ }; // {};
method.call(params);
}
if ( ++m_lost>2)
{
m_connected =false;
}
}
public void sendMessage_getConfiguration()
{
// TODO Auto-generated method stub
}
private void createMenuFrom( Object [] arrY)
{
if ( arrY.length >0)
{
m_global.itemDB.clean();
}
int v=(int)(arrY.length/9);
int lvl=1;
for (int y=0; y<arrY.length; y++)
{
if ( y==lvl*v)
{
setSlider(lvl++);
}
Log.i(TAG, "item " + y);
Object[] arrX = (Object[]) arrY[y];
int id =(Integer) arrX[0];
String alias =(String) arrX[1];
String local =(String) arrX[2];
String chinese =(String) arrX[3];
int restaurant_price =(Integer) arrX[4];
int takeaway_price =(Integer) arrX[5];
int level =(Integer) arrX[6];
int page =(Integer) arrX[7];
int sequence =(Integer) arrX[8];
int colour_text = (int)(getValue( (String) arrX[9])&0xffffffff);
int colour_background = (int)(getValue( (String) arrX[10])&0xffffffff);
int colour_selected_text = (int)(getValue( (String) arrX[11])&0xffffffff);
int colour_selected_background = (int)(getValue( (String) arrX[12])&0xffffffff);
int colour_background2 = (int)(getValue( (String) arrX[13])&0xffffffff);
int colour_selected_background2 = (int)(getValue( (String) arrX[14])&0xffffffff);
if ( m_global.mainMenuHandler !=null)
{
// m_global.mainMenuHandler.obtainMessage( y, "UPDATE_MENU_SLIDEBAR "+y).sendToTarget();
}
m_global.itemDB.insert( id, alias, local, chinese, restaurant_price,
takeaway_price, (byte)level, (byte)page, (short)sequence,
colour_text, colour_background, colour_selected_text,
colour_selected_background, colour_background2,
colour_selected_background2);
}
m_global.itemDB.complete();
Log.i(TAG, "Items received correct.");
}
/** Indicate that we want to get the menu card.
*/
public void sendMessage_getMenuItems()
{
m_getItems = true;
m_getPages = true;
}
/** @brief Get the menu items. */
public void getMenuItems()
{
boolean demo =Configuration.getInstance().isDemo();
if (demo ==true)
{
createMenuFrom( demoMenu.items);
next();
}
else
{
XMLRPCMethod method =new XMLRPCMethod( "items", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
m_global.itemDB.deleteAll();
m_global.itemDB.clean();
Object[] arrY = (Object[]) result;
createMenuFrom( arrY);
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = {};
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 1").sendToTarget();
}
method.call(params);
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 5").sendToTarget();
}
}
}
/** Call to get all transactions from the server, including payments, items and time-frames. */
public void sendMessage_sendTransactions()
{
m_sendTransactions =true;
}
/** Set slider to a value 1..10
*
* @param n [in] 0..10
*/
private void setSlider( int n)
{
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_SLIDEBAR "+n).sendToTarget();
}
}
/** After sending the orders, the database can be cleaned...
*/
private void cleanDatabase()
{
try
{
m_global.transactionDB.clean();
m_global.timeFrameDB.clean();
m_global.transactionItemDB.clean();
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
/** Send all transaction */
private void sendTransactions()
{
if ( m_global.transactionDB.size() ==0)
{
m_sendTransactions =false;
cleanDatabase();
next();
return;
}
if ( Configuration.getInstance().isDemo())
{
cleanDatabase();
try
{
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
}
catch (Exception e)
{
e.printStackTrace();
}
m_sendTransactions =false;
}
XMLRPCMethod method =new XMLRPCMethod( "orders", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
cleanDatabase();
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
m_sendTransactions =false;
}
});
Object[][] transaction =m_global.transactionDB.get();
Object[][] timeFrame =m_global.timeFrameDB.get();
Object[][] item =m_global.transactionItemDB.get();
Object[] params ={ transaction,timeFrame,item };
//{
// transaction, timeFrame, item
//}/;
if ( transaction ==null || timeFrame ==null || item ==null)
{
cleanDatabase();
Log.e( TAG,"Database problem!!");
}
method.call( params);
}
/// Call to get all transactions from the server, including payments, items and time-frames.
public void sendMessage_getTransactions()
{
if ( m_global.transactionDB.size() >0)
{
return;
}
if ( m_global.timeFrameDB.size() >0)
{
return;
}
if ( m_global.transactionItemDB.size() >0)
{
return;
}
XMLRPCMethod method =new XMLRPCMethod( "get_transactions", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
m_countTransactions =10;
m_connected =true;
if ( m_global.transactionDB.size() >0)
{
Log.i(TAG, "Transaction DB not empty.");
return;
}
if ( m_global.timeFrameDB.size() >0)
{
Log.i(TAG, "Time Frame DB not empty.");
return;
}
if ( m_global.transactionItemDB.size() >0)
{
Log.i(TAG, "Transaction Item DB not empty.");
return;
}
try
{
m_global.transactionList.clean();
Object[] arrY = (Object[]) result;
Object[] transactions =(Object[]) arrY[0];
Object[] timeFrames =(Object[]) arrY[1];
Object[] items =(Object[]) arrY[2];
//Object[] payments =(Object[]) arrY[3];
for (int y=0; y<transactions.length; y++)
{
Object[] trx = (Object[]) transactions[y];
int id = Integer.valueOf(trx[0].toString());
String tme =trx[1].toString();
String name =trx[2].toString();
int customer_id =Integer.valueOf( trx[3].toString());
int status =Integer.valueOf( trx[4].toString());
int total =Integer.valueOf( trx[5].toString());
Ctransaction t=new Ctransaction( id, name, tme, status, customer_id, total);
m_global.transactionList.insert( t);
}
for (int y=0; y<timeFrames.length; y++)
{
Object[] trx = (Object[]) timeFrames[y];
int id = Integer.valueOf( trx[0].toString());
int tfi =Integer.valueOf( trx[1].toString());
int waiter =Integer.valueOf( trx[2].toString());
String start_time =trx[3].toString();
String end_time =trx[4].toString();
int transaction_id =Integer.valueOf( trx[5].toString());
int device_id =Integer.valueOf( trx[6].toString());
CtimeFrame c =new CtimeFrame( id, (short)tfi, waiter,
start_time, end_time,
transaction_id, device_id);
m_global.transactionList.insert( c);
}
for (int y=0; y<items.length; y++)
{
Object[] trx = (Object[]) items[y];
//int id = (Integer) trx[0];
long menu_item_id =Long.valueOf( trx[1].toString());
int sequence =Integer.valueOf( trx[2].toString());
int time_frame_index =Integer.valueOf( trx[3].toString());
int deleted_time_frame_index =Integer.valueOf( trx[4].toString());
long transaction_id =Long.valueOf( trx[5].toString());
int quantity =Integer.valueOf( trx[6].toString());
int level =Integer.valueOf( trx[7].toString());
int deleted =Integer.valueOf( trx[8].toString());
int portion =Integer.valueOf( trx[9].toString());
int orig_price =Integer.valueOf( trx[10].toString());
int unit_price =Integer.valueOf( trx[11].toString());
String time =trx[12].toString();
Citem i=new Citem( menu_item_id, y, (short)sequence,
(short)time_frame_index,
(short)deleted_time_frame_index,
transaction_id, quantity,
(byte)level, deleted, (byte)portion, unit_price, orig_price, time);
m_global.transactionList.insert( i);
}
//for (int y=0; y<payments.length; y++)
//{
//Object[] pay = (Object[]) payments[y];
//int id = (Integer) pay[0];
//String time =(String) pay[1];
//int money_received =(Integer) pay[2];
//int customer_id =(Integer) pay[3];
//int pay_method =(Integer) pay[4];
//int partial_index =(Integer) pay[5];
//global.paymentsDB.insert( id, time, money_received, customer_id, pay_method, partial_index);
//}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = { transactionMessageCount++ };
method.call(params);
}
/// Call, but not in main thread, answer comes in a thread.
private void getMenuPages()
{
if ( Configuration.getInstance().isDemo())
{
decodePages( demoMenu.pages);
next();
return;
}
XMLRPCMethod method =new XMLRPCMethod( "pages", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
decodePages( result);
}
});
setSlider(7);
Object[] params = {};
method.call(params);
setSlider(8);
}
/**
* @brief Convert an array to page data.
* @param result [in] array with local, chinese names.
*/
private void decodePages( Object result)
{
try
{
m_global.pageDB.clean();
Object[] arrY = (Object[]) result;
setSlider(9);
for (int y=0; y<arrY.length; y++)
{
Object[] arrX = (Object[]) arrY[y];
int id = (Integer) arrX[0];
String local =(String) arrX[1];
String chinese =(String) arrX[2];
String lc =local.replace( "'", "''");
String ch =chinese.replace( "'", "''");
m_global.pageDB.insert( id, lc, ch);
}
m_connected =true;
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_READY").sendToTarget();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
class XMLRPCMethod extends Thread
{
private String method;
private Object[] params;
private Handler handler;
private XMLRPCMethodCallback callBack;
public XMLRPCMethod(String method, XMLRPCMethodCallback callBack)
{
this.method = method;
this.callBack = callBack;
handler = new Handler();
}
public void call()
{
call(null);
}
public void call(Object[] params)
{
this.params = params;
start();
}
//@Override
public void run()
{
synchronized(this)
{
try
{
final long t0 = System.currentTimeMillis();
final Object result = m_client.callEx(method, params);
final long t1 = System.currentTimeMillis();
handler.post(new Runnable()
{
public void run()
{
Log.i(TAG, "XML-RPC call took " + (t1-t0) + "ms");
callBack.callFinished(result);
next();
}
});
}
catch (final XMLRPCFault e)
{
handler.post(new Runnable()
{
public void run()
{
Log.e(TAG, "Fault message: " + e.getFaultString() + "\nFault code: " + e.getFaultCode());
Log.d("Test", "error", e);
next();
}
});
}
catch (final XMLRPCException e)
{
next();
handler.post(new Runnable()
{
public void run()
{
Throwable couse = e.getCause();
if (couse instanceof HttpHostConnectException)
{
Log.e(TAG, "Cannot connect to " + m_uri.getHost() + "\nMake sure server.py on your development host is running !!!");
}
else
{
Log.e(TAG, "Error " + e.getMessage());
}
Log.d(TAG, "error", e);
}
});
}
catch (Exception e)
{
next();
e.printStackTrace();
}
}
}
}
}