
正文
android开发框架搭建,android 框架搭建
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
如何开发Android应用框架
在Android开发中能够知道和使用一些好用的第三方支持,省去自己的很多时间,下面涉及到的多为经过历史兴衰与检验的,江山代有人才出一代更比一代强,有些已经被更新更好用的所取代,但也很多地方仍可圈可点不乏参考,有些依然经典,整理出来请君一参.欢迎大家的指正,补充与交流.
1、AndBase框架
项目地址:
1.andbase中包含了大量的开发常用手段。
如网络下载,多线程与线程池的管理,数据库ORM,图片缓存管理,图片文件下载上传,Http请求工具,常用工具类(字符串,日期,文件处理,图片处理工具类等),能够使您的应用在团队开发中减少冗余代码,很大的提高了代码的维护性与开发高效性,能很好的规避由于开发疏忽而导致常犯的错误。
2.andbase封装了大量的常用控件。
如list分页,下拉刷新,图片轮播,表格,多线程下载器,侧边栏,图片上传,轮子选择,图表,Tab滑动,日历选择器等。
3.强大的AbActivity,您没有理由不继承它。
继承它你能够获得一个简单强大可设置的操作栏,以及一系列的简单调用,如弹出框,提示框,进度框,副操作栏等。
4.提供效率较高图片缓存管理策略,使内存大幅度节省,利用率提高,效率提高。
程序中要管理大量的图片资源,andbase提供简单的方法,几步完成下载与显示,并支持缩放,裁剪,缓存功能。
5.封装了大量常见工具类。
包括日期,字符,文件,图片等各种处理函数, 多而全。
6.用andbase大量减少handler的使用,而采用回调函数,代码更整洁。
handler会产生大量代码,并且不好维护,andbase对handler进行了封装。
7.简单轻量支持注解自动建表的ORM框架(支持一/多对多的关联操作)。
写sql,建表,工作量大,andbase提供更傻瓜异步增删改查工具类。
8.异步请求http框架,网络请求标准化,支持文件上传下载,get,post,进度显示。
包含了异步与http请求的工具类,实用。
2、XUtil框架
项目地址:
主要有四大模块:
(1) 数据库模块:Android中的orm框架,一行代码就可以进行增删改查;
支持事务,默认关闭;
可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名);
支持绑定外键,保存实体时外键关联实体自动保存或更新;
自动加载外键关联实体,支持延时加载;
支持链式表达查询,更直观的查询语义,参考下面的介绍或sample中的例子。
(2) 注解模块:android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;
新的事件绑定方式,使用混淆工具混淆后仍可正常工作;
目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。
(3) 网络模块:支持同步,异步方式的请求;
支持大文件上传,上传大文件不会oom;
支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;
下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;
返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。
(4) 图片缓存模块:加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;
支持加载网络图片和本地图片;
内存管理使用lru算法,更好的管理bitmap内存;
可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等...
3、ThinkAndroid框架
项目地址:
主要有以下模块:
(1) MVC模块:实现视图与模型的分离。
(2) ioc模块:android中的ioc模块,完全注解方式就可以进行UI绑定、res中的资源的读取、以及对象的初始化。
(3) 数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。
(4) http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。
(5) 缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置
(6) 图片缓存模块:imageview加载图片的时候无需考虑图片加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。
(7) 配置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。
(8) 日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印
(9) 下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进行控制、如开始、暂停、删除等等。
(10) 网络状态检测模块:当网络状态改变时,对其进行检
4、LoonAndroid
项目地址:
主要有以下模块:
(1) 自动注入框架(只需要继承框架内的application既可)
(2) 图片加载框架(多重缓存,自动回收,最大限度保证内存的安全性)
(3) 网络请求模块(继承了基本上现在所有的http请求)
(4) eventbus(集成一个开源的框架)
(5) 验证框架(集成开源框架)
(6) json解析(支持解析成集合或者对象)
(7) 数据库(不知道是哪位写的 忘记了)
(8) 多线程断点下载(自动判断是否支持多线程,判断是否是重定向)
(9) 自动更新模块
(10) 一系列工具类
5、volley
项目地址 :
(1) JSON,图像等的异步下载;
(2) 网络请求的排序(scheduling)
(3) 网络请求的优先级处理
(4) 缓存
(5) 多级别取消请求
(6) 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)
6、android-async-http
项目地址:
文档介绍:
(1) 在匿名回调中处理请求结果
(2) 在UI线程外进行http请求
(3) 文件断点上传
(4) 智能重试
(5) 默认gzip压缩
(6) 支持解析成Json格式
(7) 可将Cookies持久化到SharedPreferences
7、Afinal框架
项目地址:
主要有四大模块:
(1) 数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。
(2) 注解模块:android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。
(3) 网络模块:通过httpclient进行封装http数据请求,支持ajax方式加载,支持下载、上传文件功能。
(4) 图片缓存模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。
FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。FinalBitmap的内存管理使用lru算法,
没有使用弱引用(android2.3以后google已经不建议使用弱引用,android2.3后强行回收软引用和弱引用,详情查看android官方文档),
更好的管理bitmap内存。FinalBitmap可以自定义下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器,
在imageview显示图片的时候播放动画等(默认是渐变动画显示)。
总结框架结构,
ImageLoader框架(第8大框架)
UniversalImageLoader是用于加载图片的一个开源项目,在其项目介绍中是这么写的,
支持多线程图片加载
提供丰富的细节配置,比如线程池大小,HTPP请求项,内存和磁盘缓存,图片显示时的参数配置等等;
提供双缓存
支持加载过程的监听;
提供图片的个性化显示配置接口;
Widget支持(这个,个人觉得没必要写进来,不过尊重原文)
其他类似的项目也有很多,但这个作为github上著名的开源项目被广泛使用。第三方的包虽然好用省力,可以有效避免重复造轮子,但是却隐藏了一些开发上的细节,如果不关注其内部实现,那么将不利于开发人员掌握核心技术,当然也谈不上更好的使用它,计划分析项目的集成使用和低层实现。
开源框架android-async-http(第9大框架)
官网:
Android-async-http开源框架可以是我们轻松的获取网络数据或者向服务器发送数据,使用起来也简单,详细请看官网:
到官网下载zip包,解压,里面有完整的代码和各种版本的jar包和demo,源码在library里面,jar包在releases里面。项目更新速度很快,老版本的回调是一个普通类,最新版是一个接口。
KJFrameForAndroid框架(第10大框架)
参考:
KJFrameForAndroid是一款基于Android的ORM和 IOC应用开发框架,封装了很多Android开发中常用的功能,包括Android中对Bitmap的操作类库。KJFrameForAndroid的设计非常精简,利用KJFrameForAndroid,我们可以用最少的代码完成很多丰富的Android功能应用,为Android开发者节省许多不必要的开发时间。
KJFrameForAndroid总共分为五大模块:UILibrary,UtilsLibrary,HttpLibrary,BitmapLibrary,DBLibrary。
Android-async-http开源框架可以是我们轻松的获取网络数据或者向服务器发送数据,使用起来也简单,详细请看官网:
到官网下载zip包,解压,里面有完整的代码和各种版本的jar包和demo,源码在library里面,jar包在releases里面。项目更新速度很快,老版本的回调是一个普通类,最新版是一个接口。
相关问答
Q1: Android搭建应用框架系列之BaseActivity
其实写 BaseActivity 的时候,都需要结合不同的 App 的需求以及应用架构来实现的,没有固定的实现方式。所以这里结合前面几篇文章来写一个 BaseActivity
结合前面的文章说的, BaseActivity 应该有下面这些内容
应用中往往少不了加载动画,所以 BaseActivity 也应该写一个公共的显示和隐藏加载框的方法,结合前文的 IProgressDialog 接口。由于 Android 的 ProgressDialog 注解过时, Google 不推荐使用,那么这里就通过 AlertDialog+ProgressBar 简单实现下面的效果
我们都知道 AlertDialog 是有一个底色背景的,所以这里先写一个 Style 让底色背景透明
接下来就是这个弹框的布局
然后就是创建 AlertDialog 设置布局
把前面的 Style 在创建 AlertDialog.Builder() 传入即可让底色背景透明,然后通过 AlertDialog 的 setView() 方法就可以自定义布局了。
定义一个 FragmentManager 方便操作 Fragment 的时候使用
对应 Rx1.x 版本的 CompositeSubscription ,将请求接口统一绑定起来
然后在 onDestroy() 进行统一的解绑
结合前文封装的 RealmHelper 帮助类,实现 Realm 的实例并且定义一个 RealmAsyncTask
然后在 onStop 里面进行清除
首先会在 BaseActivity 定义一个默认的布局 act_single_fragment.xml
其中 content 是用来放置内容的区域,然后 toolbar_layout.xml 是 ToolBar 的布局
提供一个方法供外部实现 ToolBar 样式,默认是 TitleFragment
TitleFragment 就是一个简单的头部样式,如图
最后处理返回键的回调方法
通过上面的说明,最终 BaseActivity 如下
Q2: 如何搭建Android快速开发框架
搭建Android开发环境
准备工作:下载Eclipse、JDK、Android SDK、ADT插件
下载地址:Eclipse:
JDK:
Android SDK:
ADT:
1、安装和配置JAVA开发环境:
①把准备好的Eclipse和JDK安装到本机上(最好安装在全英文路径下),并给JDK配置环境变量,其中JDK的变量值为JDK安装路径的根目录,如我的为:D:\Program Files\Java\jdk1.7.0_02;
②打开命令提示符(cmd),输入java -version命令,显示如下图则说明JAVA环境变量已经配置好了。
2、安装ADT插件:
①打开已安装好的Eclipse,选择菜单栏上的“Help”-在弹出的下拉框中单击选择“Install new software...”;
②在新打开的对话框中我们完全可以直接在"Work with"中输入:在线安装ADT插件,但由于Google的服务器搭建在国外,所以通过这种方式安装起来会比较慢,而且可能会出现人品差死活装不上的情况,所以不推荐在线安装。
③我推荐直接通过下载好的ADT插件压缩包进行安装(此种方式可以在离线环境下进行)。具体步骤是:在新打开的对话框中点击“Add”按钮-在打开的对话框中点击“Archive”按钮选择之前已经下载好保存在本地硬盘的ADT插件压缩包,至于上面的“Name”可以随便取,这只是一个代号而已,没什么实际作用。
④在上一步中点击“Ok”按钮后我们会发现中间的空白处出现了两行复选框,单击"Select All"按钮选中所有的复选框,这步过后一路“Next”,需要“Accept”的就选中“Accept”,直到点击“Finish”结束,这样ADT插件就安装好了。整个过程需要的时间视机器性能而定。安装好ADT插件后,Eclipse的工具栏会出现一排Android的图标,如下图:
3、安装SDK:
①把下载好的Android SDK安装到本机上(最好安装在全英文路径下),并为Android SDK配置环境变量。Android SDK的环境变量值为SDK安装目录下的platform-tools文件夹和tools文件夹子目录路径,如我的分别为:E:\My Studying\Android\android-sdk\platform-tools、E:\My Studying\Android\android-sdk\tools,在变量值中,两个路径用逗号隔开。
②打开命令提示符(cmd),分别输入android -h和adb命令,显示如下图则说明Android SDK环境变量已经配置好了。
③打开Android SDK的安装目录,双击 "SDK Manager"-在打开的窗口中先选择你需要安装的SDK版本,其中“Status”表示该SDK包是否安装,如我选的是“Android2.2(API 8)”(我的之前已经安装过了,所以“Status”为“Installed”)-再点击“Install packages...”按钮,在弹出来的窗口中最好选“Accept All”这样才能安装你刚才选的所有的包-最后点“Install”按钮就开始安装了,整个过程会很慢,这需要你的耐心。
另外我们还可以通过在Eclipse上的工具栏中点击下图指示的图标打开“SDK Manager”然后进行安装,这样和上面的SDK安装方式一样,就不累述了。
④最后再选择Eclipes主菜单上的"Windows"-选择"preferrnces";
⑤在弹出来的对话框中选中左边栏的“Android”-通过右侧的“Browse...”按钮选择SDK的安装路径根目录-点击最下方的“Ok”按钮,这样SDK就在Eclipse上加载成功了。
4、创建Android模拟器(AVD):
①打开Eclipse-在Eclipse的工具栏上单击下图指示的图标打开“Android Virsual Device Manager”窗口;
②在“Android Virsual Device Manager”窗口单击“New”按钮-在弹出来的窗口中"Name"可以随便取;“Target”指模拟器的系统版本;“SD Card”的"size"是指手机存储卡的大小,只要你不在模拟器上装太多的应用,一般给个二三十MB就够了;“Skin”是指屏幕的分辨率大小,其中“Built in”是一般手机常用标准屏幕分辨率大小,而“Resolution”是自定义屏幕分辨率大小,具体做法,可以根据自身情况选择。-一切设置好后点击“Create AVD”,这时一个模拟器就创建好了。如果有必要,我们可以创建多个模拟器用于测试时使用。
附:Android模拟器型号以及其对应的分辨率大小:
Standard Width Height DAR Pixeis
HVGA 480 * 320 3:2 153,600
QVGA 320 * 240 4:3 76,800
WQVGA400 400 * 240 5:3 96,000
WQVGA432 432 * 240 9:5 103,680
WVGA800 800 * 480 5:3 384,000
WVGA852 854 * 480 409,920
至此为止,在Eclipse上就已经成功搭建Android开发环境了。
Q3: 怎样搭建一个android开发框架
相对于传统计算机程序语言来说,Android开发学习资源上还稍微欠缺一些,对于一些基础应用讲解还稍显匮乏,本篇所讲述的Android培训内容可以帮助大家更好的理解Android项目快速开发框架。结合之前所用的ormlite和hessian,再加上SAE已经支持JAVA,把服务端切换到JAVA,也就有了本文。使用hessian来做数据传输,ormlite来实现客户端与服务端的数据存储,极大的减少了CRUD工作。本文为探索贴,未正式用于大型项目,欢迎大家讨论使用!正文一、简介1.1 ormliteOrmlite[Object Relational Mapping Lite (ORM Lite)]对象关系映射精简版(精简版的ORM)提供了一些简单的,轻量级持久化Java对象到SQL数据库,同时也避免了复杂性和更多的标准的ORM包的开销的功能。支持数据库的jdbc调用,当然,最重要的肯定是它支持android原生的数据库api调用sqlite。——转载自这里。1.2 hessian使用方法参照本博两篇文章:[hessdroid]Android下使用Hessian与Java服务端通讯[hessdroid]Android下使用Hessian与Java服务端通讯的传值测试1.3 Android快速开发框架说明考虑如下几个特点:a). 客户端(Android)和服务端均使用Java语言b). 客户端(Android)和服务端均支持Hessian和ormlite框架c). 完整的支持面向对象开发:存储和交互传输二、准备2.1 开发环境为了便于同时开发Android和Java Web,这里下载的是Eclipse IDE for Java EE Developers版本,然后安装最新的ADT插件和TOMCAT插件。2.2 服务端应用服务器使用Tomcat,采用Java(JSP/Servlet)来实现服务端的业务逻辑,数据库使用Mysql。快速框架搭建推荐大家使用XAMPP(集成Apache、MySQL、PHP等,支持绿色安装)。2.3 客户端普通的Android环境2.4 通信与存储说明服务端与客户端通过Hessian进行数据交换,通过Ormlite保存数据库(通过JDBC保存到服务端的MYSQL数据库,也可以直接保存到客户端的sqlite数据库);三、代码3.1 项目工程截图(服务端)HOLib共用于客户端和服务端,保证接口和数据对象一致性。3.2 重点代码分析3.2.1 服务端web.xml?xml version="1.0" encoding="ISO-8859-1"?web-app xmlns="" xmlns:xsi="" xsi:schemaLocation=" web-app_2_4.xsd" version="2.4" servlet servlet-nameuser/servlet-name servlet-classcom.nmbb.ho.server.servlet.UserServlet/servlet-class /servlet servlet-mapping servlet-nameuser/servlet-name url-pattern/user.do/url-pattern /servlet-mapping listener listener-classcom.nmbb.ho.server.StartupInit/listener-class /listener/web-appStartupInit.javapublic class StartupInit implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent arg0) { try { TableUtils.dropTable(OrmliteHelper.getConnection(), POUser.class, true); //创建数据库 TableUtils.createTable(OrmliteHelper.getConnection(), POUser.class); } catch (SQLException e) { e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent arg0) { }} 代码说明:StartupInit可用于创建数据库表结构,这里用于测试,真实环境注意数据丢失问题。POUser.java@DatabaseTable(tableName = "nmbb_users")public class POUser implements Serializable { /** 用户编号,6位数字 */ @DatabaseField(generatedId = true) public int suid; /** 用户名 */ @DatabaseField(width = 30) public String username; /** 密码 */ @DatabaseField(width = 30) public String password; /** 昵称 */ @DatabaseField(width = 60) public String nickname; /** 200 正常 201 数据校验错误 202用户已经存在 */ public int status = 200; /** 用于放错误信息 */ public String msg; public POUser() { }} 代码说明:注意需要一个空的构造函数,其他请参考ormlite资料。UserServlet.java/*** 用户Servlet** @author 农民伯伯* @see **/public class UserServlet extends HessianServlet implements IUserService { @Override public POUser register(String username, String password) { POUser result = new POUser(); System.out.println("[UserServlet.register]..."); // 检测数据是否合法 if (isEmpty(username) || isEmpty(password)) { result.status = 201; result.msg = "用户名或密码不能为空"; } else { // 检测用户是否存在 OrmliteHelperPOUser db = new OrmliteHelperPOUser(); if (db.exist(POUser.class, "username", username)) { result.status = 202; result.msg = "用户名已经存在"; } else { result.username = username; result.password = password; db.create(result);// 入库 result.msg = "注册成功"; System.out.println("create user suid:" + result.suid); } } return result; } @Override public ListPOUser query(int suid, int startIndex, int pageSize) { return new OrmliteHelperPOUser().query(POUser.class, "suid", suid, startIndex, pageSize) ; } /** * 判断字符串是否为空 * * @param str * @return */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; }}3.2.2 客户端(Android) public class UserActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void OnClickRegiger(View view) { new AsyncTaskVoid, Void, POUser() { @Override protected POUser doInBackground(Void... params) { String url = ""; HessianProxyFactory factory = new HessianProxyFactory(); try { factory.setDebug(true); factory.setReadTimeout(5000); //不设置会报 expected hessian reply at 0x48 factory.setHessian2Reply(false); IUserService basic = (IUserService) factory.create(IUserService.class, url, getClassLoader()); return basic.register("admin", "123456"); } catch (MalformedURLException e) { Log.e("UserActivity", "OnClickRegiger", e); } catch (Exception e) { Log.e("UserActivity", "OnClickRegiger", e); } return null; } @Override protected void onPostExecute(POUser result) { if (result != null) { if (result.status == 200) { //保存入库 new DbHelperPOUser().create(result); } Toast.makeText(UserActivity.this, "" + result.msg, Toast.LENGTH_LONG).show(); } }; }.execute(); }}代码说明:1、DbHelper在源码里给出。2、如果项目无法编译通过,请注意设置项目的字符编码、JDK版本、Android的版本。三、总结5.1 优点a). 完全面向对象开发b). 降低项目的复杂度,减少引入其他框架所带来的复杂性c). 非常适合一个开发服务端和客户端充分的利用的框架的特点,提交开发效率,适合中小型项目快速开发。5.2 缺点a). 注意服务端与客户端共用id的问题5.3 其他a). ormlite支持标准的JPA助记符,这里。这样服务端采用Hibernate应该也是可以的,有时间可以做一个整合例子看看。学习语言同做事情一样,想通其中的关系,就会事半功倍,对语言要深入的理解,
Q4: 如何搭建 android 开发环境
一.认识android的架构
Android其本质就是在标准的Linux系统上增加了Java虚拟机Dalvik,并在Dalvik虚拟机上搭建了一个JAVA的application framework,所有的应用程序都是基于JAVA的application framework之上。
android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。
二.搭建环境
搭建开发环境
对国内的开发者来说最痛苦的是无法去访问android开发网站。为了更好的认识世界,对程序员来说,会翻墙也是的一门技术,带你去领略墙外的世界,好了,不废话了, 国内开发者访问(androiddevtools) 上面已经有了所有你要的资源,同时可以下载到我们的主角framework
但是这样的搭建只能去阅读源代码,我们无法去更进一步去实现自己的rom,我们看到锤子的系统在早期的开放rom是自己从新实现了framework的代码,现在看起来他成功了,所以我们还要去搭建android系统的源码编译环境。
搭建源码编译环境
三.开始主题
在一开始写c程序的时候都有一个运行的入口,比如
#include iostream
#include cmath
#include algorithm
using namespace std;
//这里的main就是应用的入口
int main(int argc, const char * argv[]){
return 0;
}
在计算机网络原理中我们用socket实现一个服务器端,不断的接听客户端的访问,而且他的代码是这样实现的:
#include winsock2.h
#pragma comment(lib, "WS2_32.lib")
#include stdio.h
void main()
{
WORD wVersionRequested;//版本号
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
//加载套接字库,如果失败返回
err = WSAStartup(wVersionRequested, wsaData);
if (err != 0)
{
return;
}
//判断高低字节是不是2,如果不是2.2的版本则退出
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2)
{
return;
}
//创建流式套接字,基于TCP(SOCK_STREAM)
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
//Socket地址结构体的创建
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格
addrSrv.sin_family = AF_INET;//指定地址簇
addrSrv.sin_port = htons(6000);
//指定端口号,除sin_family参数外,其它参数都是网络字节序,因此需要转换
//将套接字绑定到一个端口号和本地地址上
bind(socSrv, (SOCKADDR*)addrSrv, sizeof(SOCKADDR));//必须用sizeof,strlen不行
listen(socSrv, 5);
SOCKADDR_IN addrClient;//字义用来接收客户端Socket的结构体
int len = sizeof(SOCKADDR);//初始化参数,这个参数必须进行初始化,sizeof
//循环等待接受客户端发送请求
while (1)
{
//等待客户请求到来;当请求到来后,接受连接请求,
//返回一个新的对应于此次连接的套接字(accept)。
//此时程序在此发生阻塞
SOCKET sockConn = accept(socSrv, (SOCKADDR*)addrClient, len);
char sendBuf[100];
sprintf(sendBuf, "Welcome %s to JoyChou",
inet_ntoa(addrClient.sin_addr));//格式化输出
//用返回的套接字和客户端进行通信
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多发送一个字节
//接收数据
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\\n", recvBuf);
closesocket(sockConn);
}
}
他采用了一个while死循环去监听客户端的请求。
先上源代码
public final class ActivityThread {
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("pre-initialized");
Looper.prepareMainLooper();
//从中可以看到为app开辟了一个线程进入了looper之中
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
看到源码失望了,没有一个while循环啊,其实用了他方法实现
//用一个looper的机制循环监听响应
Looper.prepareMainLooper();
Looper.loop();
进一步深入代码
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
// 在这里看到了一个循环监听消息
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(" Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println(" Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}






