【iOS&Android】RN学习3——集成进现有原生项目

在做了短暂的技术调研和分析之后,我决心将RN和现有的QDaily项目进行集成,并替换掉其中的广告效果展示页面。

本文开发环境为Mac,在React Native 版本为0.30。同时RN仅仅作为插件形势集成到原有Native工程中,因此主要还是一个Native工程而非RN工程

而且,本文的前提是你已经在本地配好了iOS开发环境或Android开发环境,也就是说,你起码已经是一个Android开发者或者iOS开发者。

一、必备的环境配置

先安装node.js,可以下载pkg包,也可以命令行安装:

brew install node

然后安装React Native的命令行工具(react-native-cli)

npm install -g react-native-cli

这样,最重要的东西就安装好了,其它东西都可以自己看个人情况酌情使用。此处出现任何问题,都可以直接官网或者stackoverflow。

阅读更多

【Android&iOS】QDaily基于WebP的流量优化实践

本文属于“好奇心日报app的流量和文章打开速度优化”系列文章第一篇,主要介绍基于图片压缩的流量优化。
流量优化对于一个app来讲意义非常重大,能节约用户的流量,节约用户的存储空间,而且能有提高网络请求的回包速度,提高app的速度。因此流量优化历来都是app的优化重点,而且是一个持续优化的点。

QDaily是一个多图片的新闻类应用,采编喜欢上传gif图来提高内容的表现力,这也使得流量消耗非常大。粗略估计,用户在浏览完第一页所有新闻(共48篇),会消耗流量达100m,其中98m为图片,这里值得优化的空间非常大。

针对这种情况,我们先后使用的优化包含:wifi条件下预载所有文章、图片和js、css数据;重用所有已经下载的js、css和图片的缓存;后台图片的压缩以及客户端图片的WebP化。

其中,后台压缩和WebP化依赖第三方多媒体处理服务器,已知比较好的国内服务有腾讯优图和七牛。这里我们采用的七牛的服务,以下很多具体的调用都是基于七牛的。

我们的后台通过七牛的图片压缩(包含质量和分辨率),我们将首页流量由100m减少到了80m,依然有极大的提升空间。因此客户端采用基于WebP的流量压缩方案,将流量由80m压缩到了20m,减少了75%!相对于最初的处理,流量减少了80%!(android大多数机型支持WebP animated,压缩能达到80%,但iOS的压缩率取决于首页中gif图的个数和大小,测试大概优化在60%-80%之间)

下面就介绍下这个效果极好的WebP的流量解决方案。

阅读更多

每日阅读20160726

本月事情多,师妹的好多事情,还有开发工作。深刻研究了RN的使用,并应用在实践中;极限的流量优化,将QDaily客户端的消耗流量减少了75%。这些都开始囤积文章,稍后慢慢分享出来。

水一些本月学习的东西

1、React-Native For Android 环境搭建及踩坑

android引入RN的基础知识。

2、用 Jenkins 搭建 iOS/Android 持续集成打包平台

已经在本机上进行的使用,未来会在编译服务器部署。

阅读更多

React Native 0.30 Android出现Didn't find class "com.facebook.jni.IteratorHelper"错误

React Native 0.30 Android出现Didn’t find class “com.facebook.jni.IteratorHelper”错误

错误堆栈及解决办法

错误堆栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
E/unknown:React( 7231): Exception in native call from JS
E/unknown:React( 7231): java.lang.ClassNotFoundException: Didn't find class "com.facebook.jni.IteratorHelper" on path: DexPathList[[zip file "/data/app/com.silklabs.bla.example-1/base.apk"],nativeLibraryDirectories=[/data/app/com.silklabs.bla.example-1/lib/x86, /vendor/lib, /system/lib]]
E/unknown:React( 7231): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
E/unknown:React( 7231): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
E/unknown:React( 7231): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.ModuleRegistryHolder.initHybrid(Native Method)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.ModuleRegistryHolder.<init>(ModuleRegistryHolder.java:26)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.NativeModuleRegistry.getModuleRegistryHolder(NativeModuleRegistry.java:63)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:106)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:50)
E/unknown:React( 7231): at com.facebook.react.cxxbridge.CatalystInstanceImpl$Builder.build(CatalystInstanceImpl.java:484)
E/unknown:React( 7231): at com.facebook.react.XReactInstanceManagerImpl.createReactContext(XReactInstanceManagerImpl.java:860)
E/unknown:React( 7231): at com.facebook.react.XReactInstanceManagerImpl.access$600(XReactInstanceManagerImpl.java:103)
E/unknown:React( 7231): at com.facebook.react.XReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(XReactInstanceManagerImpl.java:203)
E/unknown:React( 7231): at com.facebook.react.XReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(XReactInstanceManagerImpl.java:182)
E/unknown:React( 7231): at android.os.AsyncTask$2.call(AsyncTask.java:292)
E/unknown:React( 7231): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
E/unknown:React( 7231): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
E/unknown:React( 7231): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/unknown:React( 7231): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/unknown:React( 7231): at java.lang.Thread.run(Thread.java:818)
E/unknown:React( 7231): Suppressed: java.lang.ClassNotFoundException: com.facebook.jni.IteratorHelper
E/unknown:React( 7231): at java.lang.Class.classForName(Native Method)
E/unknown:React( 7231): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
E/unknown:React( 7231): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
E/unknown:React( 7231): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
E/unknown:React( 7231): ... 17 more
E/unknown:React( 7231): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

解决办法

在初始化ReactInstanceManager中,增加build方法 .setUseOldBridge(true) 即可。

错误原因

com.facebook.jni.IteratorHelper 为 0.31-rc 的class,暂时不能使用。facebook又把半成品给小白鼠体验了

每日阅读20160627-30

这几天先用swift把一键上传七牛的代码写好了,学着了一些osx的开发技巧,oc swfit的混编,swift的闭包,还有swift最让新用户崩溃的半弱类型(? or !)。

1、Swift 范的 CGRect、CGSize 和 CGPoint

先来个轻松的。规范下swift的书写,看完不累,而且貌似有些收获。程序员要有代码洁癖。

一个小技巧,之前用scheme也达到了类似的效果,不过没有这么彻底。主要区分在预编译指令这里的区别。不过对于跳转的app url scheme在修改了bundleid后会出现问题。例如跳转微信授权和分享后会,会回不到当前app。大多时候都是很方便的。

阅读更多

使用iOS APP的Build Configuration区分开发和生产环境

前两天看文章使用 Xcode 的 Target 区分开发和生产环境,感觉这个虽然是一种区分开发和生产环境比较强大的方法,但也有比较轻量级的,下面就分享下QDaily采用的配置Build Configuration方案。

区分测试环境和生产环境的上面的链接已经说了:区分统计数据、区分crash log、区分server地址、区分本地数据库…

每个工程默认会有两个Build Configure,即debug和release,我们就在这里做文章,增加一个releaseBeta版本,用来打包内部测试环境版本。

QDaily在这里主要区分了app name,app icon,app bundleId(测试推送),并增加了一个全局的预处理宏BETA,代码中通过BETA标志进行和DEBUG相似的处理

阅读更多

移动端开发好文20160626

1、Android App 不死之路

软件开发者要有自己的节操,有时候为了推送需要,有一个非常小的进程常驻后台还可以接受。国内安卓生态就是被这种自以为nb的开发毁掉的。
不过技术本身没有错,可以看看底层实现。不过这类技术可用性不高。

2、ES6 有什么新东西?

RN开发的基础知识储备。读了这篇文章,感觉模板字符串语法,胖剪头语法和class的引入这3处很有意思,值得关注;对map和array的遍历让我对js这个语法感觉充满了神奇…

还有,需要更多的理解其中this关键字的可用位置。。。要继续持续关注!

3、逃离北上广,我们过得不好,但也不坏

分享个非技术类的,庆幸我在互联网行业。庆幸我过得很好,要心存感恩

4、预告个自己写的Mac小程序

一键上传到七牛,便于在纯文本的markdown上加图片。先看gif,整理好了会分享出来的。

移动端开发好文20160625

周六,放松下,没看几篇文章。最近写博客传图很麻烦,今天写了一个Mac端的小程序,简单传图到qiniu上。下周写好了我传到github上,然后写个文章介绍下。

1、微信Android热补丁实践演进之路

微信终端开发中心的另一篇好文,业界已经传遍了。

微信出品,都是长文,都是竞品。算是给所有还在做android热修复的朋友一个指明。个人之前用过andfix,感觉兼容性很差,给版本提高了1%的crash率,很伤心。微信还挺推崇Nuwa的,看来可以尝试一下。

文章底部的参考文章很详尽,想了解学习android hotfix的同学算是找到所以呢地图了。

2、2016:iOS开发趋势思考

阅读更多

移动端开发好文20160624

个人发现在看公众号或者博客的文章会有问题,就是会留在自己的舒适区域,只看自己想看的那一部分,导致收获会越来越少,有空还是要读书,系统性的学习。

1、Android性能调优利器StrictMode

android性能调优第一步。打开严格模式和内存泄露检查。严格模式的用法值得学习,不过它检测能力还比较存疑,针对ANR的处理应该不错,不过对FPS的提升应该帮助不大。

预计第二步是Leak检查,这样可以有效的缓解内存峰值问题.
再之后是UI优化和FPS优化

阅读更多