当前位置:  编程技术>移动开发
本页文章导读:
    ▪手机上的讯息推送        手机上的消息推送       最近在找android手机上的消息推送的。目前看来有以下几种常用的方式: 1.定期查询:按照指定的时间间隔连接服务器查询获取最新的消息。实现起来简单,非实时.........
    ▪ XStream的施用实例        XStream的使用实例       之前发了几篇文章几乎都是代码的,我大学快要毕业了,最近在公司里实习,有两个月不到的样子,之前在大学里也是菜鸟一个,什么也不会,进公司了,学习的机.........
    ▪ xcode4.3.2联机调试时出现错误,无法在真机上运行       xcode4.3.2联机调试时出现异常,无法在真机上运行 xcode4.3.2联机调试时出现异常,无法在真机上运行error: failed to launch '/Users/jpm/Library/Developer/Xcode/DerivedData/phonetest1-gerjuzyynkfhhfgtdklsrehowmgy/Build/.........

[1]手机上的讯息推送
    来源: 互联网  发布时间: 2014-02-18
手机上的消息推送

      最近在找android手机上的消息推送的。目前看来有以下几种常用的方式:

1.定期查询:按照指定的时间间隔连接服务器查询获取最新的消息。实现起来简单,非实时,查询时间过短则流量耗费多,耗电量大。下面是一个爱立信的测试结果:

 

2.短信方式:需要及时发送消息给客户端时也可以通过这种方式,但大家都懂的,这个很花钱。

 

3.长轮询:基本上与目前很多网站使用的方式一样(WEB阿里旺旺、微博、人人等等)。客户端发起一个很长超时时间的请求,然后服务器端在没有消息的时候阻塞这个请求(一直不给返回值)直到快要超时为止,有消息到来再返回响应。客户端收到响应或超时后立即再发起请求。

这种算是比较好的方式了,消息能够及时地到达客户端。但考虑到移动互联网的特点(网络不稳定、设备内存小)这种方式不能保证重要的消息一定能推送到客户端,另外anroid在手机内存小的情况下可能会杀这个在等待PUSH消息不怎么活动的进程。

 

4.C2DM:GOOGLE提供了消息的PUSH功能,需要和GOOGLE账号绑定,目前看来这种方式在国内是没戏的。

 

5.XMPP:在客户端集成asmack,服务器端使用ejabberd或openfire等开源的XMPP服务器软件也是一种可行的方式。

缺点就是先要有注册、登陆等过程,无线网络环境下连接的效果不怎么样。重要消息的PUSH需要自己实现确认逻辑。

 

6.MQTT:基于代理发布/订阅 模式的消息传输协议,适用于受限环境:

    网络代价昂贵、带宽低、不可靠;

    在嵌入设备中运行、处理器和内存资源有限。

特点是:

   使用发布/订阅模式,解除应用程序耦合;

   对负载内容屏蔽的消息传输;

   使用TCP/IP;

   提供“至多一次”、“至少一次”、“有且仅有一次”三种级别的消息传输;

   小型传输、流量开销少;

   使用LAST WILL 和TESTAMENT特性通知有关各方客户端异常中断机制。

(听起来简直就是为移动互联网设计的 )

 

 

下面是基于MQTT的简单实现方案:

 

服务器:

可以采用IBM的MQTT服务器RSMB;

开源的Mosquitto

 

客户端:

IBM的wmqtt.jar 适用于JAVA客户端。

 

1.下载安装运行Mosquitto服务器。

2.在anroid客户端集成以下代码:

import com.ibm.mqtt.IMqttClient;
import com.ibm.mqtt.MqttClient;
import com.ibm.mqtt.MqttException;
import com.ibm.mqtt.MqttPersistence;
import com.ibm.mqtt.MqttPersistenceException;
import com.ibm.mqtt.MqttSimpleCallback;

public class MQTTConnection implements MqttSimpleCallback{
	IMqttClient mqttClient = null;	
	private static int MQTT_PORT =1883; 
	private static MqttPersistence MQTT_PERSISTENCE=null;
	public static String MQTT_CLIENT_ID ="";
	private static boolean MQTT_CLEAN_START = true;
	private static short MQTT_KEEP_ALIVE = 60 * 15;
	private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 } ;
	private long mStartTime;
		
	public MQTTConnection(String brokerHostName, String initTopic) throws MqttException {
		String mqttConnSpec = "tcp://" + brokerHostName + "@" + MQTT_PORT;
    	// Create the client and connect
    	mqttClient = MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE);
    	String clientID = MQTT_CLIENT_ID;
    	mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE);

        // register this client app has being able to receive messages
		mqttClient.registerSimpleHandler(this);
		
		// Subscribe to an initial topic, which is combination of client ID and device ID.
		subscribeToTopic(initTopic);

		// Save start time
		mStartTime = System.currentTimeMillis();
		// Star the keep-alives
		//startKeepAlives();			
	}
	
	private void subscribeToTopic(String topicName) throws MqttException {
		
		if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
			// quick sanity check - don't try and subscribe if we don't have
			//  a connection
			System.out.println("subscribe to topic fail");
		} else {									
			String[] topics = { topicName };
			mqttClient.subscribe(topics, MQTT_QUALITIES_OF_SERVICE);
		}
	}	
	
	public void disconnect() {
		try {			
			mqttClient.disconnect();
		} catch (MqttPersistenceException e) {
			System.out.println("disconnection to server error");
		}
	}

	
	@Override
	public void connectionLost() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("connection to server closed");
	}

	@Override
	public void publishArrived(String topicName, byte[] payload, int qos, boolean retained)
			throws Exception {
		// TODO Auto-generated method stub
		String s = new String(payload);
		System.out.println("push message recived :"+s);
	}
}
 

3.运行客户端程序,在命令窗口中使用Mosquitto_pub.exe -q [Qos级别] -t [主题] -m [发布的内容] 进行测试。

 

 

另:Mosquitto由于使用socket select 模型,能支持的客户端连接数量有限。

如果要支持更高并发量,一方面可以考虑采用“策略服务器+Mosquitto集群”的方式,另一方面可以考虑erlang实现的一些MQTT服务器替换Mosquitto(上次见到的一个类似的发布/订阅系统每秒可以完成向40W订阅用户广播的任务,够牛逼了吧)。

 

 

 

 


    
[2] XStream的施用实例
    来源: 互联网  发布时间: 2014-02-18
XStream的使用实例

      之前发了几篇文章几乎都是代码的,我大学快要毕业了,最近在公司里实习,有两个月不到的样子,之前在大学里也是菜鸟一个,什么也不会,进公司了,学习的机会挺多的,所以将学到的那些东西都记下来,怕是以后忘了还能再回来看看。

如果大家有什么好的意见和建议都可以提示出来。

     在与其他公司接口方面,有用到XStream这个类。想说也跟着写些小实例。XStream是一套简单实用的类库,用于序列化对象与XML对象之间的相互转换,其他都不多说,下面开始做实例喽!

     首先可以写一个XML文件edie.xml。其内容可以如下格式书写:

<?xml version="1.0" encoding="UTF-8" ?>
<Info author="Edie" version="v1.0.2">
	<Id>001</Id>
	<Name>MinMin</Name>
	<QQ>1025771464</QQ>
	<Phone>123456789</Phone>
	<Details>
		<Message>I'm Edie!</Message>
	</Details>
	<Details>
		<Message>I call my lover Shuai!</Message>
	</Details>
	<Details>
		<Message>We all like fish !</Message>
	</Details>
	<Details>
		<Message>He is my forever boy!</Message>
	</Details>
	<Details>
		<Message>嘿嘿,我是菜鸟</Message>
	</Details>
	<Details>
		<Message>Do you want know me more?</Message>
	</Details>
</Info>

 根据XMl文件的书写格式,我们可以新建几个JavaBean,一个是Info.java

package org.mm.bean;

import java.util.List;

public class Info {
private Author author;
private Version version;
private String Id;
private String Name;
private String QQ;
private String Phone;
private List<Detail> Details;
@Override
public String toString() {
    return "Info [author=" + author + ", version=" + version + ", Id=" + Id + ", Name=" + Name
            + ", QQ=" + QQ + ", Phone=" + Phone + ", Details=" + Details + "]";
}
}

 由于XML文件中,Info标签里Details是有多个的,因此在Info类中将Details定义成List。

如此一来,我们就应该明白,应该再新建一个Detail.java

package org.mm.bean;

public class Detail {
private String Message;

@Override
public String toString() {
    return "Message [Message=" + Message + "]";
}
}

 在XML文件中,我有定义两个属性,一个是author,一个是version。这两个我是分别写了两个bean,下面是Author.java

package org.mm.bean;

public class Author {
private String name;

public String getName() {
    return name;
}

public Author(String name) {
    this.name = name;
}

@Override
public String toString() {
    return "Author [name=" + name + "]";
}

}

 

Version.java

package org.mm.bean;

public class Version {

    private String version;

    public String getVersion() {
        return version;
    }

    public Version(String version) {
        this.version = version;
    }

    @Override
    public String toString() {
        return "Version [version=" + version + "]";
    }
    
}

 

最后要写一函数来运行一下。ParseXML.java

package org.mm;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.mm.bean.Detail;
import org.mm.bean.Info;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class ParaXML {

    public static void main(String[] args) throws Exception {
        InputStream in = new FileInputStream("./xml/edie.xml");
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        StringBuffer sb = new StringBuffer();
        String temp = br.readLine();
        while (temp != null) {
            sb.append(temp);
            temp = br.readLine();
        }
        System.err.println(sb.toString());
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("Info", Info.class);

        xstream.useAttributeFor(Info.class, "author");
        xstream.useAttributeFor(Info.class, "version");
        xstream.aliasField("Author", Info.class, "author");
        xstream.aliasField("version", Info.class, "version");
        xstream.registerConverter(new AuthorConverter());
        xstream.registerConverter(new VersionConverter());
        xstream.addImplicitCollection(Info.class, "Details", Detail.class);
        xstream.alias("Details", Detail.class);
        // xstream.aliasField("Message", Detail.class, "message");
        // xstream.aliasField("Id", Info.class, "id");
        // xstream.aliasField("Name", Info.class, "name");
        // xstream.aliasField("QQ", Info.class, "qq");
        // xstream.aliasField("Phone", Info.class, "phone");
        // xstream.aliasField("Detail", Info.class, "detail");
        Info obj = (Info) xstream.fromXML(sb.toString().replaceAll("fish", "bread").replaceAll("apple", "banana"));
        System.out.println("obj:" + obj);
        String xml = xstream.toXML(obj);
        System.out.println(xml);
    }

}

 

在程序中,我们可以看到,是用FileInputStream来读XML文件的,是将xml文件以流的行式读出来,放在BufferReader里面。还有一点即是我将xstream.aliasField()都注释掉了,因为在javabean中,属性的命名和XML文件中命名一样。如果不一样,则需要用aliasField来映射。

Info的两个属性名,在这里我是写了两个Converter来转换的。AuthorConverter.java

package org.mm;

import org.mm.bean.Author;

import com.thoughtworks.xstream.converters.SingleValueConverter;

public class AuthorConverter  implements SingleValueConverter{

    @Override
    public boolean canConvert(@SuppressWarnings("rawtypes") Class type) {
        // TODO Auto-generated method stub
        return type.equals(Author.class);
    }
    @Override
    public Object fromString(String name) {
        // TODO Auto-generated method stub
        return new Author(name);
    }
    @Override
    public String toString(Object obj) {
        // TODO Auto-generated method stub
        return ((Author)obj).getName();
    }

}

 另外一个Converter是VersionConverter.java

package org.mm;

import org.mm.bean.Version;

import com.thoughtworks.xstream.converters.SingleValueConverter;

public class VersionConverter implements SingleValueConverter {

    @Override
    public boolean canConvert(@SuppressWarnings("rawtypes") Class type) {
        return type.equals(Version.class);
    }

    @Override
    public Object fromString(String version) {
        return new Version(version);
    }

    @Override
    public String toString(Object obj) {
        return ((Version) obj).getVersion();
    }

}

 


    
[3] xcode4.3.2联机调试时出现错误,无法在真机上运行
    来源: 互联网  发布时间: 2014-02-18
xcode4.3.2联机调试时出现异常,无法在真机上运行
xcode4.3.2联机调试时出现异常,无法在真机上运行
error: failed to launch '/Users/jpm/Library/Developer/Xcode/DerivedData/phonetest1-gerjuzyynkfhhfgtdklsrehowmgy/Build/Products/Debug-iphoneos/phonetest1.app/phonetest1' -- failed to get the task for process 1500

解决方法如下:
For xcode 4:you have to create Entitlements.plist file from new file. and
Targets->build Settings->Code Signing Entitlements you have to write here "Entitlements.plist"
设置Entitlements.plist的属性Can be debugged=YES(切记在xcode4.3.2上打包应用发布时一定要设置成NO,否则打包成功但无法安装到ios设备上,xcode4.2以下版本则无需设置成NO)

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
编程语言 iis7站长之家
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3