android与c通信
① 请问下,android能不能直接通过手机IP进行socket通信,不是局域.
可以的,只要通信的IP是通的就行了。
有两种方案:
1、在PC机上建立服务器,手机与手机之间的通信通过服务器进行中转
2、一部手机作为服务器,另一部手机作为客户端接入该手机
一般是第一种方案
1、pc端:
serverSocket=new ServerSocket(5648); //在5648端口进行侦听
Socket sk = serverSocket.accept();//如果有接入,则创建对应的socket;
2、手机端:
socket=new Socket("tobacco5648.xicp.net",5648);//连接socket
3、消息输入输出:
pw=new PrintWriter(socket.getOutputStream()); //消息输出
pw.println("发送消息");
pw.flush();
br=new BufferedReader(new InputStreamReader(socket.getInputStream())); //消息接收
while((str=br.readLine())!=null){
//接收消息
}
② Android 进程间通信的几种实现方式
Android 进程间通信的几种实现方式
主要有4种方式:
这4种方式正好对应于android系统中4种应用程序组件:Activity、Content Provider、Broadcast和Service。
主要实现原理:
由于应用程序之间不能共享内存。为了在不同应用程序之间交互数据(跨进程通讯),AndroidSDK中提供了4种用于跨进程通讯的方式进行交互数据,实现进程间通信主要是使用sdk中提供的4组组件根据实际开发情况进行实现数据交互。
详细实现方式:
Acitivity实现方式
Activity的跨进程访问与进程内访问略有不同。虽然它们都需要Intent对象,但跨进程访问并不需要指定Context对象和Activity的 Class对象,而需要指定的是要访问的Activity所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过 Intent构造方法的第2个参数指定)。 在android系统中有很多应用程序提供了可以跨进程访问的Activity,例如,下面的代码可以直接调用拨打电话的Activity。
java">IntentcallIntent=newIntent(Intent.ACTION_CALL,Uri.parse("tel:12345678");
startActivity(callIntent);
Content Provider实现方式
Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)
应用程序可以利用Content Provider完成下面的工作
1. 查询数据
2. 修改数据
3. 添加数据
4. 删除数据
Broadcast 广播实现方式
广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。这就象电台进行广播一样,听众只能被动地收听,而不能主动与电台进行沟通。在应用程序中发送广播比较简单。只需要调用sendBroadcast方法即可。该方法需要一个Intent对象。通过Intent对象可以发送需要广播的数据。
Service实现方式
常用的使用方式之一:利用AIDL Service实现跨进程通信
这是我个人比较推崇的方式,因为它相比Broadcast而言,虽然实现上稍微麻烦了一点,但是它的优势就是不会像广播那样在手机中的广播较多时会有明显的时延,甚至有广播发送不成功的情况出现。
注意普通的Service并不能实现跨进程操作,实际上普通的Service和它所在的应用处于同一个进程中,而且它也不会专门开一条新的线程,因此如果在普通的Service中实现在耗时的任务,需要新开线程。
要实现跨进程通信,需要借助AIDL(Android Interface Definition Language)。Android中的跨进程服务其实是采用C/S的架构,因而AIDL的目的就是实现通信接口。
总结
跨进程通讯这个方面service方式的通讯远远复杂于其他几种通讯方式,实际开发中Activity、Content Provider、Broadcast和Service。4种经常用到,学习过程中要对没种实现方式有一定的了解。
③ 安卓支持c++么
当然支持,安卓(android)开发工具集里有个所谓的NDK就是用C/C++编程的,如果用android studio开发用NDK是比较方便的。
安卓(android)从诞生之日起就支持c/c++的编程,android代码本身,底层也全部是c/c++来编写,应用层用java,通过JNI(Java Native Interface)机制来和其它语言互相通信(互相调用),在android里主要是c/c++和java互相调用,很多java调用的库也是用c/c++来写的。
现在的android在应用层(app)也强化了对c/c++代码的支持,并提供了一整套把java代码和c/c++编译成的.so文件打包成apk,便于发布的功能,就是所谓的NDK(Native Development Kit), android studio对NDK功能做了原生的支持之所以android要越来越支持NDK,原因主要包括:
代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大
可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。比如视频,音频压缩,网络传输等功能
便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
④ android手机端程序与pc端c程序进行socket通信问题
这是说你的网络连接的相关的程序写在了主线程里面,在 android里面是不可以这样的因为主线程是ui线程这种耗时操作是不能写在主线程中,否则界面会出现卡顿,所以你应该把你的socket操作写在另外一个线程中 也就是 new thread(){ public void run()
{}}.start();
把你的socket操作写在run方法中
⑤ 如何实现android和服务器长连接
提出问题:这种功能必须涉及client(客户端)和server(服务器),所以到底client如何和server实现实时连接通讯?
分析问题:这种功能实际上就是数据同步,同时要考虑手机本身、电量、网络流量等等限制因素,所以通常在移动端上有一下两个解决方案:
1.一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器,称Polling(轮询);
2.还有一种是移动端和服务器建立长连接,使用XMPP长连接,称Push(推送)。(按照本人理解:客户端的实现时:
while(true) {
request(timeout);
request(timeout);
}
客户端发出一个“长”请求,如果服务器发送消息或者时间out了,客户端就断开这个请求,再建立一个长请求
)
从耗费的电量、流量和数据延迟性各方面来说,Push有明显的优势。但是使用Push的缺点是:
对于客户端:实现和维护相对成本高,在移动无线网络下维护长连接,相对有一些技术上的开发难度。
对于服务器:如何实现多核并发,cpu作业调度,数量庞大的长连接并发维护等技术,仍存在开发难点。
在讲述Push方案的原理前,我们先了解一下移动无线网络的特点。
移动无线网络的特点:
因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯
原理图如下:
GGSN(Gateway GPRS Support Node 网关GPRS支持结点)模块就实现了NAT功能。
因为大部分移动无线网络运营商都是为了减少网关的NAT映射表的负荷,所以如果发现链路中有一段时间没有数据通讯时,会删除其对应表,造成链路中断。(关于NAT的作用及其原理可以查看我的另一篇博文:关于使用UDP(TCP)跨局域网,NAT穿透的心得)
Push在Android平台上长连接的实现:
既然我们知道我们移动端要和Internet进行通信,必须通过运营商的网关,所以,为了不让NAT映射表失效,我们需要定时向Internet发送数据,因为只是为了不然NAT映射表失效,所以只需发送长度为0的数据即可。
这时候就要用到定时器,在android系统上,定时器通常有一下两种:
1.java.util.Timer
2.android.app.AlarmManager
分析:
Timer:可以按照计划或者时间周期来执行相关的任务。但是Timer需要用WakeLock来让CPU保持唤醒状态,才能保证任务的执行,这样子会消耗大量流量;当CPU处于休眠的时候,就不能唤醒执行任务,所以应用于移动端明显是不合适。
AlarmManager:AlarmManager类是属于android系统封装好来管理RTC模块的管理类。这里就涉及到RTC模块,要更好地了解两者的区别,就要明白两者真正的区别。
RTC(Real- Time Clock)实时闹钟在一个嵌入式系统中,通常采用RTC 来提供可靠的系统时间,包括时分秒和年月日等;而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32.768KHz 晶体和电阻电容等。(如果对这方面感兴趣,可以自己查阅相关资料,这里就说个大概)
好了,回来正题。所以,AlarmManager又称全局定时闹钟。这意味着,当我用使用AlarmManager来定时执行任务,CPU可以正常地休眠,只有在执行任务是,才唤醒CPU,这个过程是很短时间的。
下面简单来说明其使用:
1.类似于Timer功能:
//获得闹钟管理器
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
//设置任务执行计划
am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, 5*1000, sender);//从firstTime才开始执行,每隔5秒再执行
2.实现全局定时功能:
//获得闹钟管理器
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
//设置任务执行计划
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 5*1000, sender);//从firstTime才开始执行,每隔5秒再执行
总结:在android客户端使用Push推送时,应该使用AlarmManager来实现心跳功能,使其真正实现长连接。
在服务器端的实现:
在服务器端,可以使用很多语言来实现,如C/C++,java,Erlang等等,如我们国内比较好的极光推送(C开发),openfire(java开发)等等。
最近我看了极光推送的介绍和原理,下面我就说说他们是遇到什么难题,然后使用什么技术或者方案来解决呢。
当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。
假设一台服务器维护10万个长连接,当有1000万用户量时,需要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题。那就需要我们尽可能提高单台服务器接入用户的量,也就是业界已经讨论很久了的 C10K 问题。
C2000K
针对这个问题,他们专门成立了一个项目,命名为C2000K,顾名思义,他们的目标是单机维持200万个长连接。最终他们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接。
最后总结:
因为我最近用java在做一个PC、服务器、android的即时通讯系统(说白了就是模仿QQ,后面希望有不同的功能)。我的原则是用别人的原理,自己来实现,这样才更好深入了解一些框架。所以,估计难点是在通讯开发和服务器上的开发,必须深刻了解多消息循环、异步非阻塞的模型。之后我会发表关于这方面的实现。
在现在的android平台上,已经不是android单机的世界了(我不是说做单机游戏没有前途)。现在都是依靠发展蓬勃的互联网来支撑整个IT体系,所以,要成为一个android应用开发高手,必须朝着android、硬件、云服务这一体系来发展。