├── .gitignore
├── 8.源码分析[2].md
├── LICENSE
├── README.md
├── React Native 官方文档中文版-from-极客学院.epub
├── lession1.helloworld.md
├── lession10.ImageView 使用采坑.md
├── lession11.UI常见小例子.md
├── lession2.常见问题汇总.md
├── lession3.ReactJS语法-android.md
├── lession4.手势触摸响应链说明.md
├── lession5.实现一个native_RN组件.md
├── lession6.工具调试.md
├── lession7.源码分析[1].md
├── lession9.NativeModule组件封装教程.md
├── pics
├── 1.jpeg
├── 2.jpeg
├── 3.jpeg
├── Screenshot_2015-09-23-12-30-41.png
├── Screenshot_2015-09-23-16-41-45.png
├── Screenshot_2015-10-14-19-51-43.png
├── demo-list.png
├── device-2015-09-21-180925-w.png
├── device-2015-09-21-180925.png
├── flexbox.png
├── js-url.png
├── jsc-bug.png
├── nullable duplication.png
├── remote-url.png
├── snap-chrome-plugin.png
└── uiexplorer.png
├── react-android.bundle.js
└── react-native-android-lession.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
--------------------------------------------------------------------------------
/8.源码分析[2].md:
--------------------------------------------------------------------------------
1 | #为什么在AwesomeProject里没看到React对应的so,
2 |
3 | 其实他是通过gradle依赖的那个gradle-dependence实现的。
4 |
5 | 而如果要看compile'com.facebook.react:react-native:0.11.0'的实现,
6 |
7 | 就要去git上下载
8 |
9 | https://github.com/facebook/react-native 项目代码
10 |
11 |
12 |
13 | #通过ReactAndroid项目可以看到,他的“复杂的”gradle脚本,
14 |
15 | 里面有操作node_module 的task,并且依赖ndk环境编译
16 |
17 | 可能会遇到该问题
18 |
19 | 
20 | #mac下配置NDK配置React
21 |
22 | http://developer.android.com/ndk/downloads/index.html#download
23 |
24 | 将bin文件放到你一个新开辟的文件下后,执行:
25 |
26 | ndk$ chmod a+x android-ndk-r10c-darwin-x86_64.bin
27 |
28 | ndk$ ./android-ndk-r10c-darwin-x86_64.bin
29 |
30 | 之后就可以看到
31 |
32 | 
33 |
34 | 项目可以编译通过的状态。
35 |
36 |
37 | 在我们的主工程项目里面也可以看到node_modules的对应目录关系:
38 |
39 |
40 | 
41 |
42 | # ReactAndroid打包分析[共15个task]:
43 |
44 | 1.task createNativeDepsDirectories
45 |
46 | 2.task downloadBoost
47 |
48 | 3.task prepareBoost
49 |
50 | 4.task downloadDoubleConversion
51 |
52 | 5.task prepareDoubleConversion
53 |
54 | 6.task downloadFolly
55 |
56 | 7.task prepareFolly
57 |
58 | 8.task downloadGlog
59 |
60 | 9.task prepareGlog
61 |
62 | 10.task downloadJSCHeaders
63 |
64 | 11.task prepareJSC
65 |
66 | 12.task buildReactNdkLib
67 |
68 | 13.task cleanReactNdkLib
69 |
70 | 14.task packageReactNdkLibs
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-android-lession
2 | ---
3 | > 老穆记录: react native andorid
4 |
5 | ---
6 | [关于iOS部分可以参考vczero的lession文章](https://github.com/vczero/react-native-lession)
7 |
8 |
9 | > React-Native 是Android端实现实现动态部署的另一种思路,绕过dexLoad【一些现有的Android插件框架】。
10 |
11 | > 是在开发效率和用户体验间做的一种权衡。
12 |
13 | > React-native使用JS开发,开发效率高、发布能力强。
14 |
15 |
16 | * 1、用编辑器打开对应的.js文件,分析代码结构:
17 |
18 | var React = require('react-native');
19 |
20 | 和Node.js有关,require可以引入其他模块。
21 |
22 | 类似java 的 import com.andorid.xx.Act;
23 |
24 | * 2、定义组件,结构化的代码:
25 |
26 | var {
27 |
28 | AppRegistry,
29 |
30 | StyleSheet,
31 |
32 | Text,
33 |
34 | View,
35 |
36 | } = React;
37 |
38 | * 3、React.createClass里的render方法就是渲染视图用的。return返回的是视图的模板代码。
39 |
40 | * 4、样式表现:那么StyleSheet.create就是干这件事的,只是用JS的自面量表达了css样式。
41 |
42 | * 5、引入css样式:
43 |
44 | 方法1:style={styles.container}
45 |
46 | 方法2:style={{width:20,height:100}}
47 |
48 | * 6、注册View组件,第二个参数为React.createClass创建的 那个var对象
49 |
50 | AppRegistry.registerComponent('aswsome', () => yourVar);
51 |
52 | #最新动态
53 | 15.10.28日React Native Android可以load指定 jsBundle啦 虽然暂时还不支持直接的server-url,但是可以通过自定义JSLoader+DownloadManager去实现了。
54 |
55 | 1.这个代码应该会合到0.14版本中 https://github.com/facebook/react-native/releases
56 |
57 | 2.使用loadFromFile代替了loadFromNetwork
58 |
59 | 3.使用loadFromAssets充当了loadFromNetworkCached
60 |
61 | 4.code diff http://t.cn/RU5aksF?u=1310602621&m=3903222676550852&cu=1310602621
62 |
63 | #1.环境安装
64 | 1.安装nvm
65 |
66 | * 1.brew install nvm
67 |
68 | 2.nvm 安装最新的 Node.js 4.0
69 |
70 | * nvm install node && nvm alias default node
71 |
72 | 3.安装watchman 和 flow
73 |
74 | * $ brew install watchman
75 | * $ brew install flow
76 |
77 | 并更新brew
78 |
79 | * brew update && brew upgrade
80 |
81 | #2.demo运行
82 |
83 | 首先切换到你想要的目录下,依次执行以下命令
84 |
85 | * $ npm install -g react-native-cli
86 |
87 | * $ react-native init AwesomeProject
88 |
89 | * $ cd AwesomeProject/
90 |
91 | 运行项目
92 |
93 | * $ react-native run-android
94 |
95 | #3.react-android依赖树
96 |
97 | android-jsc-r174650
98 |
99 | appcompat-v7-23.0.0
100 |
101 | bolts-android-1.1.4
102 |
103 | drawee-0.6.1
104 |
105 | fbcore-0.6.1
106 |
107 | fresco-0.6.1
108 |
109 | imagepipeline-0.6.1
110 |
111 | imagepipeline-okhttp-0.6.1
112 |
113 | jackson-core-2.2.3
114 |
115 | jsr305-3.0.0
116 |
117 | library-2.4.0
118 |
119 | okhttp-2.4.0
120 |
121 | okhttp-ws-2.4.0
122 |
123 | okio-1.5.0
124 |
125 | react-native-0.11.0
126 |
127 | support-annotations-23.0.0
128 |
129 | support-v4-23.0.0
130 |
131 |
132 |
133 | #4.从服务端动态拉取配置,并用listview进行展示
134 |
135 | ##1.listview展示
136 |
137 | 
138 |
139 | ##2.自定义webview 和 自定义Toast
140 |
141 | 
142 |
143 | ## 3.配合官方的UI explorer,对学习和使用ReactAndroid都会有非常大的帮助
144 |
145 | 
146 |
147 | 
148 |
--------------------------------------------------------------------------------
/React Native 官方文档中文版-from-极客学院.epub:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/React Native 官方文档中文版-from-极客学院.epub
--------------------------------------------------------------------------------
/lession1.helloworld.md:
--------------------------------------------------------------------------------
1 | #1.跑起来helloWorld
2 | ##1.安装nvm
3 | 1.brew install nvm
4 |
5 | ##2.nvm 安装最新的 Node.js 4.0
6 |
7 | nvm install node && nvm alias default node
8 | ##3.安装watchman 和 flow
9 | $ brew install watchman
10 |
11 | $ brew install flow
12 |
13 | 并更新brew
14 |
15 | brew update && brew upgrade
16 |
17 |
18 | #RN,Hello world
19 | ##构建项目
20 | 首先切换到你想要的目录下,依次执行以下命令
21 |
22 | $ npm install -g react-native-cli
23 |
24 | $ react-native init AwesomeProject
25 |
26 | $ cd AwesomeProject/
27 | ##运行项目
28 | $ react-native run-android
29 | #2.熟悉jsx语法
30 |
31 | 上手简单页面 具体内容:
32 |
33 | 
--------------------------------------------------------------------------------
/lession10.ImageView 使用采坑.md:
--------------------------------------------------------------------------------
1 |
2 | # Android ReactNative ImageView 的使用
3 |
4 | > 在使用RNAndroid 的 ToolbarAndroid时 ,关于navIcon标签的属性值,即设置左上角导航图片的资源路径时,发现直接尝试加载android apk包中的资源会失败:
5 |
6 | 
7 | ## imageView source的 资源路径的设置
8 | > 主要有以下几种形式可供使用和操作:
9 |
10 | ### 1.根据当前 node 服务器的 资源绝对路径
11 | * 进行配置,验证可以正常显示:
12 |
13 | ``
14 |
15 |
16 |
17 | ### 2.根据给定的url
18 | * 直接显示,验证可以正常显示:
19 |
20 | ``
21 |
22 | ### 直接使用apk包中图片名
23 |
24 | * 在使用ToolbarAndroid 时可以看到 navIcon的属性值是支持直接传递apk包内的图片名的。
25 |
26 | * 即还有一种是 让js直接使用app的 res包下的drable资源,这里遇到了一些问题,按道理说,程序会自动去当前的app容器中起找,考虑到RN的消息通信的流转机制,毕竟最总绘制UI ,是发生在 native这一层,所以 picture 及 xml 等资源文件的路径索取,应该还是会回归到native那一次层,如果是是使用app包内的图片资源,那么按照官方给出的样例,后缀名是不用写的,这也是Android 本身推荐的方式。
27 |
28 | * 但是目前直接这样操作(apk包里已经有了 这个同名的文件ic_launcher.png),貌似是不能正常显示出来,官方是有给出这样的加载方式的case,但是我这边本地这样尝试,貌似没有成功,切换到上两种情况即ok了。不知道大家有没有遇到类似情况。
29 |
30 | `< Image source={{uri: 'ic_launcher'}} style={{width: 30, height: 30}} />`
31 |
32 |
33 | ## 对应官方Image 文档:
34 | [http://facebook.github.io/react-native/docs/image.html#content](http://facebook.github.io/react-native/docs/image.html#content)
35 |
36 |
37 | ## 源码分析及跟踪
38 |
39 | ### ImageRequestBuilder
40 | 根据红框的log,可以找到对应的ImageRequestBuilder类的代码【截图如下】,
41 | 从mathod的doc中可以看到,就是标准的ImageView是只支持network and local uris,那么 navIcon那个难道是自己拼的uri不成?
42 |
43 | 
44 | 
45 |
46 |
47 |
48 |
49 | ### ReactImageView
50 | 再去对照ReactAndroid 的 ReactImageView源码,可以看到在setSource方法中,对source的路径相关的合法性检验和处理,里面有个mIsDitrty的结果反馈。
51 |
52 | 另外,优先check了分发uri后,如果失败,则会继续调用ReactImageView的静态方法 getResourceDrawableUri(Context context , String name)
53 |
54 | 
55 |
56 | ### getResourceDrawableUri
57 | getResourceDrawableUri 最终会执行通过下面React中如下代码获得DrawableId
58 |
59 | return context.getResources().getIdentifier(
60 | name.toLowerCase().replace("-", "_"),
61 | "drawable",
62 | context.getPackageName())`
63 |
64 | * 平时直接用getIdentifier() 不是特别多,简单说明下方法参数介绍
65 |
66 | > Resources resources = context.getResources();
67 |
68 | >intindentify= getResources().getIdentifier("icon", "drawable", "org.xx.package");
69 |
70 | > 第一个参数为ID名,第二个为资源属性是ID或者是Drawable,第三个为包名。
71 |
72 | ### R.java
73 | 到gradle的build/generated/source/r/debug/package里可以找到R.java文件,去里面查一下是否有自己要用的那个 drawable名字
74 |
75 | 查了后 ,fuck ,果然没有 这个ic_launcher 的id名
76 |
77 |
78 |
79 | ### id
80 | 一路跟踪 。。。。。擦,写死了 drawable 这种type, 而新版本的Studio是推荐的mipmap文件夹。。。。。额 找到问题关键了
81 |
82 | 
83 | 
84 | 
85 |
86 |
87 |
88 | ### mipmap
89 | 原来是 新的Android studio 现在新建的文件夹都是mipmap-xxdpi 而不是以前的drawable-xxdpi,自己也没有注意
90 |
91 | 具体的原因可以参考这里,http://segmentfault.com/q/1010000002603418
92 |
93 | 即官方后续也是推荐使用mipmap代替 drawable...
94 |
95 | ### 曙光
96 | 换成drawable 下 ,运行正常,采坑结束,基本了解了 js端imageView组件到native层加载搜索的逻辑了
97 |
98 |
99 | 文章源地址见 github :[老穆 React Native 常见采坑总结](https://github.com/yipengmu/ReactNative_Android_QA/blob/master/README.md)
100 |
--------------------------------------------------------------------------------
/lession11.UI常见小例子.md:
--------------------------------------------------------------------------------
1 | #UI 常用 小case
2 |
3 |
4 | ##1.setTimeout
5 |
6 | render里面 onpress时调用:被点击后200秒触发弹框
7 |
8 | fondSellOut(event) {
9 | setTimeout(function() {
10 | alert('click')
11 | }, 2000);
12 | console.log('Pressed!');
13 | },
--------------------------------------------------------------------------------
/lession2.常见问题汇总.md:
--------------------------------------------------------------------------------
1 | #常见问题汇总:
2 | #1.假如你成功了
3 | ##success界面
4 | 按照官方的教程把RN-android 环境搭建好后,就可以把demo跑起来了;
5 |
6 | 
7 |
8 | 本地实际的访问地址可以参考:
9 | http://localhost:8081/index.android.bundle?platform=android
10 |
11 | #2.可能第一次都会失败
12 |
13 | ##1.出现一个红色的界面,failed JS bundle
14 |
15 | 
16 |
17 | 解决方案:
18 |
19 | 有时候你运行 react-native run-android,发现并不能自动运行 dev server,你可以在当前项目目录中运行如下命令来手动启动 server:
20 | ```shell
21 | $ react-native start
22 | ```
23 | 本地server指定的8081端口并没有成功接送数据
24 |
25 | adb reverse tcp:8081 tcp:8081
26 |
27 | 可以在chrome浏览器中访问:http://localhost:8081/
28 |
29 | 在JS-SERVER上看到数据包过来
30 |
31 | 
32 |
33 | 如果是5.0以下的系统 会爆出closed , 建议使用wifi方式进行调试
34 | ```shell
35 | $ adb reverse tcp:8081 tcp:8081
36 | error: closed
37 | ```
38 | 点击手机的物理menu键, 或者摇动手机才会出现Dev settings菜单(这项操作需要在你已经打开的ReactNavtive应用界面操作才有效)
39 |
40 | Dev Settings -> Debug server host for device,
41 |
42 | 填入自己pc电脑上的 IP 地址,需要在同一网段,例如手机和pc都连接到了tplink-wifi-sid上。
43 |
44 | 之后menu-reload js 即可。
45 |
46 | 如果手机和电脑不在同一个网段,或者手机不能访问到,就会出现
47 | Unable to download js bundle的红屏界面
48 |
49 | ##2.可能出现白色的界面
50 | 
51 | 解决方案:
52 |
53 | 像MIUI等系统,默认会把那个显示悬浮窗开关给屏蔽关掉【用户可以手动切换】,操作后,重新load即可
54 |
55 | 更常见的搭建问题可以参考下这个:http://www.race604.com/react-native-for-android-start/
56 |
57 | ##3.invariant Violation:Application 红色屏幕错误
58 | 
59 |
60 | 解决方案:
61 |
62 | 1.首先可以参考 OverStack 和一个官方的issue:
63 |
64 | http://stackoverflow.com/questions/29287987/invariant-violation-application-awesomeproject-has-not-been-registered-when-b
65 |
66 | https://github.com/facebook/react-native/issues/500#issuecomment-111575780
67 |
68 | 2.根据具体错误信息去排查,最后发现我出现这个错误的原因是不小心在文件头部打多了个无效字符,导致无法正确解析下面的代码行。所以只需要把那个无用的代码【影响了语法编译环节】删掉,重新reload -js 即可
69 |
70 | ##4.加载UIExplorerBlock失败
71 |
72 | 
73 |
74 | 这是一个官方bug,默认的node_modules里面并没有该组件对应
75 |
76 | https://github.com/facebook/react-devtools/issues/128
77 |
78 | ios之前有这个问题,Android的初期版本貌似也有该类似问题
79 |
80 | ##5. .babelrc.stage文件错误
81 | ```java
82 | transforming [========================================] 100% 399/400
83 | Error while persisting cache: TransformError: /Users/alexwan/Documents/Project/HelloWorld/node_modules/react-deep-force-update/lib/index.js: [BABEL] /Users/alexwan/Documents/Project/HelloWorld/node_modules/react-deep-force-update/lib/index.js: Unknown option:
84 | /Users/alexwan/Documents/Project/HelloWorld/node_modules/react-deep-force-update/.babelrc.stage
85 | ```
86 | 项目文件夹中node_modules/react-deep-force-update/.babelrc.stage 这个文件也会引起`红屏`,删除之后就可以运行通过了。
87 |
--------------------------------------------------------------------------------
/lession3.ReactJS语法-android.md:
--------------------------------------------------------------------------------
1 | #React需要注意的语法
2 |
3 | ##所有的jsx组件Facebook推荐大家按照一定的格式去编写
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | * 1.对于ui 组件使用大写命名
15 |
16 | * 2.对于组件的属性使用小写命名
17 |
18 | * 3.对于style的配置支持按照对象方式去引用,{yourvar.somelable};
19 |
20 | * 4.也支持两层嵌套style样式,直接写入属性,类似{{}}
21 |
22 | * 5.对于style,React还支持 数组的方式即{[yourvar.somelable1,yourvar.somelable2]}
23 |
24 | ##style样式写法
25 | var styles = StyleSheet.create({
26 | base: {
27 | width: 38,
28 | height: 38,
29 | },
30 | background: {
31 | backgroundColor: '#222222',
32 | },
33 | active: {
34 | borderWidth: 2,
35 | borderColor: '#00ff00',
36 | },
37 | });
38 |
39 | 这样的构造StyleSheet的方式是非必须的但是是(老穆)推荐的.
40 |
41 | 他的目的类似函数封装,对于后续的复用和重载都会有一定好处.
42 |
43 | 当然你也可以直接通过内联方式去编写样式代码例如
44 |
45 | ``
--------------------------------------------------------------------------------
/lession4.手势触摸响应链说明.md:
--------------------------------------------------------------------------------
1 | #React-android的手势响应链
2 | 由于react native 不同于 webview,最终落地是 实打实的 native view componet 。
3 |
4 | 所以在响应事件分发情况上来说,是完全具备native的各种touch处理能力的:`fling,touch,tap,click,double click and ....。`
5 |
6 | 能够有分级,分阶段,父view与子view直接的 消息传递和消息处理链的存在。
7 |
8 | 对应的ReactJS处理的实现在`ResponderEventPlugin.js`中
9 |
10 | #交互上体验提升
11 | 之前使用h5的方式,对于客户端手势交互的反馈不是很友好,但是native可以很好的解决该问题
12 |
13 | 系统提供标准的selector.xml方式让开发者快速实现“二态效果”,包括其他的cancel状态的变更,快速,灵敏的反应对于app的交互体验将远好于web app的体验
14 |
15 | #ReactJs端的实现
16 |
17 | > View.props.onStartShouldSetResponder: (evt) => true
18 | > View.props.onMoveShouldSetResponder: (evt) => true
19 | > View.props.onResponderGrant: (evt) => {}
20 | > View.props.onResponderReject: (evt) => {}
21 | > View.props.onResponderMove: (evt) => {}
22 | > View.props.onResponderRelease: (evt) => {}
23 | > View.props.onResponderTerminationRequest: (evt) => true
24 | > View.props.onResponderTerminate: (evt) => {}
25 |
26 | ##这里的evt 是一个touch的语义的封装:
27 |
28 | nativeEvent
29 |
30 | changedTouches - Array of all touch events that have changed since the last event
31 |
32 | identifier - The ID of the touch
33 |
34 | locationX - The X position of the touch, relative to the element
35 |
36 | locationY - The Y position of the touch, relative to the element
37 |
38 | pageX - The X position of the touch, relative to the screen
39 |
40 | pageY - The Y position of the touch, relative to the screen
41 |
42 | target - The node id of the element receiving the touch event
43 |
44 | timestamp - A time identifier for the touch, useful for velocity calculation
45 |
46 | touches - Array of all current touches on the screen
47 |
48 |
49 | ##如果父容器需要消耗事件
50 | View.props.onStartShouldSetResponderCapture: (evt) => true,
51 |
52 | View.props.onMoveShouldSetResponderCapture: (evt) => true,
--------------------------------------------------------------------------------
/lession5.实现一个native_RN组件.md:
--------------------------------------------------------------------------------
1 | #编写一个Native模块
2 |
3 | #extends ReactContextBaseJavaModule
4 | “一个原生模块是一个通常继承 ReactContextBaseJavaModule 类的 Java 类,并且实现了 JavaScript 需要实现的方法。
5 |
6 | 我们这里的目标是允许通过使用 JavaScript 书写 ToastAndroid.show('Awesome', ToastAndroid.SHORT);
7 |
8 |
9 | 就可以在屏幕上面显示一个短短的 toast 消息。”
10 |
11 | package com.facebook.react.modules.toast;
12 | import android.widget.Toast;
13 | import com.facebook.react.bridge.NativeModule;”
14 |
15 | import com.facebook.react.bridge.ReactApplicationContext;
16 | import com.facebook.react.bridge.ReactContext;
17 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
18 | import com.facebook.react.bridge.ReactMethod;
19 |
20 | import java.util.Map;
21 | public class ToastModule extends ReactContextBaseJavaModule {
22 | private static final String DURATION_SHORT_KEY = "SHORT";
23 | private static final String DURATION_LONG_KEY = "LONG";
24 | public ToastModule(ReactApplicationContext reactContext) {
25 | super(reactContext);
26 | }
27 | }
28 |
29 | “ReactContextBaseJavaModule 需要一个叫做 getName 的方法被实现。
30 |
31 | 这个方法的目的就是返回在 JavaScript 里面表示这个类的叫做 NativeModule 的字符串的名字。
32 |
33 | 在这里我们调用 ToastAndroid 因此我们可以在 JavaScript 里面使用 React.NativeModules.ToastAndroid 来得到它。”
34 |
35 | @Override
36 | public String getName() {
37 | return "ToastAndroid";
38 | }
39 |
40 | “给 JavaScript 暴露一个方法,一个 Java 方法需要使用 @ReactMethod 来注解。
41 |
42 | 桥接的方法的返回值类型总是 void。
43 |
44 | React Native 的桥接是异步的,因此将一个结果传递给 JavaScript 的唯一方式就是使用回调函数或者调用事件”
45 |
46 | @ReactMethod
47 | public void show(String message, int duration) {
48 | Toast.makeText(getReactApplicationContext(), message, duration).show();
49 | }”
50 |
51 | 参数映射规则如下 @ReactMethod:
52 |
53 | Boolean -> Bool
54 |
55 | Integer -> Number
56 |
57 | Double -> Number
58 |
59 | Float -> Number
60 |
61 | String -> String
62 |
63 | Callback -> function
64 |
65 | ReadableMap -> Object
66 |
67 | ReadableArray -> Array
68 |
69 | #注册Native模块
70 |
71 | 在使用 Java 的最后一步就是注册这个模块,这将在你的应用包中的 createNativeModules 发生。如果一个模块没有被注册,那么它在 JavaScript 是不可用的。
72 |
73 | class AnExampleReactPackage implements ReactPackage {
74 |
75 | @Override
76 | public List createNativeModules(ReactApplicationContext reactContext) {
77 | List modules = new ArrayList<>();
78 | modules.add(new ToastModule(reactContext));
79 | return modules;
80 | }
81 |
82 | #使用ReactJS调用
83 | var {
84 | NativeModules
85 | } = require('react-native');
86 |
87 | module.exports = NativeModules.ToastAndroid;”
88 |
89 | var ToastAndroid = require('ToastAndroid')
90 | ToastAndroid.show('Awesome', ToastAndroid.SHORT);
91 |
--------------------------------------------------------------------------------
/lession6.工具调试.md:
--------------------------------------------------------------------------------
1 | #调试与测试
2 | “安装 React Developer Tools 作为谷歌浏览器的扩展。这将允许您通过 React 在开发工具中导航组件层次结构 ( 更多详情参阅 facebook/react-devtools )。”
3 |
4 |
5 |
6 | 
7 |
8 | https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en
9 |
10 | #通过menu设置
11 | * js auto reload
12 | * debug ip port
--------------------------------------------------------------------------------
/lession7.源码分析[1].md:
--------------------------------------------------------------------------------
1 | #React 0.11.0 源码分析
2 |
3 | ##如何调用远程的js
4 | * 根据代码分析,目前react.jar里没有剥离出对于的setLocalJSFilePatch()和setRemoteJsFileUrl()的方法。
5 |
6 | 跟进代码到
7 |
8 | ReactInstanceManager.onJSBundleLoadedFromServer();
9 |
10 |
11 | recreateReactContext(
12 |
13 | new JSCJavaScriptExecutor(),
14 |
15 | JSBundleLoader.createCachedBundleFromNetworkLoader(
16 |
17 | mDevSupportManager.getSourceUrl(),
18 |
19 | mDevSupportManager.getDownloadedJSBundleFile()));
20 |
21 |
22 |
23 | ##JS加载初始化逻辑源码分析
24 | * 通过分析初始化逻辑及加载逻辑,我们很容易能够跟进到ReactInstanceManager这个类中的,方法onJSBundleLoadedFromServer();
25 |
26 | 
27 |
28 |
29 | ##现在只能通过dev-setting的Helper类进行设置
30 |
31 | * 通过手机的硬件物理menu菜单,里面有个设置ip的地方,即加载本sid网段下的一个指定ip
32 |
33 | * 而本地会启动一个Node服务器,把现在的安格indexandroid.js部署在那个服务器上,只能手动改变那个js中代码,进行配置
34 |
35 | 
36 |
37 | ##如何分离图片库fresco和网络库okhttp
38 | * 这个是个好问题,目前的版本代码耦合还是比较紧密的,需要进一步分析和跟进源代码,系统能够做一个adapter适配器,让不同的实现者可以注入自己的图片库和网络库
--------------------------------------------------------------------------------
/lession9.NativeModule组件封装教程.md:
--------------------------------------------------------------------------------
1 | #如何封装一个React native for android 的 NativeModule组件
2 |
3 |
4 | ##1.首先需要使用自己的packageManager
5 |
6 | public class YourRnPackage extends MainReactPackage {
7 | @Override
8 | public List createNativeModules(ReactApplicationContext reactContext) {
9 | List modules = super.createNativeModules(reactContext);
10 | //new an Array intstead of abstract List exception
11 | List result = new ArrayList<>();
12 | result.addAll(modules);
13 | result.add(new YourOpenSomePageModule(reactContext));
14 | result.add(new YourToastModule(reactContext));
15 | return result;
16 | }
17 | @Override
18 | public List> createJSModules() {
19 | return Collections.emptyList();
20 | }
21 |
22 | @Override
23 | public List createViewManagers(ReactApplicationContext reactContext) {
24 | List main = super.createViewManagers(reactContext);
25 | List result = new ArrayList<>();
26 | result.addAll(main);
27 | result.add(new YourWebviewManager());
28 |
29 | return result;
30 |
31 | }
32 | }
33 |
34 |
35 | #2.在你的Activitiy或Fragment中对其进行设置
36 |
37 |
38 | public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
39 | private ReactInstanceManager mReactInstanceManager;
40 | private ReactRootView mReactRootView;
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | mReactRootView = new ReactRootView(this);
46 |
47 | mReactInstanceManager = ReactInstanceManager.builder()
48 | .setApplication(getApplication())
49 | .setBundleAssetName("index.android.bundle")
50 | .setJSMainModuleName("index.android")
51 | .addPackage(new YourRnPackage())
52 | .setUseDeveloperSupport(BuildConfig.DEBUG)
53 | .setInitialLifecycleState(LifecycleState.RESUMED)
54 | .build();
55 |
56 | mReactRootView.startReactApplication(mReactInstanceManager, "YourRnPackage", null);
57 |
58 | setContentView(mReactRootView);
59 | }
60 |
61 | #3.Step by Step:
62 |
63 | 1.Create the ViewManager subclass.
64 |
65 | 2.Annotate the view properties with @UIProp
66 |
67 | 3.Implement the createViewInstance method
68 |
69 | 4.Implement the updateView method
70 |
71 | 5.Register the manager in createViewManagers of the applications package.
72 |
73 | 6.Implement the JavaScript module
74 |
75 | #4.以新增一个自定义Toast为例
76 |
77 |
78 | public class YourToastModule extends ReactContextBaseJavaModule {
79 | private static final String DURATION_SHORT_KEY = "SHORT";
80 |
81 | private static final String DURATION_LONG_KEY = "LONG";
82 |
83 | public AliToastModule(ReactApplicationContext reactContext) {
84 | super(reactContext);
85 | }
86 |
87 | @Override
88 | public String getName() {
89 | return "AliToastAndroid";
90 | }
91 |
92 | @Override
93 | public Map getConstants() {
94 | final Map constants = new HashMap<>();
95 | //JS端可以使用指定NativeModules对象下的属性
96 | constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
97 | constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
98 | return constants;
99 | }
100 |
101 | @ReactMethod
102 | public void show(String message, int duration) {
103 | Toast.makeText(getReactApplicationContext(), message, duration).show();
104 | }
105 | }
106 | 1.继承自ReactContextBaseJavaModule,实现getName用于js前端调用NativeModules.类A,实现含有@ReactMethod的方法用于前端调用类A的xx方法
107 |
108 | public class YourToastModule extends ReactContextBaseJavaModule {
109 | @ReactMethod
110 | public void show(String message, int duration) {
111 | Toast.makeText(getReactApplicationContext(), message, duration).show();
112 | }
113 | 2.在你自定义的packManager中增加你的NativeModule,
114 |
115 | @Override
116 | public List createNativeModules(ReactApplicationContext reactContext) {
117 | List modules = super.createNativeModules(reactContext);
118 | //new an Array intstead of abstract List exception
119 | List result = new ArrayList<>();
120 | result.addAll(modules);
121 | result.add(new YourOpenSomePageModule(reactContext));
122 | result.add(new YourToastModule(reactContext));
123 | return result;
124 | }
125 |
126 | 3.这样就可以在前端调用了,代码如下:
127 |
128 | var React = require('react-native');
129 | var ToastAndroid = React.NativeModules.YourToastModule
130 | ToastAndroid.show('自定义toast 调用成功', ToastAndroid.SHORT);
131 |
132 | #4.最终的自定义组件封装的调用效果如下图所示:
133 |
134 | 1.底部的toast就是通过自定义的React组件显示出来的
135 |
136 | 2.屏幕中的webview也是类似的方法,在JS使用了
137 | 如下代码即可:
138 |
139 | var ToastAndroid = React.NativeModules.MyWebView
140 |
141 | `var AliReactAndroid = React.createClass({});`
142 |
143 |
146 | 
--------------------------------------------------------------------------------
/pics/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/1.jpeg
--------------------------------------------------------------------------------
/pics/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/2.jpeg
--------------------------------------------------------------------------------
/pics/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/3.jpeg
--------------------------------------------------------------------------------
/pics/Screenshot_2015-09-23-12-30-41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/Screenshot_2015-09-23-12-30-41.png
--------------------------------------------------------------------------------
/pics/Screenshot_2015-09-23-16-41-45.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/Screenshot_2015-09-23-16-41-45.png
--------------------------------------------------------------------------------
/pics/Screenshot_2015-10-14-19-51-43.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/Screenshot_2015-10-14-19-51-43.png
--------------------------------------------------------------------------------
/pics/demo-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/demo-list.png
--------------------------------------------------------------------------------
/pics/device-2015-09-21-180925-w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/device-2015-09-21-180925-w.png
--------------------------------------------------------------------------------
/pics/device-2015-09-21-180925.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/device-2015-09-21-180925.png
--------------------------------------------------------------------------------
/pics/flexbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/flexbox.png
--------------------------------------------------------------------------------
/pics/js-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/js-url.png
--------------------------------------------------------------------------------
/pics/jsc-bug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/jsc-bug.png
--------------------------------------------------------------------------------
/pics/nullable duplication.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/nullable duplication.png
--------------------------------------------------------------------------------
/pics/remote-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/remote-url.png
--------------------------------------------------------------------------------
/pics/snap-chrome-plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/snap-chrome-plugin.png
--------------------------------------------------------------------------------
/pics/uiexplorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yipengmu/react-native-android-lession/e685daba04db38ef83da394359c93aac7437adb1/pics/uiexplorer.png
--------------------------------------------------------------------------------
/react-android.bundle.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | */
5 | 'use strict';
6 |
7 | var React = require('react-native');
8 |
9 | var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json'
10 |
11 | var {
12 | AppRegistry,
13 | StyleSheet,
14 | Text,
15 | View,
16 | ListView,
17 | Image,
18 | } = React;
19 |
20 |
21 | var AwesomeProject1 = React.createClass({
22 | render: function() {
23 | return (
24 |
25 |
26 | Welcome to TMall React Native!
27 |
28 |
29 | To get started, edit index.android.js
30 |
31 |
32 | Shake or press menu button for dev menu
33 |
34 |
35 | );
36 | }
37 | });
38 |
39 | var MOCKED_MOVIES_DATA = [
40 | {title: 'Title', year: '2015', posters: {thumbnail: 'http://i.imgur.com/UePbdph.jpg'}},
41 | ];
42 |
43 | var styles = StyleSheet.create({
44 | container: {
45 | flex: 1,
46 | justifyContent: 'center',
47 | flexDirection: 'row',
48 | alignItems: 'center',
49 | backgroundColor: '#F5FCFF',
50 | },
51 | rightContainer: {
52 | flex: 1,
53 | justifyContent: 'center',
54 | alignItems: 'center',
55 | backgroundColor: '#FF0000',
56 | },
57 | thumbnail: {
58 | width: 53,
59 | height: 81,
60 | },
61 | title: {
62 | fontSize: 20,
63 | marginBottom: 8,
64 | textAlign: 'center',
65 | },
66 | year: {
67 | textAlign: 'center',
68 | },
69 | mystyle: {
70 | height:40,
71 | borderWidth: 1,
72 | borderColor: 'red',
73 | },listView: {
74 | paddingTop: 20,
75 | backgroundColor: '#F5FCFF',
76 | }
77 | });
78 |
79 | // var testInnerStyle = React.createClass({
80 |
81 | // render: function(){
82 | // var movie = MOCKED_MOVIES_DATA[0];
83 | // return(
84 | //
85 | //
86 | //
87 | // 文案描述
88 | //
89 | //
90 | // );
91 | // }
92 | // });
93 |
94 |
95 |
96 | var mytest = React.createClass({
97 |
98 | render: function() {
99 |
100 | //
101 | //
102 |
103 | //
104 | //
105 |
106 | //单个远程对象image+textview绘制
107 | // if (!this.state.movies) {
108 | // return this.renderLoadingView();
109 | // }
110 |
111 | // var movie = this.state.movies[0];
112 | // return this.renderMovie(movie);
113 |
114 |
115 | //批量远程对象image+textview绘制
116 | if (!this.state.loaded) {
117 | return this.renderLoadingView();
118 | }
119 |
120 | return (
121 |
126 | );
127 |
128 | // var movie = MOCKED_MOVIES_DATA[0];
129 |
130 | // return (
131 |
132 | //
133 | //
136 |
137 | //
138 | // {movie.title}
139 | // {movie.year}
140 | //
141 | //
142 |
143 |
144 | //
145 | // );
146 | },
147 | getInitialState: function() {
148 | return {
149 | // movies: null,
150 |
151 | //注意此处的return后面跟的是{} 而不是()
152 | dataSource: new ListView.DataSource({
153 | rowHasChanged: (row1, row2) => row1 !== row2,
154 | }),
155 | loaded: false,
156 |
157 | };
158 | },
159 |
160 | componentDidMount: function() {
161 | this.fetchData();
162 | },
163 |
164 | fetchData: function() {
165 | fetch(REQUEST_URL)
166 | .then((response) => response.json())
167 | .then((responseData) => {
168 | this.setState({
169 | //for single
170 | // movies: responseData.movies,
171 |
172 | //for listview
173 | dataSource: this.state.dataSource.cloneWithRows(responseData.movies),
174 | loaded: true,
175 | });
176 | })
177 | .done();
178 | },
179 | renderLoadingView: function() {
180 | return (
181 |
182 |
183 | Loading movies...
184 |
185 |
186 | );
187 | },
188 |
189 | renderMovie: function(movie) {
190 | return (
191 |
192 |
195 |
196 |
197 | {movie.title} tag1
198 | {movie.year}
199 |
200 |
201 | );
202 | },
203 | });
204 |
205 |
206 |
207 |
208 | AppRegistry.registerComponent('AwesomeProject', () => mytest);
209 |
--------------------------------------------------------------------------------
/react-native-android-lession.md:
--------------------------------------------------------------------------------
1 | # react-native-android-lession
2 | ---
3 | > 老穆记录: react native andorid 学习路程
4 |
5 | ---
6 | [关于iOS部分可以参考vczero的lession文章](https://github.com/vczero/react-native-lession)
7 |
8 |
9 | > React-Native 是Android端实现实现动态部署的另一种思路,绕过dexLoad【一些现有的Android插件框架】。
10 |
11 | > 是在开发效率和用户体验间做的一种权衡。
12 |
13 | > React-native使用JS开发,开发效率高、发布能力强。
14 |
15 |
16 | * 1、用编辑器打开对应的.js文件,分析代码结构:
17 |
18 | var React = require('react-native');
19 |
20 | 和Node.js有关,require可以引入其他模块。
21 |
22 | 类似java 的 import com.andorid.xx.Act;
23 |
24 | * 2、定义组件,结构化的代码:
25 |
26 | var {
27 |
28 | AppRegistry,
29 |
30 | StyleSheet,
31 |
32 | Text,
33 |
34 | View,
35 |
36 | } = React;
37 |
38 | * 3、React.createClass里的render方法就是渲染视图用的。return返回的是视图的模板代码。
39 |
40 | * 4、样式表现:那么StyleSheet.create就是干这件事的,只是用JS的自面量表达了css样式。
41 |
42 | * 5、引入css样式:
43 |
44 | 方法1:style={styles.container}
45 |
46 | 方法2:style={{width:20,height:100}}
47 |
48 | * 6、注册View组件,第二个参数为React.createClass创建的 那个var对象
49 |
50 | AppRegistry.registerComponent('aswsome', () => yourVar);
51 |
52 |
53 | #1.环境安装
54 | 1.安装nvm
55 |
56 | * 1.brew install nvm
57 |
58 | 2.nvm 安装最新的 Node.js 4.0
59 |
60 | * nvm install node && nvm alias default node
61 |
62 | 3.安装watchman 和 flow
63 |
64 | * $ brew install watchman
65 | * $ brew install flow
66 |
67 | 并更新brew
68 |
69 | * brew update && brew upgrade
70 |
71 | #2.demo运行
72 |
73 | 首先切换到你想要的目录下,依次执行以下命令
74 |
75 | * $ npm install -g react-native-cli
76 |
77 | * $ react-native init AwesomeProject
78 |
79 | * $ cd AwesomeProject/
80 |
81 | 运行项目
82 |
83 | * $ react-native run-android
84 |
85 | #3.react-android依赖树
86 |
87 | android-jsc-r174650
88 |
89 | appcompat-v7-23.0.0
90 |
91 | bolts-android-1.1.4
92 |
93 | drawee-0.6.1
94 |
95 | fbcore-0.6.1
96 |
97 | fresco-0.6.1
98 |
99 | imagepipeline-0.6.1
100 |
101 | imagepipeline-okhttp-0.6.1
102 |
103 | jackson-core-2.2.3
104 |
105 | jsr305-3.0.0
106 |
107 | library-2.4.0
108 |
109 | okhttp-2.4.0
110 |
111 | okhttp-ws-2.4.0
112 |
113 | okio-1.5.0
114 |
115 | react-native-0.11.0
116 |
117 | support-annotations-23.0.0
118 |
119 | support-v4-23.0.0
120 |
121 |
122 |
123 | #4.从服务端动态拉取配置,并用listview进行展示
124 |
125 | 
126 |
--------------------------------------------------------------------------------