Rapi

本页内容
引言
SMARTPHONE SDK API 库
管理设备中的目录文件
取系统信息
远程操作电话和短信功能

    Windows Mobile日益成熟,开发者队伍也越来越壮大。作为一个10年的计算机热爱者和程序员,我也经受不住新技术的诱惑,倒腾起Mobile这个玩具。Mobile和Windows的血缘关系决定了它在Windows程序员中的受欢迎程度,在网络上随便搜索一下,关于Mobile应用、开发的文章数不胜数。可是对于计划开发一款全能的Desktop<=>Device同步管理程序的我来说,却发现资源少得可怜——仅仅在MSDN和两个国外的Developer网站上发现了一点资料。现在我仍然在搜索学习中,在这里把我迄今掌握的一点心得写出来,希望能起到抛砖引玉的功效。另请各位高手指正。

    Mobile的开发资源很繁杂,很多人常常弄不清究竟要安装哪些工具才能搭建出合适的开发环境。但是我相信Microsoft SMARTPHONE 2003 SDK和Microsoft POCKETPC 2003 SDK是所有的人都知道的,它们分别为SmartPhone和PocketPC提供了必不可少的支持。兄弟我至今没有做出什么成绩,囊中羞涩,好容易攒了台SmartPhone,今天就已Microsoft SMARTPHONE 2003 SDK为例吧。

    SMARTPHONE SDK包含了大量的API,列表如下(选自SDK文档,本人翻译):

Smartphone APIDescription
ActiveSync创建移动应用程序安装和配置,同步服务模块,过滤器和协助访问ActiveSync服务的应用。
Bluetooth API创建支持蓝牙设备的Mobile应用程序,比如耳机,打印机和其他移动设备。
CE Messaging (CEMAPI)创建messaging applications
Configuration Service Providers创建可配置各种CSPs(Configuration Service Providers)的应用
Connection Manager创建可自动管理移动设备网络连接的应用
Control API在你的移动应用程序中使用Smartphone控件
Device Management API创建可远程访问移动设备配置管理的应用程序
Game API (GAPI)创建高性能的实时游戏
Home Screen API创建用户界面插件
HTML Control创建可显示HTML文本和嵌入图片,解析XML和绑定URL到别名的应用程序
MIDI创建可播放MIDI文件的应用程序
Object Exchange (OBEX)创建对象交换应用,允许移动设备自由的通过无线交换数据
Pocket Outlook Object Model (POOM) API创建可操作收件箱部件(联系人,日历和任务)的移动应用程序
Projects Control创建可以和Projects Control交互的应用
Remote API (RAPI)创建可以同步或控制移动设备的桌面应用程序
Speech Recognizer为应用程序增加语音识别功能(比如语音拨号)
Telephony创建支持电话和短信的应用程序
User Interface管理输入面板,增加用户界面元素到你的移动应用程序
Vibrate API为你的移动应用程序增加震动特性
Voice Recorder Control创建移动数字录音程序
Windows User Interface Controls创建将移动扩展合并到标准Microsoft® Windows® CE用户界面控件的应用

    要创建Desktop<=>Device的桌面同步管理程序,主要就依靠SDK API中的Remote API(RAPI)。RAPI 库由一组函数组成,这些函数可用于通过桌面应用程序管理设备,包括设备的目录文件、设备的注册表和系统信息。废话不多说,我们先来看看如何管理设备中的目录文件

    RAPI提供了一组文件管理的方法(不完全列表,详见SDK文档。选自SDK文档,本人翻译):

FunctionDescription
CeCopyFile复制文件
CeCreateDirectory创建目录
CeCreateFile创建,打开文件、管道、通讯资源、磁盘设备或者控制台。返回一个句柄用来访问对象。
CeDeleteFile删除文件
CeFindAllFiles从指定的Windows CE目录中获取所有文件和目录的信息,并且复制到一个包含CE_FIND_DATA结构的数组中
CeFindFirstFile在目录中查找匹配给定文件名的一个文件
CeFindClose关闭指定的查找句柄,CeFindFirstFileCeFindNextFile 函数用这个句柄查找文件
CeFindNextFile从上一次访问的CeFindFirstFile继续查找文件
CeGetFileAttributes返回指定文件或目录的属性
CeGetFileSize获取指定文件的字节大小
CeGetFileTime获取文件创建日期时间,最后访问日期时间和最后修改日期时间
CeMoveFile移动(重命名)一个文件或者目录
CeReadFile从文件指针处读取文件数据
CeWriteFile从文件指针处写入文件数据

    首先要说明的是,任何RAPI操作都需要首先初始化与设备的连接:

FunctionDescription
CeRapiInit (RAPI)创建Windows CE remote application-programming interface (RAPI).
[C#.NET]
 
using System;using System.Runtime.InteropServices;
public class RAPI{	public void RapiInit() 	{		int ret = CeRapiInit();		if( ret != 0)		{			// 连接失败,获取失败代码			int e = CeRapiGetError();			// 抛出异常			Marshal.ThrowExceptionForHR(ret);		}		// 连接成功		// To Do	}	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeRapiGetError();	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeRapiInit();}
 

    连接建立后,就可以进行文件操作了。看一个将文件复制到设备的例子:

[C#.NET]
using System;using System.Runtime.InteropServices;using System.IO;
public class RAPI{	private const uint GENERIC_WRITE = 0x40000000; 	// 设置读写权限	private const short CREATE_NEW = 1; 			// 创建新文件	private const short FILE_ATTRIBUTE_NORMAL = 0x80; 	// 设置文件属性	private const short INVALID_HANDLE_VALUE = -1; 	// 错误句柄	IntPtr remoteFile = IntPtr.Zero;	String LocalFileName = @"c:/test.txt"; 		// 本地计算机文件名	String RemoteFileName = @"/My Documents/test.txt"; 	// 远程设备文件名	byte[] buffer = new byte[0x1000]; 			// 传输缓冲区定义为4k	FileStream localFile;	int bytesread = 0;	int byteswritten = 0;	int filepos = 0;	public RapiFile() 	{		// 创建远程文件		remoteFile = CeCreateFile(RemoteFileName, GENERIC_WRITE, 0, 0, CREATE_NEW, 				FILE_ATTRIBUTE_NORMAL, 0);		// 检查文件是否创建成功		if ((int)remoteFile == INVALID_HANDLE_VALUE)		{			throw new Exception("Could not create remote file");		}		// 打开本地文件		localFile = new FileStream(LocalFileName, FileMode.Open);		// 读取4K字节		bytesread = localFile.Read(buffer, filepos, buffer.Length);		while(bytesread > 0)		{			// 移动文件指针到已读取的位置			filepos += bytesread;			// 写缓冲区数据到远程设备文件			if(! Convert.ToBoolean(CeWriteFile(remoteFile, buffer, bytesread, 				ref byteswritten, 0)))			{ // 检查是否成功,不成功关闭文件句柄,抛出异常				CeCloseHandle(remoteFile);				throw new Exception("Could not write to remote file");			}			try			{				// 重新填充本地缓冲区				bytesread = localFile.Read(buffer, 0, buffer.Length);			}			catch(Exception)			{				bytesread = 0;			}		}		// 关闭本地文件		localFile.Close();		// 关闭远程文件		CeCloseHandle(remoteFile);	}
	// 声明要引用的API	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeCloseHandle(IntPtr hObject); 	[DllImport("rapi.dll", CharSet=CharSet.Unicode)]	internal static extern int CeWriteFile(IntPtr hFile, byte[] lpBuffer, 		int nNumberOfbytesToWrite, ref int lpNumberOfbytesWritten, int lpOverlapped);	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern IntPtr CeCreateFile(		string lpFileName, 		uint dwDesiredAccess,		int dwShareMode,		int lpSecurityAttributes,		int dwCreationDisposition,		int dwFlagsAndAttributes,		int hTemplateFile);}
 

    操作完毕后在合适的时候需要断开RAPI连接,使用如下函数(选自SDK文档,本人翻译):

FunctionDescription
CeRapiUninit (RAPI)销毁Windows CE remote application-programming interface (RAPI).
[C#.NET]
using System;using System.Runtime.InteropServices;public class RAPIUninit
{ public RAPIUninit() { CeRapiUninit(); } // 声明要引用的API [DllImport("rapi.dll", CharSet=CharSet.Unicode)] internal static extern int CeRapiUninit();}
 

    文件操作的函数有很多,基本思路都是一样的,在这里就不一一举例了。请注意文件句柄使用以后一定要释放。

    我们再看一个取系统信息的例子,RAPI提供了一些取系统信息的函数(选自SDK文档,本人翻译):

FunctionDescription
CeGetSystemInfo返回当前系统信息
CeGetSystemMetrics获取Windows元素的尺寸和系统设置
CeGetVersionEx获取当前运行的操作系统版本的扩展信息
CeGetSystemPowerStatusEx获取电池状态
CeGlobalMemoryStatus获取系统物理内存和虚拟内存信息
CeGetStoreInformation获取存储器信息并填入STORE_INFORMATION结构
[C#.net]
public class RAPI{	SYSTEM_INFO si;			// 系统信息	OSVERSIONINFO versionInfo;		// 版本信息	SYSTEM_POWER_STATUS_EX PowerStatus;	// 电源信息	MEMORYSTATUS ms;			// 内存信息	String info;	public void systemInfo()	{		// 检索系统信息		try		{			CeGetSystemInfo(out si);		}		catch(Exception)		{			throw new Exception("Error retrieving system info.");		}		// 检索设备操作系统版本号。		bool b;		versionInfo.dwOSVersionInfoSize = Marshal.SizeOf(typeof(OSVERSIONINFO));	// 设置为结构大小				b = CeGetVersionEx(out versionInfo);		if(!b)		{			throw new Exception("Error retrieving version information.");		}		// 检索设备电源状态		try		{			CeGetSystemPowerStatusEx(out PowerStatus, true); // true 表示读取最新的电源信息,否则将从缓存中获得		}		catch(Exception)		{			throw new Exception("Error retrieving system power status.");		}		// 检索设备内存状态		CeGlobalMemoryStatus( out ms );		// 设置检索信息的格式。		info = "The connected device has an ";		switch (si.wProcessorArchitecture)		{			case ProcessorArchitecture.Intel:				info += "Intel processor./n";				break;			case ProcessorArchitecture.MIPS:				info += "MIPS processor./n";				break;			case ProcessorArchitecture.ARM:				info += "ARM processor./n";				break;			default:				info = "unknown processor type./n";				break;		}		info += "OS version: " + versionInfo.dwMajorVersion + "." + versionInfo.dwMinorVersion + "." +			versionInfo.dwBuildNumber + "/n";		if (PowerStatus.ACLineStatus == 1)		{			info += "On AC power:YES/n";		}		else		{			info += "On AC power:NO /n";		}		info += "Battery level: " + PowerStatus.BatteryLifePercent + "%/n";		info += "Total memory: " + String.Format("{0:###,###,###}",  ms.dwTotalPhys) +			"/n";		// 显示结果。		Console.WriteLine(info);	}	#region 声明API,详见SDK文档	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern int CeGetSystemInfo(out SYSTEM_INFO pSI);	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern bool CeGetVersionEx(out OSVERSIONINFO lpVersionInformation);	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern bool CeGetSystemPowerStatusEx(out SYSTEM_POWER_STATUS_EX pStatus, bool fUpdate);	[DllImport("rapi.dll", CharSet=CharSet.Unicode, SetLastError=true)]	internal static extern void CeGlobalMemoryStatus(out MEMORYSTATUS msce);	#endregion	#region 声明结构	///			/// 处理器架构 (CeGetSystemInfo)	///	public enum ProcessorArchitecture : short	{		///		/// Intel		///		Intel		= 0,		/// 		/// MIPS		/// 				MIPS		= 1,		///		/// Alpha		///		Alpha		= 2,		///				/// PowerPC		/// 		PPC		= 3,		///		/// Hitachi SHx		///		SHX		= 4,		///		/// ARM		///		ARM		= 5,		///		/// IA64		///		IA64		= 6,		/// 		/// Alpha 64		///		Alpha64		= 7,		///		/// Unknown		///		Unknown 		= -1	}	/// 	/// 移动设备内存信息	///	[StructLayout(LayoutKind.Sequential)]	public struct MEMORYSTATUS	{		internal uint dwLength;		///		/// 当前内存占用 (%)		///		public int dwMemoryLoad;		///		/// 物理内存总量		/// 		public int dwTotalPhys;		///		/// 可用物理内存		///		public int dwAvailPhys;		/// 		/// 分页数		///		public int dwTotalPageFile;		///		/// 未分页		/// 		public int dwAvailPageFile;		///		/// 虚拟内存总量		/// 		public int dwTotalVirtual;		/// 		/// 可用虚拟内存		///		public int dwAvailVirtual;	}	/// 	/// 移动设备电源信息	/// 	public struct SYSTEM_POWER_STATUS_EX	{		///		/// 交流电状态		/// 		public byte ACLineStatus;		///		/// 电池充电状态。1 High,2 Low,4 Critical,8 Charging,128 No system battery,255 Unknown status		///		public byte BatteryFlag;		///		/// 电池电量剩余百分比		///		public byte BatteryLifePercent;		/// 		/// 保留字段,设置为0		/// 		internal byte Reserved1;		/// 				/// 电池电量剩余时间(秒)		///		public int BatteryLifeTime;		///		/// 电池充满电的总可用时间(秒)		///		public int BatteryFullLifeTime;		///		/// 保留字段,设置为0		///		internal byte Reserved2;		/// 		/// 后备电池状态		///		public byte BackupBatteryFlag;		///		/// 后备电池剩余电量百分比		///		public byte BackupBatteryLifePercent;		///		/// 保留字段,设置为0		///		internal byte Reserved3;		///				/// 后备电池电量剩余时间(秒)		///		public int BackupBatteryLifeTime;		/// 		/// 后备电池充满电的总可用时间(秒)		///		public int BackupBatteryFullLifeTime;	}	/// 	/// OSVERSIONINFO platform type	/// 	public enum PlatformType : int	{		///		/// Win32 on Windows CE.		/// 		VER_PLATFORM_WIN32_CE	= 3	}	///	/// 操作系统版本信息	/// 	public struct OSVERSIONINFO	{		internal int dwOSVersionInfoSize;		///		/// 主版本信息		/// 		public int dwMajorVersion;		/// 		/// 副版本信息		/// 		public int dwMinorVersion;		/// 		/// 编译信息		/// 		public int dwBuildNumber;		///		/// 操作系统类型		/// 		public PlatformType dwPlatformId;	}	/// 	/// 处理器类型 (CeGetSystemInfo)	/// 		public enum ProcessorType : int	{		/// 		/// 386		/// 		PROCESSOR_INTEL_386	= 386,		/// 		/// 486		/// 		PROCESSOR_INTEL_486	= 486,		/// 		/// Pentium		/// 		PROCESSOR_INTEL_PENTIUM	= 586,		/// 		/// P2		/// 		PROCESSOR_INTEL_PENTIUMII	= 686,		/// 		/// IA 64		/// 		PROCESSOR_INTEL_IA64	= 2200,		/// 		/// MIPS 4000 series		/// 		PROCESSOR_MIPS_R4000        	= 4000,		/// 		/// Alpha 21064		/// 		PROCESSOR_ALPHA_21064      	 = 21064,		/// 		/// PowerPC 403		/// 		PROCESSOR_PPC_403           	= 403,		/// 		/// PowerPC 601		/// 		PROCESSOR_PPC_601          	 = 601,		/// 		/// PowerPC 603		/// 		PROCESSOR_PPC_603          	 = 603,		/// 		/// PowerPC 604		/// 		PROCESSOR_PPC_604           	= 604,		/// 		/// PowerPC 620		/// 		PROCESSOR_PPC_620          	 = 620,		/// 		/// Hitachi SH3		///		PROCESSOR_HITACHI_SH3       	= 10003,		/// 		/// Hitachi SH3E		/// 		PROCESSOR_HITACHI_SH3E     	 = 10004,		///		/// Hitachi SH4		/// 		PROCESSOR_HITACHI_SH4       	= 10005,		/// 		/// Motorola 821		/// 		PROCESSOR_MOTOROLA_821      = 821,		/// 		/// Hitachi SH3		/// 		PROCESSOR_SHx_SH3           	= 103,		/// 		/// Hitachi SH4		/// 		PROCESSOR_SHx_SH4           	= 104,		/// 		/// Intel StrongARM		/// 		PROCESSOR_STRONGARM         	= 2577,		/// 		/// ARM720		/// 		PROCESSOR_ARM720            	= 1824,		/// 		/// ARM820		/// 		PROCESSOR_ARM820            	= 2080,		/// 		/// ARM920		/// 		PROCESSOR_ARM920           	 = 2336,		/// 		/// ARM 7		/// 		PROCESSOR_ARM_7TDMI        	 = 70001	}	/// 	/// CeGetSystemInfo的数据结构	/// 	public struct SYSTEM_INFO	{		/// 		/// 处理器架构		/// 		public ProcessorArchitecture wProcessorArchitecture;		/// 		/// 保留		/// 		internal ushort wReserved;		/// 		/// Specifies the page size and the granularity of page protection and commitment.		/// 		public int dwPageSize;		/// 		/// 应用程序可访问内存地址的最小值		///(Pointer to the lowest memory address accessible to applications		/// and dynamic-link libraries (DLLs). )		/// 				public int lpMinimumApplicationAddress;		/// 		/// 应用程序可访问内存地址的最大值(Pointer to the highest memory address		/// accessible to applications and DLLs.)		/// 				public int lpMaximumApplicationAddress;		/// 		/// Specifies a mask representing the set of processors configured into		/// the system. Bit 0 is processor 0; bit 31 is processor 31.		/// 		public int dwActiveProcessorMask;		/// 		/// 处理器数量(Specifies the number of processors in the system.)		/// 		public int dwNumberOfProcessors;		/// 		/// 处理器类型(Specifies the type of processor in the system.)		/// 		public ProcessorType dwProcessorType;		/// 		/// Specifies the granularity with which virtual memory is allocated.		/// 		public int dwAllocationGranularity;		/// 		/// Specifies the system architecture-dependent processor level.		/// 		public short wProcessorLevel;		/// 		/// Specifies an architecture-dependent processor revision.		/// 		public short wProcessorRevision;	}	#endregion}
 

    RAPI可以做的事情还有很多,比如取注册表信息,提供对 Microsoft ActiveSync 底层功能的访问,运行远程应用程序,文件列表等等。只要仔细阅读SDK文档,相信都不是难事。

    作为Mobile设备的桌面管理程序,备份通话记录,联机发送短信等功能是必不可少的。在我刚发现RAPI的时候,以为和前面的例子一样,有现成的函数可以使用。仔细研究以后才发现要复杂的多。相信这是很多朋友的希望实现的功能,所以班门弄斧,简述如下。

    RAPI并没有提供通话,SIM卡和短信方面的函数,它们分别包含在SmartPhone SDK的Phone API,SIM Manager和Short Message Service中。然而包含这些API的phone.dll,cellcore.dll和sms.dll都是储存在设备上的,在Windows上运行的程序是无法调用存储在远程设备上的动态连接库的。

    我们仍然需要RAPI。虽然它没有提供直接访问通话记录和短信方面的操作,但是它提供了一个特殊的函数:

FunctionDescription
CeRapiInvoke使用一种通用的机制执行远程程序

    CeRapiInvoke的原型如下:

STDAPI_( HRESULT ) CeRapiInvoke(
    LPCWSTR pDllPath,                      // 包含API的Dll文件完整路径
    LPCWSTR pFunctionName,         // 要调用的函数名
    DWORD cbInput,                           // 函数输入缓冲区大小
    BYTE * pInput,                               // 函数输入缓冲区指针
    DWORD * pcbOutput,                  // 函数输出缓冲区大小
    BYTE ** ppOutput,                       // 函数输出缓冲区指针
    IRAPIStream ** ppIRAPIStream,  // 指定使用阻塞模式或流模式
    DWORD dwReserved);                // 保留

    CeRapiInvoke将允许我们调用远程设备中的任何API函数!不过不是直接调用,仍然需要对远程API进行一些“包装”。由于时间关系,我将在不久的将来为大家献上关于CeRapiInvoke的详细说明。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 字符串特殊字符转义

XML转义字符 以下为XML标志符的数字和字符串转义符 " ( 或 &quot;) ( 或 &apos;) & ( 或 &amp;) lt(<) (< 或 <) gt(>) (> 或 >) 如题&#xff1a; 比如&#xff1a;在string.xml中定义如下一个字符串&#xff0c;…

如何描绘一个vue的项目_描绘了一个被忽视的幽默来源

如何描绘一个vue的项目Source)来源 ) Data visualization is a great way to celebrate our favorite pieces of art as well as reveal connections and ideas that were previously invisible. More importantly, it’s a fun way to connect things we love — visualizing …

数据存储加密和传输加密_将时间存储网络应用于加密预测

数据存储加密和传输加密I’m not going to string you along until the end, dear reader, and say “Didn’t achieve anything groundbreaking but thanks for reading ;)”.亲爱的读者&#xff0c;我不会一直待到最后&#xff0c;然后说&#xff1a; “没有取得任何开创性的…

熊猫分发_熊猫新手:第一部分

熊猫分发For those just starting out in data science, the Python programming language is a pre-requisite to learning data science so if you aren’t familiar with Python go make yourself familiar and then come back here to start on Pandas.对于刚接触数据科学的…

多线程 进度条 C# .net

前言  在我们应用程序开发过程中&#xff0c;经常会遇到一些问题&#xff0c;需要使用多线程技术来加以解决。本文就是通过几个示例程序给大家讲解一下多线程相关的一些主要问题。 执行长任务操作  许多种类的应用程序都需要长时间操作&#xff0c;比如&#xff1a;执行一…

window 10 多版本激活工具

window 10 通用版激活工具 云盘地址&#xff1a;https://pan.baidu.com/s/1bo3L4Kn 激活工具网站&#xff1a;http://www.tudoupe.com/win10/win10jihuo/2017/0516/6823.html 转载于:https://www.cnblogs.com/ipyanthony/p/9288007.html

android 动画总结笔记 一

终于有时间可以详细去了解一下 android动画&#xff0c;先从android动画基础着手。在android 3.0之前android动画api主要是android.view.Animation包下的内容&#xff0c;来先看看这个包里面主要的类![Animation成员](https://img-blog.csdn.net/20150709115201928 "Anima…

《Linux内核原理与分析》第六周作业

课本&#xff1a;第五章 系统调用的三层机制&#xff08;下&#xff09; 中断向量0x80和system_call中断服务程序入口的关系 0x80对应着system_call中断服务程序入口&#xff0c;在start_kernel函数中调用了trap_init函数&#xff0c;trap_init函数中调用了set_system_trap_gat…

使用C#调用外部Ping命令获取网络连接情况

使用C#调用外部Ping命令获取网络连接情况 以前在玩Windows 98的时候&#xff0c;几台电脑连起来&#xff0c;需要测试网络连接是否正常&#xff0c;经常用的一个命令就是Ping.exe。感觉相当实用。 现在 .net为我们提供了强大的功能来调用外部工具&#xff0c;并通过重定向输…

Codeforces Round 493

心情不好&#xff0c;被遣散回学校 &#xff0c;心态不好 &#xff0c;为什么会累&#xff0c;一直微笑就好了 #include<bits/stdc.h> using namespace std; int main() {freopen("in","r",stdin);\freopen("out","w",stdout);i…

android动画笔记二

从android3.0&#xff0c;系统提供了一个新的动画&#xff0d;property animation, 为什么系统会提供这样一个全新的动画包呢&#xff0c;先来看看之前的补间动画都有什么缺陷吧1、传统的补间动画都是固定的编码&#xff0c;功能是固定的&#xff0c;扩展难度大。比如传统动画只…

回归分析检验_回归分析

回归分析检验Regression analysis is a reliable method in statistics to determine whether a certain variable is influenced by certain other(s). The great thing about regression is also that there could be multiple variables influencing the variable of intere…

是什么样的骚操作让应用上线节省90%的时间

优秀的程序员 总会想着 如何把花30分钟才能解决的问题 在5分钟内就解决完 例如在应用上线这件事上 通常的做法是 构建项目在本地用maven打包 每次需要clean一次&#xff0c;再build一次 部署包在本地ide、git/svn、maven/gradie 及代码仓库、镜像仓库和云平台间 来回切换 上传部…

QQ API

QQ API设计说明书目录一、引言 31.1 编写目的 31.2 更新时间 3二、总体设计 3三、注册的系统消息 33.1 WM_QQAPI_REGISTER 33.2 WM_QQAPI_REGISTER_RESP 43.3 WM_QQAPI_AVAILABLE 4四、从设备到QQ的自定义事件 54.1 EVENT_QQAPI_SET_AUDIODEVICE …

Ubuntu 18.04 下如何配置mysql 及 配置远程连接

首先是大家都知道的老三套&#xff0c;啥也不说上来就放三个大招&#xff1a; sudo apt-get install mysql-serversudo apt isntall mysql-clientsudo apt install libmysqlclient-dev 这三步下来mysql就装好了&#xff0c;然后我们偷偷检查一下 sudo netstat -tap | grep mysq…

数据科学与大数据技术的案例_主数据科学案例研究,招聘经理的观点

数据科学与大数据技术的案例I’ve been in that situation where I got a bunch of data science case studies from different companies and I had to figure out what the problem was, what to do to solve it and what to focus on. Conversely, I’ve also designed case…

导致View树遍历的时机

遍历View树意味着整个View需要重新对其包含的子视图分配大小并重绘&#xff0c;导致重新遍历的原因主要有三个 1.视图本身内部状况变化引起重绘。 2.第二个是View树内部添加或者删除了View。 3.View本身的大小及可见性发生变化。 能引起View树重新遍历的操作&#xff0c;总…

什么是Hyperledger?Linux如何围绕英特尔的区块链项目构建开放平台?

访问区块链会议并关注区块链新闻时&#xff0c;不可避免地&#xff0c;您会遇到Linux基金会的Hyperledger。理解像比特币、以太坊这样的加密货币还算相对容易的&#xff0c;Hyperledger却不然。但如果你多研究研究&#xff0c;你会发现一些令人兴奋的非货币、工业区块链的应用项…

队列的链式存储结构及其实现_了解队列数据结构及其实现

队列的链式存储结构及其实现A queue is a collection of items whereby its operations work in a FIFO — First In First Out manner. The two primary operations associated with them are enqueue and dequeue.队列是项目的集合&#xff0c;由此其操作以FIFO(先进先出)的方…