现在的位置: 首页 > 综合 > 正文

在Android上使用Flamingo进行远程调用的实例

2013年10月29日 ⁄ 综合 ⁄ 共 6117字 ⁄ 字号 评论关闭

A. 前言

        近期在Android上开发一个应用程序,需要解决前后端通信的问题。最常见的解决方案是使用HTTP+JSON,但个人感觉如果要传输多个数据项的话还是比较麻烦;另一个解决方案是Hessian;当然还有其它的解决方案,例如WebService等。这些方案都不够简单直接,后来找到Exadel Flamingo这个好东西,实际上它在Flex开发中用得比较多,有关于它在Android开发中使用的文章,在网上搜索到的并不多。

B. Exadel Flamingo简介

       搞过Flex开发的人估计会听说过Exadel Flamingo,它是一个RIA的集成库和通信框架,可以实现前端(Flex, JavaFX和Android)和后端(JBoss Seam或Spring)的透明传输和远程调用,更多信息请访问官网

C. 开发环境

  • JDK 1.6.0_26
  • JBoss AS 5.1.0.GA
  • JBoss Seam 2.2.2.Final
  • JBoss Tools 3.3.x
  • Exadel Flamingo 2.2.0
  • Android 2.3.3
  • Eclipse 3.7.2
  • Hessian 3.2.1

 请先下载和安装好相关工具和库文件。

D. 服务器程序

1. 新建项目

打开Eclipse,新建一项目“Seam Web Project”,“Target runtime”选“JBoss 5.1 Runtime”。

2. 添加库文件

往/WebContent/WEB-INF/lib目录添加以下库文件:

flamingo-service-2.2.0.jar

flamingo-services-common-2.2.0.jar

hessian-3.2.1.jar

3. 修改配置

修改/WebContent/WEB-INF/web.xml,添加以下内容:

  <servlet>
    <servlet-name>Hessian Remote Servlet</servlet-name>
    <servlet-class>com.exadel.flamingo.service.seam.HessianToSeamServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Hessian Remote Servlet</servlet-name>
    <url-pattern>/flamingo/hessian/*</url-pattern>
  </servlet-mapping>

它的作用是启用Flamingo的Servlet。

4. 编写代码
  • 服务接口
package com.powercn.bridge.webremote;

public interface LoginService {
	public String SERVICE_NAME = "login";
	public boolean login(String username, String password);
	public UserInfo getUserInfo(String username);
}
  • 实体类
package com.powercn.bridge.webremote;

import java.io.Serializable;

public class UserInfo implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private String username = "";
	private String password = "";
	private Integer money = 100;
	
	public UserInfo(String username) {
		this.username = username;
	}
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Integer getMoney() {
		return money;
	}
	public void setMoney(Integer money) {
		this.money = money;
	}
}
  • 实现类
package com.powercn.bridge.impl;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

import com.powercn.bridge.webremote.LoginService;
import com.powercn.bridge.webremote.UserInfo;

@Scope(ScopeType.STATELESS)
@Name(LoginService.SERVICE_NAME)
public class LoginServiceImpl implements LoginService {

	public boolean login(String username, String password) {
		if (password.equals("password")) {
			return true;
		} else {
			return false;
		}		
	}
	
	public UserInfo getUserInfo(String username) {
		UserInfo userInfo = new UserInfo(username);
		userInfo.setPassword("password");
		userInfo.setMoney(1000);
		return userInfo;
	}

}

E. 客户端程序

1. 新建项目

打开Eclipse,新建一项目“Android Project”,“Build Target”选“Android 2.3.3”。

2. 修改界面

双击/res/layout/main.xml,在布局编辑窗口里添加控件,最终形成以下布局。

3. 添加库文件

往/libs目录添加以下库文件,并在“Java Build Path”添加引用:

flamingo-android-common-2.2.0.jar

flamingo-android-hessian-client-2.2.0.jar

flamingo-java-client-2.2.0.jar

flamingo-service-2.2.0.jar

flamingo-services-common-2.2.0.jar

4. 复制代码

将服务器端的服务接口和实体类复制到src目录下的相同包名之下。

5. 编写代码
package com.powercn.bridge;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.bridge.android.R;
import com.exadel.flamingo.android.FlamingoApplication;
import com.powercn.bridge.webremote.LoginService;
import com.powercn.bridge.webremote.UserInfo;

public class MyClientActivity extends Activity {
	private EditText serviceUrlEditText;
	private EditText usernameEditText;
	private EditText passwordEditText;
	private Button loginButton;
	private EditText logEditText;
		
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        serviceUrlEditText = (EditText)findViewById(R.id.serviceUrlEditText);
        usernameEditText = (EditText)findViewById(R.id.usernameEditText);
        passwordEditText = (EditText)findViewById(R.id.passwordEditText);
        loginButton = (Button)findViewById(R.id.loginButton);
        logEditText = (EditText)findViewById(R.id.logEditText);
        
        loginButton.setOnClickListener(onLoginClick);

        // 要根据实际的情况修改IP地址和端口
        serviceUrlEditText.setText("http://192.168.1.2:8080/my-server/flamingo/hessian");
    }
    
    private OnClickListener onLoginClick = new OnClickListener () {
    	public void onClick(View view) {
    		String serviceUrl = serviceUrlEditText.getText().toString();    		
    		
    		// 初始化远程服务
    		FlamingoApplication flamingoApplication = (FlamingoApplication) getApplication();
    		flamingoApplication.initializeFlamingoServiceFactory(serviceUrl);
    		LoginService loginService = flamingoApplication.getService(LoginService.class, LoginService.SERVICE_NAME);
    		if (loginService == null) {
    			logEditText.append("初始化远程服务失败。\n");
    			return;
    		} else {
    			logEditText.append("初始化远程服务成功。\n");
    		}
    		
    		// 调用远程方法,返回登录结果
    		String username = usernameEditText.getText().toString();
    		String password = passwordEditText.getText().toString();
    		boolean loginSucceed = loginService.login(username, password);
    		 if (loginSucceed) {
    			logEditText.append("登录成功。\n");
    		} else {
    			logEditText.append("登录失败。\n");
    		}
    		 
    		// 调用远程方法,返回用户信息
    		UserInfo userInfo = loginService.getUserInfo(username);
    		logEditText.append("Username: " + userInfo.getUsername() + "\n");
    		logEditText.append("Password: " + userInfo.getPassword() + "\n");
    		logEditText.append("Money: " + Integer.toString(userInfo.getMoney()) + "\n");
	    		
    	}
    };    
}

F. 联调测试

发布my-server,启动JBoss,运行MyClient程序,一切顺利的话将会看到以下运行结果:

G. 注意问题

1. Hessian的版本

在线文档说用hessian-3.1.3.jar,exadel-flamingo-2.2.0附带文档说用hessian-4.0.6.jar。

实际运行时发现要使用hessian-3.2.1.jar,使用其它版本可能会出现异常,暂时没有时间细究原因。
版本低于3.2.1,前端Android程序出现异常: 06-09 14:34:16.918: E/AndroidRuntime(733): com.caucho.hessian.client.HessianConnectionException: 302:
版本高于3.2.1,后端JBoss应用会出现异常: 10:47:01,234 ALL [ContextSerializerFactory] java.lang.ClassNotFoundException: com.powercn.bridge.services.UserInfoHessianSerializer

2. 权限设置

要为客户端程序添加使用网络的权限,在AndroidManifest.xml加入:

<uses-permission android:name="android.permission.INTERNET"/>

3. 修改AndroidManifest.xml

application要配置为: android:name="com.exadel.flamingo.android.FlamingoApplication", 否则会出现异常: java.lang.ClassCastException。

4. JBoss设置

要在JBoss的设置界面的Server Behaviour组里,勾选 “Listen on all interfaces to allow remote web connections”,以允许其它主机访问。

5. 官方文档

在线文档的内容跟exadel-flamingo-2.2.0附带文档的内容略有不同,个人认为以附带文档为准。

6. 版本更新

Exadel Flamingo最后一个版本2.2.0,是在2010-07-23发布的,已经快两年没有更新了。

H. 相关下载

服务器程序源代码

客户端程序源代码

JBoss 5.1.0.GA

JBoss Seam 2.2.2.Final

Exadel Flamingo 2.2.0

I. 参考资料

JBoss AS官网

JBoss Seam官网

Android开发者官网

Exadel Flamingo官网

Exadel Flamingo参考指南

有关Android下使用Hessian与Java服务端通讯

【上篇】
【下篇】

抱歉!评论已关闭.