项目目录
|
|
|
|
Expected a component class,got [object Object]
Small github地址
Small官方教程
使用Small进行Android模块化开发
small的插件化的基本使用
插件模块是Small特有的插件化与IDE完美结合的产物,做到了“模块即组件,组件即插件”。 组件是工程的角度,插件是应用的角度。只有做到了清晰的组件解耦,才能更好的拆分插件模块。
出于业务需求考虑,Small定义了两类插件:公共库插件与应用插件。应用插件相对简单,就是用来把大应用拆分成一个个小的业务单元,公共库插件则是为这些业务单元提供公共的代码与资源。
通过设定 URI,宿主、本地化应用插件、本地化web插件、在线网页,以及任何自定义的插件之间能够相互调起与传递参数。
目前已支持 Android 、iOS 以及 HTML5 插件。并且三者之间可以通过同一套 JavaScript 接口进行通信。
通过 build.gradle 集成 Small,项目的build.gradle文件中
|
|
通过 自定义Application 初始化 Small,app > java > com.example.mysmall > SmallApp中
|
|
AndroidManifest.xml中
|
|
创建插件模块 App.main,注意包名为com.example.app.main
通过 buildLib,buildBundle 编译 Small 插件,命令后面可添加 -Dbundle.arch=x86
|
|
通过 bundle.json 配置插件路由,右键 app 模块,New > Folder > Assets Folder 新建 assets 目录,在新建配置文件bundle.json内容如下
|
|
通过 Small.openUri 启动插件,宿主的 app > java > com.example.mysmall > MainActivity中
|
|
创建公共库插件模块 Lib.style,注意包名为com.example.lib.style,将app.main/src/main/res/values 下除了strings.xml的文件移动到lib.style/src/main/res/values 目录下,修改 lib.style/src/main/res/colors.xml中colorPrimary值为#2FA739
添加公共库引用,修改 app.main/build.gradle,增加对 lib.style 的依赖
|
|
添加插件路由
|
|
重新运行
|
|
宿主:工程中的app模块,不能依赖lib.xxx
|
|
公共库插件:工程中的lib.xxx模块,是标准的Android库工程
其中-q是安静模式,可以让输出更好看,也可以不加。对插件的编译,会在app/smallLibs/生成对应的so文件,这些so文件本质上就是独立的apk包。
// 框架初始化
Small.preSetUp(this);
// 浏览器跳转url
Small.setBaseUri(“http://code.wequick.net/small-sample/“);
// 在宿主的 Application 里指定是否从 assets 读取插件,有build.gradle 中 buildToAssets的值指定
Small.setLoadFromAssets(BuildConfig.LOAD_FROM_ASSETS);
// 设定基本的跳转地址
Small.openUri(“https://github.com/wequick/Small/issues“, MainActivity.this);
// 更新bundles.json和version信息
Small.updateManifest(info.manifest, false)
// 获取补丁文件目录
net.wequick.small.Bundle bundle = Small.getBundle(u.packageName);
File file = bundle.getPatchFile();
// 使更新后的插件生效
bundle.upgrade();
// 暗度插件意图
Small.wrapIntent(intent);
// 创建远程fragment
Small.createObject(“fragment-v4”, sUris[position], MainActivity.this);
// 设置网页的基本回调
Small.setWebViewClient(new MyWebViewClient());
// TODO
Small.getBundleVersions()
// TODO
Small.setWebActivityTheme(R.style.AppTheme);
// TODO
Small.getIsNewHostApp()
打开项目的app工程也就是入口工程,文件夹里有一个smallLibs文件夹,里面有一个armeabi文件,里面是.so文件,这些文件就是通过buildLib和buildBundle来把非宿主的app中的文件打包成的.so文件。最终安装到手机上的apk其实就是只有宿主的apk和其内部的.so文件,通过加载.so文件来实现加载插件中的文件。热更新就是更新bundle.json文件和插件.so文件的过程。
增量更新的原理是:在服务器端先拿新版本安装包和旧版本安装包进行对比,在生成差异包之后下发,之后客户端根据对应的差异包和本地旧版本安装包合成,便生成了新版本安装包。
对于Small框架,它把每个插件都编译成.so文件,然后存放到app的native目录下,不过,如果它发现自己的download目录有新的插件,那么就会去加载download目录下的插件,并且这种加载优先权是最大的,也就是说它会优先加载download目录下的插件。所以,如果我们要做增量更新,旧文件就从app的native目录进行读取,然后从服务器端下载增量包,最后合成的文件存放到download目录下,这样每次插件启动都会到download目录下加载新的插件。
嵌入到现有原生应用
史上最详细的Android原生APP中添加ReactNative 进行混合开发教程
MainActivity.java完整代码如下:
MyReactActivity完整代码如下:
package.json文件如下,注意react和react native的版本
|
|
添加index.android.js文件到项目中
|
|
app/build.gradle配置
|
|
整个工程build.gradle配置
|
|
app/src/main/AndroidManifest.xml配置
|
|
如果点击按钮后应用崩溃了,同时Android Studio中报错 permission denied for this window type ,需要开启悬浮窗(overlay)权限。
解决方法一,修改MainActivity.java中代码如下:
解决方法二,修改MyReactActivity.java中代码如下:
编辑~/.gradle/gradle.properties,~表示用户目录,比如windows上可能是C:\Users\用户名,而mac上可能是/Users/用户名,没有就创建一个,添加如下的代码,把其中的**替换为相应密码:
|
|
编辑你项目目录下的android/app/build.gradle,添加如下的签名配置:
|
|
cmd进入项目android目录,执行 gradlew installRelease,生成的APK文件位于项目的android/app/build/outputs/apk/app-release.apk
执行gradlew installRelease
如果报错Unable to process incoming event 'ProcessComplete' <ProgressCompleteEvent>
,这种错误
需要在在混淆文件/android/app/proguard-rules.pro末尾中加入
将 /android/app/src/main/res/values/strings.xml 中 app_name 的值改成想要的app名称
将 /android/app/src/main/res/ 路径下,mipmap-开头的目录中的图片替换为同名的其它图片
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
第一个包,即Client发给Server的SYN中途被丢,Client会周期性超时重传,直到收到Server的确认;
第二个包,即Server发给Client的SYN+ACK中途被丢,Server会周期性超时重传,直到收到Client的确认;
第三个包,即Client发给Server的ACK中途被丢:
a)假定此时双方都没有数据发送,Server会周期性超时重传SYN+ACK,直到收到Client的确认收到之后Server的TCP连接业也为established状态;
b)假定此时Client有数据发送,Server收到Client的Data+ACK,自然会切换为established状态,并接受Client的Data;
c)假定Server有数据发送,数据发送不了,会一直周期性超时重传SYN+ACK,直到收到Client的确认才可以发送数据。
为什么连接的时候需要三次握手?
在谢希仁的《计算机网络》中是这样说的:“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。”书中举例:“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
网上查到:“这个问题的本质是,信道不可靠,但是通信双发需要就某个问题达成一致,而要解决这个问题,无论你在消息中包含什么信息,三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足”在不可靠信道上可靠地传输信息”这一需求所导致的。这可视为对“三次握手”目的的另一种解答思路。
第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
为什么断开的时候需要四次挥手?
因为TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
别人评论《Web表单设计:点石成金的艺术》这本书非常好,ANT DESING 官网的资源中也提到了这本书,于是买了一本看看。这本书已经绝版了,我买的是影印版的,图片大多数都看不清,我个人对这本书并没有什么特别好的感觉,没感觉到对自己有什么帮助。现在把每章的最佳实践记录下来,希望能够加深些理解,后期需要时能够想到这本书。
NPM install
|
|
IOS install
|
|
Android install
|
|
|
|
|
|
Usage
在上一篇React-Native-上传下载例子的基础上,添加如下代码
|
|
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW)服务器传输超文本到本地浏览器的传送协议。它基于TCP/IP通信协议来传递数据,是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力,如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间。HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。
一次HTTP操作称为一个事务,其工作过程可分为四步:
如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。
根据HTTP标准,HTTP请求可以使用多种请求方法。HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
常见状态代码、状态描述、说明:
1**(信息类):表示接收到请求并且继续处理
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本,只能切换到更高级的协议
2**(响应成功):表示动作被成功接收、理解和接受
200——表明该请求被成功地完成,所请求的资源发送回客户端
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
3**(重定向类):为了完成指定的动作,必须接受进一步处理
300——请求的资源可在多处得到
301——本网页被永久性转移到另一个URL
302——请求的网页被转移到一个新的地址,但客户访问仍继续通过原始URL地址,重定向,新的URL会在response中的Location中返回,浏览器将会使用新的URL发出新的Request
303——建议客户访问其他URL或访问方式
304——自从上次请求后,请求的网页未修改过,服务器返回此响应时,不会返回网页内容,代表上次的文档已经被缓存了,还可以继续使用
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
4**(客户端错误类):请求包含错误语法或不能正确执行
400——客户端请求有语法错误,不能被服务器所理解
401——请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
402——保留有效ChargeTo头响应
403——禁止访问,服务器收到请求,但是拒绝提供服务
404——一个404错误表明可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。eg:输入了错误的URL
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长。
5**(服务端错误类):服务器不能正确执行一个正确的请求
500——服务器遇到错误,无法完成请求
501——未实现
502——网关错误
503——由于超载或停机维护,服务器目前无法使用,一段时间后可能恢复正常
504——充当网关或代理的服务器,未及时从远端服务器获取请求
505——服务器不支持请求的 HTTP 协议的版本,无法完成处 理