前两篇简单介绍了下Web Service。下面就将此项技术与开源项目androidpn结合起来,实现服务器向android手机端推送消息

首先在eclipse中打开Androidpn服务器端,然后我们就准备将服务器端推送消息的方法暴露出来,在写代码前我们要将发布Web Service要用到的jar包拷贝到Androidpn工程中的WebRoot-->WEB-INF->lib目录下,要拷贝的几个jar包如下所示:

这些jar包都可以在D:\apache-cxf-2.4.0\lib目录下找到(这里是我的目录,也就是可以在解压得到的apache-cxf-2.4.0的lib目录下找到这些jar包)。

首先我们要将服务器端向android手机端发送消息的三个方法找到,通过之前我的跟踪调试发现androidpn是通过org.androidpn.server.xmpp.push.NotificationManager类里的sendBroadcast、sendAllBroadcast和sendNotifications三个方法来分别向所有在线用户、所有用户、指定用户发送信息的。找到方法后,我们现在要做的就是将其暴露出来。前面说过发布Web Service需要2个部分:接口和实现类。下面我们就在工程的Java Resources-->src目录下新建一个接口及其实现类,代码如下:

查看文本打印?
  1. package org.YL.cxf.ws;
  2. import javax.jws.WebService;
  3. @WebService
  4. public interface AndroidPushNotification {
  5. public void sendBroadcast(String apiKey, String title, String message);
  6. public void sendAllBroadcast(String apiKey, String title, String message);
  7. void sendNotifications(String apiKey, String username,
  8. String title, String message);
  9. }

注意上面的接口定义前有@WebService关键字。然后AndroidPushNotification接口的 实现 代码:

查看文本打印?
  1. package org.YL.cxf.ws.impl;
  2. import javax.jws.WebService;
  3. import org.YL.cxf.ws.AndroidPushNotification;
  4. import org.androidpn.server.console.controller.NotificationController;
  5. import org.androidpn.server.xmpp.push.NotificationManager;
  6. /*endpointInterface="org.YL.cxf.ws.AndroidPushNotification"为暴露的接口,
  7. serviceName="AndroidPushNotificationWs" 为服务名随便取*/
  8. @WebService(endpointInterface="org.YL.cxf.ws.AndroidPushNotification",serviceName="AndroidPushNotificationWs")
  9. public class AndroidPushNotificationWs implements AndroidPushNotification {
  10. public void sendBroadcast(String apiKey, String title, String message) {
  11. // TODO Auto-generated method stub
  12. String uri = NotificationController.myuri;
  13. NotificationManager nm = new NotificationManager();
  14. nm.sendBroadcast(apiKey, title, message, uri);
  15. }
  16. public void sendAllBroadcast(String apiKey, String title, String message) {
  17. // TODO Auto-generated method stub
  18. String uri = NotificationController.myuri;
  19. NotificationManager nm = new NotificationManager();
  20. nm.sendAllBroadcast(apiKey, title, message, uri);
  21. }
  22. public void sendNotifications(String apiKey, String username, String title,
  23. String message) {
  24. // TODO Auto-generated method stub
  25. String uri = NotificationController.myuri;
  26. NotificationManager nm = new NotificationManager();
  27. nm.sendNotifications(apiKey, username, title, message, uri);
  28. }
  29. }

在发送信息的过程中需要uri,而uri在org.androidpn.server.console.controller.NotificationController中设置。为了获得此uri我在此类中定义了一个public static的String 成员 myuri,然后将此类中将uri赋值给myuri。下面是我修改后org.androidpn.server.console.controller.NotificationController类的代码:

查看文本打印?
  1. /*
  2. * Copyright (C) 2010 Moduad Co., Ltd.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. package org.androidpn.server.console.controller;
  19. import javax.servlet.http.HttpServletRequest;
  20. import javax.servlet.http.HttpServletResponse;
  21. import org.androidpn.server.util.Config;
  22. import org.androidpn.server.xmpp.push.NotificationManager;
  23. import org.springframework.web.bind.ServletRequestUtils;
  24. import org.springframework.web.servlet.ModelAndView;
  25. import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
  26. /**
  27. * A controller class to process the notification related requests.
  28. *
  29. * @author Sehwan Noh (devnoh@gmail.com)
  30. */
  31. public class NotificationController extends MultiActionController {
  32. public static String myuri;
  33. private NotificationManager notificationManager;
  34. public NotificationController() {
  35. notificationManager = new NotificationManager();
  36. }
  37. public ModelAndView list(HttpServletRequest request,
  38. HttpServletResponse response) throws Exception {
  39. ModelAndView mav = new ModelAndView();
  40. // mav.addObject("list", null);
  41. mav.setViewName("notification/form");
  42. return mav;
  43. }
  44. public ModelAndView send(HttpServletRequest request,
  45. HttpServletResponse response) throws Exception {
  46. String broadcast = ServletRequestUtils.getStringParameter(request,
  47. "broadcast", "Y");
  48. String username = ServletRequestUtils.getStringParameter(request,
  49. "username");
  50. String title = ServletRequestUtils.getStringParameter(request, "title");
  51. String message = ServletRequestUtils.getStringParameter(request,
  52. "message");
  53. String uri = ServletRequestUtils.getStringParameter(request, "uri");
  54. myuri = uri;
  55. String apiKey = Config.getString("apiKey", "");
  56. logger.debug("apiKey=" + apiKey);
  57. //在线用户
  58. if (broadcast.equalsIgnoreCase("Y")) {
  59. notificationManager.sendBroadcast(apiKey, title, message, uri);
  60. //所有用户
  61. }else if (broadcast.equalsIgnoreCase("A")) {
  62. notificationManager.sendAllBroadcast(apiKey, title, message, uri);
  63. //指定用户
  64. }else {
  65. notificationManager.sendNotifications(apiKey, username, title,
  66. message, uri);
  67. }
  68. ModelAndView mav = new ModelAndView();
  69. mav.setViewName("redirect:notification.do");
  70. return mav;
  71. }
  72. }

所做的处理就是在类的最前面定义一个public static String myuri,然后在public ModelAndView send(HttpServletRequest request,
            HttpServletResponse response) throws Exception中将uri赋值给myuri。

接口代码写完后,我们还需要更改下WebRoot-->WEB-INF下的web.xml配置文件,更改后的配置文件如下:

查看文本打印?
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  5. <listener>
  6. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  7. </listener>
  8. <context-param>
  9. <!-- 指定Spring配置文件  -->
  10. <param-name>contextConfigLocation</param-name>
  11. <!-- 指定Spring配置文件位置  -->
  12. <param-value>/WEB-INF/applicationContext.xml</param-value>
  13. </context-param>
  14. <display-name>androidpn-server</display-name>
  15. <filter>
  16. <filter-name>encodingFilter</filter-name>
  17. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  18. <init-param>
  19. <param-name>encoding</param-name>
  20. <param-value>UTF-8</param-value>
  21. </init-param>
  22. <init-param>
  23. <param-name>forceEncoding</param-name>
  24. <param-value>true</param-value>
  25. </init-param>
  26. </filter>
  27. <filter>
  28. <filter-name>sitemesh</filter-name>
  29. <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
  30. </filter>
  31. <filter-mapping>
  32. <filter-name>encodingFilter</filter-name>
  33. <url-pattern>/*</url-pattern>
  34. </filter-mapping>
  35. <filter-mapping>
  36. <filter-name>sitemesh</filter-name>
  37. <url-pattern>/*</url-pattern>
  38. <dispatcher>REQUEST</dispatcher>
  39. <dispatcher>FORWARD</dispatcher>
  40. </filter-mapping>
  41. <!-- 下面配置表明所有来自/>androidpnservice/*请求,都交给CXFServlet来处理  -->
  42. <servlet>
  43. <servlet-name>cxf</servlet-name>
  44. <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  45. </servlet>
  46. <servlet-mapping>
  47. <servlet-name>cxf</servlet-name>
  48. <url-pattern>/androidpnservice/*</url-pattern>
  49. </servlet-mapping>
  50. <servlet>
  51. <servlet-name>dispatcher</servlet-name>
  52. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  53. <load-on-startup>1</load-on-startup>
  54. </servlet>
  55. <servlet-mapping>
  56. <servlet-name>dispatcher</servlet-name>
  57. <url-pattern>*.do</url-pattern>
  58. </servlet-mapping>
  59. <session-config>
  60. <session-timeout>30</session-timeout>
  61. </session-config>
  62. <welcome-file-list>
  63. <welcome-file>/index.html</welcome-file>
  64. <welcome-file>/index.jsp</welcome-file>
  65. <welcome-file>/index.do</welcome-file>
  66. </welcome-file-list>
  67. <error-page>
  68. <error-code>400</error-code>
  69. <location>/index.jsp</location>
  70. </error-page>
  71. <error-page>
  72. <error-code>403</error-code>
  73. <location>/403.jsp</location>
  74. </error-page>
  75. <error-page>
  76. <error-code>404</error-code>
  77. <location>/404.jsp</location>
  78. </error-page>
  79. <error-page>
  80. <error-code>500</error-code>
  81. <location>/error.jsp</location>
  82. </error-page>
  83. </web-app>

其中

查看文本打印?
  1. <!-- 下面配置表明所有来自/>androidpnservice/*请求,都交给CXFServlet来处理  -->
  2. <servlet>
  3. <servlet-name>cxf</servlet-name>
  4. <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>cxf</servlet-name>
  8. <url-pattern>/androidpnservice/*</url-pattern>
  9. </servlet-mapping>

查看文本打印?
  1. <listener>
  2. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  3. </listener>
  4. <context-param>
  5. <!-- 指定Spring配置文件  -->
  6. <param-name>contextConfigLocation</param-name>
  7. <!-- 指定Spring配置文件位置  -->
  8. <param-value>/WEB-INF/applicationContext.xml</param-value>
  9. </context-param>

是新添加的。

上面还指定了一个/WEB-INF/applicationContext.xml的配置文件,这个文件是我新添加进去的,是为了发布Web Service用的,此文件内容为:

查看文本打印?
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:jaxws="http://cxf.apache.org/jaxws"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8. http://cxf.apache.org/jaxws
  9. http://cxf.apache.org/schemas/jaxws.xsd">
  10. <import resource="classpath:META-INF/cxf/cxf.xml"/>
  11. <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  12. <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
  13. <jaxws:endpoint
  14. implementor = "org.YL.cxf.ws.impl.AndroidPushNotificationWs"
  15. address = "/androidpush">
  16. </jaxws:endpoint>
  17. </beans>

其中

查看文本打印?
  1. <jaxws:endpoint
  2. implementor = "org.YL.cxf.ws.impl.AndroidPushNotificationWs"
  3. address = "/androidpush">
  4. </jaxws:endpoint>

指定发布的Web Service的 实现 类和在获得WSDL描述文档时在“?”前面的服务名。

好了现在一切就绪,我们运行Androidpn服务器端程序,成功运行起来后,我们在浏览器地址栏中输入:http://192.168.1.117:8080/androidpnservice/androidpush?wsdl(192.168.1.117:8080是我本机的IP地址和tomcat的端口) 可得到WSDL描述文档如下(部分截图):

这时表明我们的服务端推送消息的方法发布成功,我们在来看客户端。

首先我们在eclipse中建立一个名为PushClient的空的Java Project,初始时什么也没有:

然后我们用cxf的wsdl2java来生成客户端代码:

在回到PushClient工程中刷新下(F5),可得:

为了方便调用,我又写了一个org.yl.SendNotification类,代码如下:

查看文本打印?
  1. package org.yl;
  2. import org.yl.cxf.ws.AndroidPushNotification;
  3. import org.yl.cxf.ws.impl.AndroidPushNotificationWs;
  4. public class SendNotification {
  5. AndroidPushNotificationWs factory = new AndroidPushNotificationWs();
  6. AndroidPushNotification apn = factory.getAndroidPushNotificationWsPort();
  7. public void sendBroadcast(String apiKey, String title, String message)
  8. {
  9. apn.sendAllBroadcast(apiKey, title, message);
  10. }
  11. public void sendAllBroadcast(String apiKey, String title, String message)
  12. {
  13. apn.sendBroadcast(apiKey, title, message);
  14. }
  15. public void sendNotifications(String apiKey, String username,
  16. String title, String message)
  17. {
  18. apn.sendNotifications(apiKey,username,title,message);
  19. }
  20. }

以后调用发送 消息 的方法时,只需要定义一个SendNotification对象,通过此对象就可以方便的调用方法了,避免每次调用时都

查看文本打印?
  1. AndroidPushNotificationWs factory = new AndroidPushNotificationWs();
  2. AndroidPushNotification apn = factory.getAndroidPushNotificationWsPort();

然后写一个主函数类来测试我们的整个系统,代码如下:

查看文本打印?
  1. package org.main;
  2. import org.yl.SendNotification;
  3. public class CallMain {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. SendNotification sn = new SendNotification();
  10. //给所有人发信息,这里第一个参数"1234567890"是androidpn中的apikey,在androidpn中是写死了的,第二个参数为<strong>消息</strong>标题(title),第三个参数为<strong>消息</strong>内容(message)
  11. sn.sendAllBroadcast("1234567890", "hello", "How are you?");
  12. //给在线人发信息,参数同上
  13. //sn.sendBroadcast("1234567890", "Hi", "OK");
  14. //给指定人发信息,  第一、三、四个<strong>消息</strong>的意义同上,第二个参数"4ed224a3fa8c4560a27e313ab24f597d"是用户名,可以在<strong>服务器</strong>端页面看到。
  15. //  sn.sendNotifications("1234567890","4ed224a3fa8c4560a27e313ab24f597d", "Hello Hi", "Hello World! How are you?");
  16. }
  17. }

在整个工程中,如下所示,红圈中是我手动添加的代码,其他的都cxf工具自动生成的。

好了,现在就来测试下我们的推送消息系统。

首先将Androidpn开源项目的客户端在模拟器重运行起来,然后回到PushClient工程,在主函数中将其他方法注释掉,只留下:

sn.sendAllBroadcast()方法,如下所示:

查看文本打印?
  1. package org.main;
  2. import org.yl.SendNotification;
  3. public class CallMain {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. SendNotification sn = new SendNotification();
  10. //给所有人发信息,这里第一个参数"1234567890"是androidpn中的apikey,在androidpn中是写死了的,第二个参数为<strong>消息</strong>标题(title),第三个参数为<strong>消息</strong>内容(message)
  11. sn.sendAllBroadcast("1234567890", "hello", "How are you?");
  12. //给在线人发信息,参数同上
  13. //sn.sendBroadcast("1234567890", "Hi", "OK");
  14. //给指定人发信息,  第一、三、四个<strong>消息</strong>的意义同上,第二个参数"4ed224a3fa8c4560a27e313ab24f597d"是用户名,可以在<strong>服务器</strong>端页面看到。
  15. //  sn.sendNotifications("1234567890","4ed224a3fa8c4560a27e313ab24f597d", "Hello Hi", "Hello World! How are you?");
  16. }
  17. }

然后运行程序,可看到模拟器中接收到了推送主题为:hello,内容为:How  are you?的 消息 。

同理注释掉其他方法直留下:sn.sendBroadcast()方法:

查看文本打印?
  1. package org.main;
  2. import org.yl.SendNotification;
  3. public class CallMain {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. SendNotification sn = new SendNotification();
  10. //给所有人发信息,这里第一个参数"1234567890"是androidpn中的apikey,在androidpn中是写死了的,第二个参数为<strong>消息</strong>标题(title),第三个参数为<strong>消息</strong>内容(message)
  11. //sn.sendAllBroadcast("1234567890", "hello", "How are you?");
  12. //给在线人发信息,参数同上
  13. sn.sendBroadcast("1234567890", "Hi", "OK");
  14. //给指定人发信息,  第一、三、四个<strong>消息</strong>的意义同上,第二个参数"4ed224a3fa8c4560a27e313ab24f597d"是用户名,可以在<strong>服务器</strong>端页面看到。
  15. //  sn.sendNotifications("1234567890","4ed224a3fa8c4560a27e313ab24f597d", "Hello Hi", "Hello World! How are you?");
  16. }
  17. }

然后运行程序,可看到模拟器中接收到了推送主题为:Hi,内容为:OK的 消息 。

测试最后一个给指定用户发送消息的方法:

查看文本打印?
  1. package org.main;
  2. import org.yl.SendNotification;
  3. public class CallMain {
  4. /**
  5. * @param args
  6. */
  7. public static void main(String[] args) {
  8. // TODO Auto-generated method stub
  9. SendNotification sn = new SendNotification();
  10. //给所有人发信息,这里第一个参数"1234567890"是androidpn中的apikey,在androidpn中是写死了的,第二个参数为<strong>消息</strong>标题(title),第三个参数为<strong>消息</strong>内容(message)
  11. //sn.sendAllBroadcast("1234567890", "hello", "How are you?");
  12. //给在线人发信息,参数同上
  13. //sn.sendBroadcast("1234567890", "Hi", "OK");
  14. //给指定人发信息,  第一、三、四个<strong>消息</strong>的意义同上,第二个参数"f6ac2608faa94a65b5c2d94b72e968b0"是用户名,可以在<strong>服务器</strong>端页面看到。
  15. sn.sendNotifications("1234567890","f6ac2608faa94a65b5c2d94b72e968b0", "Hello Hi", "Hello World! How are you?");
  16. }
  17. }

其中第二个参数是从 服务器 端页面得来的:

运行程序得:

到此为止我们完成了根据某一事件触发,服务器可以主动向android手机端推送消息的这一需求。

另外为了使用上的方便,可以将上面PushClient工程中除了包含main函数的类之外的代码都统统打包成androidpn.jar文件。这样当其他的应用程序需要调用相应的方法发送信息时,只需要将此androidpn.jar文件加入到相应的工程中就可以调用其中的方法了。操作如下:

首先新建一个工程PushClient2,将PushClient工程中除了包含main函数的类外的其他文件文件拷贝到PushClient2工程中,

然后file-->Export-->Java-->JAR file-->选定输出路径和文件名-->finish即可。这里我取得文件名为androidp:

然后我们新建一个空的Java Project:PushClient3,并将androidp.jar引入此工程,主函数与PushClient中的主函数相同,

然后运行此工程可得到与工程PushClient相同的效果。

总结服务器端向android手机端推送消息实现逻辑是:当我们需要向用户推送消息时,就将消息发给AndroidPn的服务器端,由AndroidPn服务器端来替我们将消息发送给用户。那么怎么将我们要推送的信息发给AndroidPn服务器端呢?我们可以采用WebService技术,将AndroidPn服务器端发送消息的方法暴露出来,然后我们就可以在本地或远程来调用AndroidPn暴露出来的方法了。所以我们的系统要想正常运行,Androidpn服务器端必须事先开启。因为Androidpn服务器端是一个Web应用程序,可以将其经过Web Service技术处理后部署到tomcat上,以后我们只需要启动tomcat,Androidpn服务器端就会自动启动起来。

做法是:在eclipse中选中经过WebService处理后的AndroidPN服务器端,然后file-->Export-->Web-->WAR file-->将其导入到tomcat的webapps目录中。

以后只需要执行apache-tomcat-7.0.32\bin\startup.bat,启动tomcat,Androidpn服务器端也就随即启动了,不需要在eclipse中启动了。

转自:http://www.verydemo.com/demo_c131_i166053.html

服务器主动向android手机端推送消息相关推荐

  1. 服务器端往手机端推送数据的问题(手机解决方案)

    1.方案一: 思路:使用socket连接,在手机端开个socketserver,然后服务器端连接手机端,实现服务器端的不定时发送数据. MIDlet关闭时, 你可以通过sms激活它. midlet运行 ...

  2. 手机端推送实现原理解析

    android系统的推送和iOS的推送有什么区别: 首先我们必须知道,所有的推送功能必须有一个客户端和服务器的长连接,因为推送是由服务器主动向客户端发送消息,如果客户端和服务器之间不存在一个长连接那么 ...

  3. 极光推送:java后台向APP推送消息(android,ios极光推送消息)

    Maven添加依赖 <!--极光推送--><dependency><groupId>cn.jpush.api</groupId><artifact ...

  4. 极光推送:后台向APP:android,ios极光推送消息

    1. 添加依赖 //jpushcompile group: 'cn.jpush.api', name: 'jpush-client', version: '3.3.4' 2. 注册极光用户 //APP ...

  5. win10消息推送服务器,win10怎么对更新的推送消息进行设定

    正常来说,我们在给电脑下载安装完新的win 10系统之后,一般是没有问题的,通常是在收到系统更新的推送之后再进行更新就行,但是好多小伙伴说自己从来没有收到过win 10的更新推送通知,下面白豆芽就和大 ...

  6. 如何实现服务器给android客户端主动推送消息

    一.消息推送基础 消息推送,就是在互联网上通过定期传送用户需要的信息来减少信息过载的一项新技术.推送技术通过自动传送信息给用户,来减少用于网络上搜索的时间.它根据用户的兴趣来搜索.过滤信息,并将其定期 ...

  7. Android Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示

    在Android Notification状态栏通知一文中,简单实现了消息的推送效果,这里就接着上文说一下,当用户接受到消息时的提示效果 // 5-加入震动及声音及亮屏 notification.de ...

  8. 服务器主动推送消息数据给客户端

    1 引言 这个问题第一次是我在实现一个导师的方案的时候所发现的,一开始我需要实现服务器与客户端的密钥协商和数据传递,服务器需要主动分发(推送)密钥给客户端,因为以前没有做过相关编码,后来只能想到用反向 ...

  9. Android 推送消息开放接口 OpenPush

    Android 推送消息开放接口 OpenPush 我们知道, 在中国不能使用 google 的服务. 在中国销售的手机甚至没有安装 google 的服务.所以, 原本由 google gcm 提供的 ...

  10. python自动推送消息_使用Python制作自动推送微信消息提醒的备忘录功能

    日常工作生活中,事情一多,就会忘记一些该做未做的事情.即使有时候把事情记录在了小本本上或者手机.电脑端备忘录上,也总会有查看不及时,导致错过的尴尬.如果有一款小工具,可以及时提醒,而不用再主动去查备忘 ...

最新文章

  1. Delta3D———通过游戏管理器组件和消息的扩展创建自定义行为 《转》
  2. TPP多租户隔离之资源清理
  3. C语言登顶!|2021年7月编程语言排行榜
  4. 大数据思维是企业互联网化的思维内核
  5. ubuntu server自动关闭屏幕背景灯_certbot-auto申请https证书,自动续期
  6. centos php编译,深入讲解CentOS PHP安装编译
  7. 【Oracle】三种方式查看SQL语句的执行计划
  8. Flume+kafka 整合
  9. linux project 软件下载,项目计划管理画甘特图工具Ganttproject安装(for linux)
  10. 教你炒股票21:缠中说禅买卖点分析的完备性
  11. 【ffmpeg】音频采集
  12. 解决:另一个 SqlParameterCollection 中已包含 SqlParameter。
  13. 建模专题1:石墨烯-氧化石墨烯及各种纳米材料体系的构建方法
  14. 一种简单的图像白平衡计算方法
  15. 移动开发技术【安卓】——Android_Studio【Part 1】
  16. mysql中null值求和_sql求和涉及到null值
  17. 书籍折页是什么效果_问题:WPS里页面设置中的拼页,书籍折页,反向书籍折页分别是什么意思?打印出来的效果是什么样的? 要双面打印...
  18. NOJ 水獭看动漫 2001
  19. 记录一次利用python调用chrome爬取天眼查网址工商信息的过程
  20. JMP的脚本JSL基础操作

热门文章

  1. mysql根据身份证号计算年龄
  2. 用简单的Python HTTP server来共享文件
  3. 克隆硬盘后进不去系统_硬盘克隆后重启找不到操作系统所在分区问题解决
  4. c语言地址符作用,理解C语言取地址符
  5. Leetcode第904题
  6. SQL分组排序和排序函数(rank、dense_rank、row_number)
  7. 可调直流稳压电源的工作原理以及常见问题
  8. 又拍云推出区块链开发平台,覆盖多个公链
  9. 【Multisim仿真】用555定时器+CD4017实现流水灯
  10. 又一名程序员猝死,送给996的程序员一份身体健康指南电子书!