首页 文章 精选 留言 我的

精选列表

搜索[自动化研究],共10000篇文章
优秀的个人博客,低调大师

Android 轻“.NET研究”松实现语音识别

苹果的iphone 有语音识别用的是Google 的技术,做为Google 力推的Android 自然会将其核心技术往Android 系统里面植入,并结合google 的云端技术将其发扬光大。 所以Google Voice Recognition在Android 的实现就变得极其轻松。 语音识别,借助于云端技术可以识别用户的语音输入,包括语音控制等技术,下面我们将利用Google 提供的Api 实现这一功能。 功能点为:通过用户语音将用户输入的语音识别出来,并打印在列表上。 功能界面如下: 用户通过点击speak按钮显示界面: 用户说完话后,将提交到云端搜索: 在云端搜索完成后,返回打印数据: 完整代码如下: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS,上海闵行企业网站制作r /> * WITHOUT WARRANTIE上海企业网站制作S OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.app; import com.example.android.apis.R; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.speech.RecognizerIntent; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import java.util.ArrayList; import java.util.List; /** * Sample code that invokes the speech recognition intent API. */ public class VoiceRecognition extends Activity implements OnClickListener { private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234 ; private ListView mList; /** * Called with the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { 上海网站建设yle="color: #0000ff;">super .onCreate(savedInstanceState); // Inflate our UI from its XML layout description. setContentView(R.layout.voice_recognition); // Get display items for later interaction Button speakButton = (Button) findViewById(R.id.btn_speak); mList = (ListView) findViewById(R.id.list); // Check to see if a recognition activity is present PackageManager pm = getPackageManager(); List < ResolveInfo > activities = pm.queryIntentActivities( new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0 ); if (activities.size() != 0 ) { speakButton.setOnClickListener( this ); } else { speakButton.setEnabled( false );上海闵行企业网站设计与制作='color:white;' href='http://www.93tj.com'>上海徐汇企业网站制作 sp上海企业网站设计与制作eakButton.setText( " Recognizer not present " ); } } /** * Handle the click on the start recognition button. */ public void onClick(View v) { if (v.getId() == R.id.btn_speak) { startVoiceRecognitionActivity(); } } /** * Fire an intent to start the speech recognition activity. */ private void startVoiceRecognitionActivity() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, " Speech recognition demo " ); startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); } /** * Handle the results from the recognition activity. */ @Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) { // Fill the list view with the strings the recognizer thought it could have heard ArrayList < String > matches = data.getStringArrayListExtra( RecognizerIntent.EXTRA_RESULTS); mList.setAdapter( new ArrayAdapter < String > ( this , android.R.layout.simple_list_it上海徐汇企业网站设计与制作em_1, matches)); } super .onActivityResult(requestCode, resultCode, data); }} Tip:本篇 从Api Demo直接复制过来,必须有网络支持。

优秀的个人博客,低调大师

Java-String.intern的深入研究

When---什么时候需要了解String的intern方法: 面试的时候(蜜汁尴尬)!虽然不想承认,不过面试的时候经常碰到这种高逼格的问题来考察我们是否真正理解了String的不可变性、String常量池的设计以及String.intern方法所做的事情。但其实,我们在实际的编程中也可能碰到可以利用String.intern方法来提高程序效率或者减少内存占用的情况,这个我们等下会细说。 What---String.intern方法究竟做了什么: Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java? Language Specification. 上面是jdk源码中对intern方法的详细解释。简单来说就是intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。否则,在常量池中加入该对象,然后 返回引用。下面的一个例子详细的解释了intern的作用过程: Now lets understand how Java handles these strings. When you create two string literals: String name1 = "Ram"; String name2 = "Ram"; In this case, JVM searches String constant pool for value "Ram", and if it does not find it there then it allocates a new memory space and store value "Ram" and return its reference to name1. Similarly, for name2 it checks String constant pool for value "Ram" but this time it find "Ram" there so it does nothing simply return the reference to name2 variable. The way how java handles only one copy of distinct string is called String interning. How---String.intern方法在jdk1.7之前和之后的区别: 简单的说其实就一个:在jdk1.7之前,字符串常量存储在方法区的PermGen Space。在jdk1.7之后,字符串常量重新被移到了堆中。 Back---重回String设计的初衷: Java中的String被设计成不可变的,出于以下几点考虑: 1. 字符串常量池的需要。字符串常量池的诞生是为了提升效率和减少内存分配。可以说我们编程有百分之八十的时间在处理字符串,而处理的字符串中有很大概率会出现重复的情况。正因为String的不可变性,常量池很容易被管理和优化。 2. 安全性考虑。正因为使用字符串的场景如此之多,所以设计成不可变可以有效的防止字符串被有意或者无意的篡改。从java源码中String的设计中我们不难发现,该类被final修饰,同时所有的属性都被final修饰,在源码中也未暴露任何成员变量的修改方法。(当然如果我们想,通过反射或者Unsafe直接操作内存的手段也可以实现对所谓不可变String的修改)。 3. 作为HashMap、HashTable等hash型数据key的必要。因为不可变的设计,jvm底层很容易在缓存String对象的时候缓存其hashcode,这样在执行效率上会大大提升。 Deeper---直接来看例子: 首先来试试下面程序的运行结果是否与预想的一致: 1 String s1 = new String("aaa"); 2 String s2 = "aaa"; 3 System.out.println(s1 == s2); // false 4 5 s1 = new String("bbb").intern(); 6 s2 = "bbb"; 7 System.out.println(s1 == s2); // true 8 9 s1 = "ccc"; 10 s2 = "ccc"; 11 System.out.println(s1 == s2); // true 12 13 s1 = new String("ddd").intern(); 14 s2 = new String("ddd").intern(); 15 System.out.println(s1 == s2); // true 16 17 s1 = "ab" + "cd"; 18 s2 = "abcd"; 19 System.out.println(s1 == s2); // true 20 21 String temp = "hh"; 22 s1 = "a" + temp; 23 // 如果调用s1.intern 则最终返回true 24 s2 = "ahh"; 25 System.out.println(s1 == s2); // false 26 27 temp = "hh".intern(); 28 s1 = "a" + temp; 29 s2 = "ahh"; 30 System.out.println(s1 == s2); // false 31 32 temp = "hh".intern(); 33 s1 = ("a" + temp).intern(); 34 s2 = "ahh"; 35 System.out.println(s1 == s2); // true 36 37 s1 = new String("1"); // 同时会生成堆中的对象 以及常量池中1的对象,但是此时s1是指向堆中的对象的 38 s1.intern(); // 常量池中的已经存在 39 s2 = "1"; 40 System.out.println(s1 == s2); // false 41 42 String s3 = new String("1") + new String("1"); // 此时生成了四个对象 常量池中的"1" + 2个堆中的"1" + s3指向的堆中的对象(注此时常量池不会生成"11") 43 s3.intern(); // jdk1.7之后,常量池不仅仅可以存储对象,还可以存储对象的引用,会直接将s3的地址存储在常量池 44 String s4 = "11"; // jdk1.7之后,常量池中的地址其实就是s3的地址 45 System.out.println(s3 == s4); // jdk1.7之前false, jdk1.7之后true 46 47 s3 = new String("2") + new String("2"); 48 s4 = "22"; // 常量池中不存在22,所以会新开辟一个存储22对象的常量池地址 49 s3.intern(); // 常量池22的地址和s3的地址不同 50 System.out.println(s3 == s4); // false// 对于什么时候会在常量池存储字符串对象,我想我们可以基本得出结论: 1. 显示调用String的intern方法的时候; 2. 直接声明字符串字面常量的时候,例如: String a = "aaa";// 3. 字符串直接常量相加的时候,例如: String c = "aa" + "bb"; 其中的aa/bb只要有任何一个不是字符串字面常量形式,都不会在常量池生成"aabb". 且此时jvm做了优化,不// 会同时生成"aa"和"bb"在字符串常量池中 如果有出入的话,再来看看具体的字节码分析: 1 /** 2 * 字节码为: 3 * 0: ldc #16; //String 11 --- 从常量池加载字符串常量11 4 2: astore_1 --- 将11的引用存到本地变量1,其实就是将s指向常量池中11的位置 5 */ 6 String s = "11"; 7 8 /** 9 * 0: new #16; //class java/lang/String --- 新开辟了一个地址,存储new出来的对象 10 3: dup --- 将new出来的对象复制了一份到栈顶(也就是s1最终指向的是堆中的另一个存储字符串11的地址) 11 4: ldc #18; //String 11 12 6: invokespecial #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V 13 9: astore_1 14 */ 15 String s1 = new String("11"); 16 17 /** 18 * 0: new #16; //class java/lang/StringBuilder --- 可以看到jdk对字符串拼接做了优化,先是建了一个StringBuilder对象 19 3: dup 20 4: new #18; //class java/lang/String --- 创建String对象 21 7: dup 22 8: ldc #20; //String 1 --- 从常量池加载了1(此时常量池和堆中都会存字符串对象) 23 10: invokespecial #22; //Method java/lang/String."<init>":(Ljava/lang/String;)V --- 初始化String("1")对象 24 13: invokestatic #25; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 25 16: invokespecial #29; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V --- 初始化StringBuilder对象 26 19: new #18; //class java/lang/String 27 22: dup 28 23: ldc #20; //String 1 29 25: invokespecial #22; //Method java/lang/String."<init>":(Ljava/lang/String;)V 30 28: invokevirtual #30; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 31 31: invokevirtual #34; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 32 34: astore_1 ---从上可以看到实际上常量池目前只存了1 34 36: invokevirtual #38; //Method java/lang/String.intern:()Ljava/lang/String; --- 调用String.intern中,jdk1.7以后,常量池也是堆中的一部分且常量池可以存引用,这里直接存的是s2的引用 35 39: pop --- 这里直接返回的是栈顶的元素 36 */ 37 String s2 = new String("1") + new String("1"); 38 s2.intern(); 39 40 /** 41 * 0: ldc #16; //String abc --- 可以看到此时常量池直接存储的是:abc, 而不会a、b、c各存一份 42 2: astore_1 43 */ 44 String s3 = "a" + "b" + "c"; 45 46 /** 47 0: new #16; //class java/lang/StringBuilder 48 3: dup 49 4: ldc #18; //String why --- 常量池的why 50 6: invokespecial #20; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 51 9: ldc #23; //String true --- 常量池的true 52 11: invokevirtual #25; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 53 14: invokevirtual #29; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 54 17: astore_1 55 */ 56 String s1 = new StringBuilder("why").append("true").toString(); 57 System.out.println(s1 == s1.intern()); // jdk1.7之前为false,之后为true 下面我们延伸一下来讲讲字符串拼接的优化问题: 1 String a = "1"; 2 for (int i=0; i<10; i++) { 3 a += i; 4 } 6 0: ldc #16; //String 1 7 2: astore_1 8 3: iconst_0 9 4: istore_2 --- 循环开始 10 5: goto 30 11 8: new #18; //class java/lang/StringBuilder --- 每个循环都建了一个StringBuilder对象,对性能有损耗 12 11: dup 13 12: aload_1 14 13: invokestatic #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 15 16: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 16 19: iload_2 17 20: invokevirtual #29; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 18 23: invokevirtual #33; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 19 26: astore_1 20 27: iinc 2, 1 ---- 计数加1 21 30: iload_2 22 31: bipush 10 23 33: if_icmplt 8 24 25 String a = "1"; 26 for (int i=0; i<10; i++) { 27 a += "1"; 28 } 29 的字节码为: 30 0: ldc #16; //String 1 31 2: astore_1 32 3: iconst_0 33 4: istore_2 34 5: goto 31 35 8: new #18; //class java/lang/StringBuilder ---还是会每次建立一个StringBuilder对象 36 11: dup 37 12: aload_1 38 13: invokestatic #20; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 39 16: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 40 19: ldc #16; //String 1 ---和上一个循环的区别也仅仅在于这里是从常量池加载1, 41 21: invokevirtual #29; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 42 24: invokevirtual #33; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 43 27: astore_1 44 28: iinc 2, 1 45 31: iload_2 46 32: bipush 10 47 34: if_icmplt 8 可知,真正的性能瓶颈在于每次循环都建了一个StringBuilder对象所以我们优化一下 :50 StringBuilder sb = new StringBuilder("1"); 51 for (int i=0; i<10; i++) { 52 sb.append("1"); 53 }对应的字节码为:55 0: new #16; //class java/lang/StringBuilder -- 在循环直接初始化了StringBuilder对象 56 3: dup 57 4: ldc #18; //String 1 58 6: invokespecial #20; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 59 9: astore_1 60 10: iconst_0 61 11: istore_2 62 12: goto 25 63 15: aload_1 64 16: ldc #18; //String 1 65 18: invokevirtual #23; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 66 21: pop 67 22: iinc 2, 1 68 25: iload_2 69 26: bipush 10 70 28: if_icmplt 15 Where---String.intern的使用: 我们直接看一个例子来结束String.intern之旅吧: 1 Integer[] DB_DATA = new Integer[10]; 2 Random random = new Random(10 * 10000); 3 for (int i = 0; i < DB_DATA.length; i++) { 4 DB_DATA[i] = random.nextInt(); 5 } 6 long t = System.currentTimeMillis(); 7 for (int i = 0; i < MAX; i++) { 8 arr[i] = new String(String.valueOf(DB_DATA[i % DB_DATA.length])); // --- 每次都要new一个对象 9 // arr[i] = new String(String.valueOf(DB_DATA[i % DB_DATA.length])).intern(); --- 其实虽然这么多字符串,但是类型最多为10个,大部分重复的字符串,大大减少内存 10 } 11 12 System.out.println((System.currentTimeMillis() - t) + "ms"); 13 System.gc(); 参考链接: http://www.360doc.com/content/14/0721/16/1073512_396062351.shtml https://www.cnblogs.com/SaraMoring/p/5713732.html黎明前最黑暗,成功前最绝望!

优秀的个人博客,低调大师

JPDA 架构研究18 - JDI的Mirror机制

引入: 上篇文章从整体上来看待JDI协议,这里结合Eclipse的实现代码来讨论下JDI的Mirror机制。 分析: 镜像机制是将目标虚拟机上的所有数据、类型、域、方法、事件、状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成 Mirror 对象。其思想和我们经常说的O/R Mapping一样,其主要思想就是把2个异构的系统中的事物统一起来。 Mirror接口是JDI规范中定义的主接口,它位于com.sun.jdi包中: 1 2 3 4 5 public abstract interface Mirror { public abstract StringtoString(); public abstract VirtualMachinevirtualMachine(); } 这个接口只提供了2个方法,一个是返回该镜像的字符串描述,一个是获取某镜像的实例的虚拟机。 Mirror机制定义了一个庞大的接口hierarchy, com.sun.jdi包中定义的几乎所有接口都直接或者间接继承了Mirror接口,从而把庞大的Debug过程中用到的任何元素,过程,事件都映射起来。 比如基本类型的值被映射为PrimitiveValue, 对象实例被映射为ObjectReference等。 在Eclipse中,它提供了MirrorImpl的镜像实现类,其中获取镜像虚拟机的代码是读取成员变量fVirtualMachineImpl字段,该字段在构造器中初始化: 1 2 3 4 5 6 7 8 9 public MirrorImpl(Stringdescription) { this .fDescription=description; this .fVirtualMachineImpl=((VirtualMachineImpl) this ); PrintWriterwriter=((VirtualMachineManagerImpl) Bootstrap.virtualMachineManager()).verbosePrintWriter(); if (writer!= null ) this .fVerboseWriter= new VerboseWriter(writer); } 虚拟机类提供了许多方法来直接或间接地获取目标虚拟机上所有的数据和状态信息,也可以挂起、恢复、终止目标虚拟机。这样调试器就可以通过某个Mirror,然后间接获得对应虚拟机,并且发送相应指令来完成相应操作了。 本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1587968,如需转载请自行联系原作者

优秀的个人博客,低调大师

基于XMPP协议的Android IM研究一

之前在做基于XMPP协议的Android IM项目的过程中遇到了不少问题,由于国内这方面的资料相对比较少,而且不够全面,经过不断的学习和请教,项目有了一点进展,下面分享一下在项目的过程中遇到的问题和解决办法。 首先,声明XMPP连接: Java代码 publicstaticfinalConnectionConfigurationconnConfig=newConnectionConfiguration("169.254.50.19",5222,"http://06peng.com"); publicstaticXMPPConnectionconnection; ConnectionConfiguration类的三个参数分别为ip地址,端口号,域名。 建立XMPP连接 Java代码 static{ connConfig.setSASLAuthenticationEnabled(true);//不使用SASL验证,设置为false connection=newXMPPConnection(connConfig); connection.connect();//连接 connection.login("06peng","111111");//登陆 } 这样就能够和服务器连接了,运行代码,结果悲剧。报下面的错误: Java代码 java.security.KeyStoreException:KeyStorejksimplementationnotfound 还有: Java代码 SASLauthenticationfailedusingmechanismPLAIN: 验证不通过,可是我已经设置了不使用SASL验证了,居然还出现这样的问题,于是看官方网站的例子,发现前面加了下面的配置: Java代码 ConnectionConfigurationconnectionConfig=newConnectionConfiguration(host,5222,""); connectionConfig.setTruststorePath("/system/etc/security/cacerts.bks"); connectionConfig.setTruststorePassword("changeit"); connectionConfig.setTruststoreType("bks"); 好吧,加上这样的验证代码应该是没问题了,哪知道一运行,还是悲剧,继续报错: Java代码 not-authorized(401) atorg.jivesoftware.smack.NonSASLAuthentication.authenticate(NonSASLAuthentication.java:109) atorg.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:239) atorg.jivesoftware.smack.Connection.login(Connection.java:353) 鉴权失败,不过至少不报KeyStore jks implementation not found的错误了。于是,继续看官方例子,寻找相关资料,结果修改代码如下: Java代码 connConfig.setReconnectionAllowed(true); connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); connConfig.setSASLAuthenticationEnabled(true); connConfig.setTruststorePath("/system/etc/security/cacerts.bks"); connConfig.setTruststorePassword("changeit"); connConfig.setTruststoreType("bks"); connection=newXMPPConnection(connConfig); 一运行,通过了,心里那个激动啊。。。 感谢博客园一位叫“没有代码”的哥们,给了我一些建议,受到了帮助和启发。 由于代码写的比较复杂,主要就是引用了比较多的类和接口,所以不贴出来了,因为很麻烦,这里介绍一些比较简单的例子: Java代码 connection.getAccountManager().createAccount(username,password);//创建一个用户 Java代码 roster.removeEntry(roster.getEntry(friendName));//删除某个好友 Java代码 roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all); roster.createEntry(user,nickname,friends);//添加一个好友到朋友组上 Java代码 Collection<RosterEntry>entries=roster.getEntries(); for(Iterator<RosterEntry>entry=entries.iterator();entry.hasNext();){ RosterEntryre=entry.next();//获取所有好友 } 相关属性的介绍: 1、ConnectionConfiguration 作为用于与XMPP服务建立连接的配置。它能配置;连接是否使用TLS,SASL加密。 包含内嵌类:ConnectionConfiguration.SecurityMode 2、XMPPConnection. XMPPConnection这个类用来连接XMPP服务. 可以使用connect()方法建立与服务器的连接。disconnect()方法断开与服务器的连接. 在创建连接前可以使用XMPPConnection.DEBUG_ENABLED = true; 使开发过程中可以弹出一个GUI窗口,用于显示我们的连接与发送Packet的信息。 3、ChatManager 用于监控当前所有chat。可以使用createChat(String userJID, MessageListener listener)创建一个聊天。 4、Chat Chat用于监控两个用户间的一系列message。使用addMessageListener(MessageListener listener)当有任何消息到达时将会触发listener的processMessage(Chat chat, Message message) 5、Message Message用于表示一个消息包(可以用调试工具看到发送包和接收包的具体内容)。它有以下多种类型。 Message.Type.NORMAL -- (默认)文本消息(比如邮件) Message.Type.CHAT -- 典型的短消息,如QQ聊天的一行一行显示的消息 Message.Type.GROUP_CHAT -- 群聊消息 Message.Type.HEADLINE -- 滚动显示的消息 Message.TYPE.ERROR -- 错误的消息 Message有两个内部类: Message.Body -- 表示消息体 Message.Type -- 表示消息类型 6、Roster 表示存储了很多RosterEntry的一个花名册.为了易于管理,花名册的项被分贝到了各个group中. 当建立与XMPP服务的连接后可以使用connection.getRoster()获取Roster对象。 别的用户可以使用一个订阅请求(相当于QQ加好友)尝试订阅目的用户。可以使用枚举类型Roster.SubscriptionMode的值处理这些请求: accept_all: 接收所有订阅请求 reject_all:拒绝所有订阅请求 manual:手工处理订阅请求 创建组:RosterGroup group = roster.createGroup("大学"); 向组中添加RosterEntry对象: group.addEntry(entry); 7、RosterEntry 表示Roster(花名册)中的每条记录.它包含了用户的JID,用户名,或用户分配的昵称. 8、RosterGroup 表示RosterEntry的组。可以使用addEntry(RosterEntry entry)添加。contains(String user) 判断某用户是否在组中.当然removeEntry(RosterEntry entry)就是从组中移除了。getEntries()获取所有RosterEntry. 9、Presence 表示XMPP状态的packet。每个presence packet都有一个状态。 用枚举类型Presence.Type的值表示: available -- (默认)用户空闲状态 unavailable -- 用户没空看消息 subscribe -- 请求订阅别人,即请求加对方为好友 subscribed -- 统一被别人订阅,也就是确认被对方加为好友 unsubscribe -- 他取消订阅别人,请求删除某好友 unsubscribed -- 拒绝被别人订阅,即拒绝对放的添加请求 error -- 当前状态packet有错误 内嵌两个枚举类型:Presence.Mode和Presence.Type. 具体使用方法可参考前一篇文章中的Smack中文文档。 本文转自06peng 51CTO博客,原文链接:http://blog.51cto.com/06peng/963449,如需转载请自行联系原作者

优秀的个人博客,低调大师

JPDA 架构研究19 - JDI的连接模块

引入: 上文提到了JDI的Mirror机制,把整个目标虚拟机上的所有数据、类型、域、方法、事件、状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成Mirror 对象。这里进一步讨论JDI的链接模块。 分析: 连接模块其主要目的是提供调试器(Debugger)到目标虚拟机(Target VM)之间的交互通道。 从连接的发起方来看:连接的发起方可以是调试器,也可以是目标虚拟机。 从连接的数量来看,一个调试器可以连接多个目标VM, 但是一个目标VM只可以连接一个调试器。 我们从调试器(Debugger)的角度,可以把连接分为主动连接和被动连接。 分类1:主动连接 (它表示调试器主动去连接Target VM) 又分两种情况: a. 当Target VM还没启动时,则使用LaunchingConnector这种形式的连接器,它会启动目标VM并连接。 Step 1: 调试器调用 VirtualMachineManager 的 launchingConnectors()方法获取所有的LaunchingConnector的实例。 1 2 3 4 5 6 7 public List<LaunchingConnector>launchingConnectors() { ArrayListlist= new ArrayList( 2 ); list.add( new SocketLaunchingConnectorImpl( this )); list.add( new SocketRawLaunchingConnectorImpl( this )); return list; } Step 2:根据传输方式或其他特征选择一个LaunchingConnector,调用其 launch() 方法启动并且连接目标虚拟机 。启动后,返回目标虚拟机的实例。 比如说,如果选用SocketLaunchingConnectorImpl,则它的launch()方法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public VirtualMachinelaunch(Map<String,? extends Connector.Argument>connectionArgs) throws IOException,IllegalConnectorArgumentsException,VMStartException { getConnectionArguments(connectionArgs); SocketListeningConnectorImpllistenConnector= new SocketListeningConnectorImpl( virtualMachineManager()); Mapargs=listenConnector.defaultArguments(); ((Connector.IntegerArgument)args.get( "timeout" )).setValue( 10000 ); Stringaddress=listenConnector.startListening(args); Stringslash=System.getProperty( "file.separator" ); StringexecString= this .fHome+slash+ "bin" +slash+ this .fLauncher; execString=execString+ "-Xdebug-Xnoagent-Djava.compiler=NONE" ; execString=execString+ "-Xrunjdwp:transport=dt_socket,address=" +address+ ",server=n,suspend=" +( this .fSuspend? "y" : "n" ); if ( this .fOptions!= null ){ execString=execString+ "" + this .fOptions; } execString=execString+ "" + this .fMain; String[]cmdLine=DebugPlugin.parseArguments(execString); Processproc=Runtime.getRuntime().exec(cmdLine); try { virtualMachine=(VirtualMachineImpl)listenConnector.accept(args); } catch (InterruptedIOExceptionlocalInterruptedIOException) { VirtualMachineImplvirtualMachine; proc.destroy(); Stringmessage=NLS.bind(ConnectMessages.SocketLaunchingConnectorImpl_VM_did_not_connect_within_given_time___0__ms_1, new String[]{ ((Connector.IntegerArgument)args .get( "timeout" )).value()}); throw new VMStartException(message,proc); } VirtualMachineImplvirtualMachine; virtualMachine.setLaunchedProcess(proc); return virtualMachine; } b.当Target VM已经启动时,则使用AttachingConnector这种形式的连接器,它会挂接到目标虚拟机上。 前提是,Target VM必须以以下方式启动 -agentlib:jdwp=transport=xxx,server=y 参数启动,并根据传输方式生成监听地址。 Step1:调试器启动,调用 VirtualMachineManager 的 attachingConnectors() 方法获取所有的AttachingConnector的实例。 1 2 3 4 5 public List<AttachingConnector>attachingConnectors() { ArrayListlist= new ArrayList( 1 ); list.add( new SocketAttachingConnectorImpl( this )); return list; Step 2: 根据目标虚拟机采用的传输方式选择一个AttachingConnector,调用其 attach() 方法挂接到目标虚拟机上。完成连接后,返回目标虚拟机的实例。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public VirtualMachineattach(Map<String,? extends Connector.Argument>connectionArgs) throws IOException,IllegalConnectorArgumentsException { getConnectionArguments(connectionArgs); Connectionconnection= null ; try { connection=((SocketTransportImpl) this .fTransport).attach( this .fHostname, this .fPort, this .fTimeout,0L); } catch (IllegalArgumentExceptione){ Listargs= new ArrayList(); args.add( "hostname" ); args.add( "port" ); throw new IllegalConnectorArgumentsException(e.getMessage(),args); } return establishedConnection(connection); } 分类2:被动连接(它表示Debugger被动地等待或者监听由Target VM发起的连接) 前提是,Target VM必须以以下方式启动 -agentlib:jdwp=transport=xxx,address=yyy 参数启动,并根据传输方式生成监听地址。 Step 1:调试器通过 VirtualMachineManager 的 listeningConnectors() 方法获取所有的ListeningConnector实例。 1 2 3 4 5 6 public List<ListeningConnector>listeningConnectors() { ArrayListlist= new ArrayList( 1 ); list.add( new SocketListeningConnectorImpl( this )); return list; } Step 2:调用ListeningConnector的 startListening() 方法让连接器进入监听状态。通过 accept() 方法通知连接器开始等待正确的入站链接,该方法将返回调试器正在监听的地址描述符;目标虚拟机会自动地 attach 到调试器上建立连接,然后返回目标虚拟机的实例。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public StringstartListening(Map<String,? extends Connector.Argument>connectionArgs) throws IOException,IllegalConnectorArgumentsException { getConnectionArguments(connectionArgs); Stringresult= null ; try { result=((SocketTransportImpl) this .fTransport).startListening( this .fPort); } catch (IllegalArgumentExceptionlocalIllegalArgumentException){ throw new IllegalConnectorArgumentsException( ConnectMessages.SocketListeningConnectorImpl_ListeningConnector_Socket_Port, "port" ); } return result; } 本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1588011,如需转载请自行联系原作者

优秀的个人博客,低调大师

【MSN Direct研究笔记】MSN Direct项目简介

提起MSN,大家首先想到的就是MSN Message即时通讯软件,其实MSN Message远不是MSN的全部,MSN的英文全称为Microsoft Server Network(微软网络服务),起源于1995年8月24日微软创建的因特网接入服务,其提供类似CompuServe及AOL的收费服务,如拨号上网、增值信息及聊天室等服务,同时也允许其他互联网用户通过因特网来使用。 而MSN Direct,则是由微软前总裁比尔盖茨在2003年提出的一种网络信息服务,它是通过FM信号来传输信息的一种技术(微软公司与SCA数据系统公司联合研发的DirectBand无线电技术)。 (2003年11月16日于拉斯维加斯的Comdex贸易展) 使用该项服务的首批设备是由Fossil和Suunto等公司制造的手表,再以后是能显示天气预报的咖啡壶,最近的产品是在北美有着广泛应用的GPS实时交通导航系统。 (2009年5月拍摄于西雅图MSN Direct部门展厅) 其核心技术架构如下: Garmin PND设备MSN Direct截图(如下图): 该设备可以接收交通、天气、油价、股票、新闻、本地信息等等内容,此外还可以订阅专属于个人相关的信息(如定制的新闻、股票等等)。 这时候也许有人会问,为什么在通信技术发达的今天,还要采用FM副载波技术这种相对比较老的技术,比如GPRS就是很好的技术(其实目前国内的一些PND公司就是采用了GPRS进行实时交通信息传输)。 理由如下: 1、 成本相对低廉。 2、 技术创新,特别是采用了LDPC技术,大大提高了通信成功率,有效地提高了带宽,为可靠传输大量实时的信息提供了技术保障。 3、 对交通实时信息来说,广播对点对点通信来说,更节省资源,符合目前时代发展的大趋势。 近几年来,由于采用了MSN Direct技术的PND设备,在北美地区得到比较好的应用和推广,所以目前该项技术也来到了中国,目前在台北和北京已经有条不紊的开展了试点工作。 MSN Direct包括各种软硬件、服务器技术: 硬件设备:由SCA数据系统公司提供DirectBand无线电技术和设备,美国国家半导体公司为SPOT产品提供芯片。 系统平台:PND系统 WINCE ;FM接收系统 .net Micro framework;服务器 windows Server 2008 R2 /Windows Server 2003 数据库:SQL2005 四大服务程序:C#语言开发 此外还有各式各样的开发和调试工具,所以要想熟练掌握MSN Direct技术,至少需要熟悉软硬件开发、通信、数据库等相关技术。 最近为了利于快速开发新的channels,一直在看MSN Direct系统的源码,发现其架构设计及技术实现细节都有不俗之处,值得深入钻研揣摩。所以今后也会针对于此,陆续写点这方面的技术心得。 (我的工作平台) 官方网站: http://www.msndirect.com/ 相关文章: 1、使用“智能手表”与您的 Outlook 日历保持连接 http://office.microsoft.com/zh-cn/outlook/HA011196242052.aspx 2、微软SPOT咖啡壶上市 用MSN Direct获知天气 http://tech.163.com/06/1117/08/304AOBKI000915BD.html 3、畅享网络资源!MSN Direct与GPS联姻 http://www.51gps.com/news/HTML/6052.html 本文转自yefanqiu51CTO博客,原文链接:http://blog.51cto.com/yfsoft/324238,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册