一路追梦想

热爱技术,更热爱生活


  • 首页

  • 关于

  • 标签

  • 归档

React Native接入小米推送

发表于 2018-08-16 | 分类于 ReactNative , Android , iOS

前言

应用接入第三方推送这个需求老板早就提过了,但是因为一方面担心推送用不好效果会适得其反,另一方面因为之前每次版本迭代的需求都比较急,所以接入推送这个事就一直没有完成,最近新版本的Android和iOS都已经上线了,下一版的迭代需求也没有太多,所以自然就把接入第三方推送这个需求放到下一版迭代开发中了。

调研

市面上有很多第三方推送,比如做推送起家的极光,信鸽(腾讯推送),个推。还有一些大公司的推送像友盟,阿里推送,百度推送,腾讯推送(信鸽),还有一些手机厂商自家的推送像小米推送,华为推送,魅族推送等

因为我们的产品是用React Native开发的,所以在调研选取推送之前,除了一些常见的推送硬指标之外,我们还希望能找到有官方支持React Native应用接入的推送。主要是考虑到现在整个客户端就我一个开发人员,Android方面倒是没有问题,iOS如果没有官方文档的话,我怕接入过程会不太顺利,毕竟现在我的iOS水平还很低。。

根据实际情况,看了一下每家的推送,好像就发现一个极光推送有官方支持React Native接入的文档和Demo,本来打算选择极光的。但是,又考察了一些关于推送到达率的这些硬指标之后,又对比了一下我们的产品umeng后台统计的机型数据之后,最终决定接入小米推送。

难点

  • 小米推送并没有官方提供的React Native接入文档或者Demo
  • 推送消息在React Native层面消息收取和分发

尤其是第二个技术难点,我们知道推送接入成功之后,收到推送消息以及用户点击推送消息这些事件的接受都是在Android和iOS的原生层面进行的,如何将消息传递到React Native层面进行消息的处理和页面的跳转是一大难题。

正式开始

下面就讲讲从接入到实现点击消息在React Native层面上跳转的过程吧

阅读全文 »

React Native接入腾讯吐个槽

发表于 2018-08-13 | 分类于 ReactNative , Android , iOS

首先介绍一下什么是吐个槽:

吐个槽是腾讯推出的一款轻量、免费的用户意见反馈服务平台,旨在方便地嵌入APP/微信公众号/QQ公众号,为中小企业或团队快速搭建用户反馈通道,帮助产品提升服务水平和效率。

说白了就是一个方便用户意见反馈的工具,优点就是接入方便,可以通过微信及时提醒。这免去了我们开发App时要自己提供一个意见反馈的功能的麻烦。

腾讯吐个槽的官方网站:吐个槽

React Native接入

官网上的文档针对微信公众号,QQ公众号,Android App,iOS App,WEB,小程序的接入过程说明的都非常详细,也非常简单,但唯独没有React Native App的接入文档,所以接入React Native的时候我是抱着试试的态度看是否能够成功,结果成功了。

找到对应产品的url

腾讯吐个槽接入的原理就是通过webview去加载每个产品对应的唯一的url,那么接入的第一步关键就是找到这个url,url的格式:

1
https://support.qq.com/product/该产品的id

产品的id就是你在后台创建对应的产品之后就可以获取到的

用webview去加载url

在React Native中使用WebView组件去加载对应的产品url,代码如下:

1
2
3
4
5
6
7
8
<WebView
style={{flex: 1}}
javaScriptEnabled={true}
domStorageEnabled={true}
source={{uri: 'https://support.qq.com/product/产品id',
body: postData, method: 'POST'}}
onLoad={() => { this.setState({loading: false}) }}
onError={() => { Toast.show('出错了,情稍后再试') }}/>

这样就完成了吐个槽的接入,是不是很简单,接下来我们可以配置一些参数来统计用户信息

阅读全文 »

使用JavaScripts的Array操作实现RatingBar评分效果

发表于 2018-05-28 | 分类于 ReactNative

最近项目上要做一个点击星星评价的效果,大致设计图如下:

其实看到这个设计图,自己就想GitHub上肯定有挺多基于ReactNative的RatingBar相关的库,Google了一下确实很多,不过想着这么简单的一个东西,完全也没必要用第三方库,自己实现也应该很容易的。虽然我也没看第三方库是怎么实现的,但是自己对于在ReactNative上实现这个RatingBar还是有思路的

思路

最开始是想着新建一个包含有5个初始状态的list,然后通过map函数来绘制出5个没有评级的默认状态,然后用户点击某个星星的时候,通过list下标index来将list里面的index之前的星星替换成评级过的黄色星星,但是这里需要注意的一点就是,因为评级在提交之前是可以随意更改的,所以不能说点击了某个星星之后就把对应index之前的变为黄色的已评价的,毕竟如果用户一开始选择了4颗星,后面又点击选择2颗星,这个时候一方面是把2之前的星星换成黄色,另一方面是把2-4之前的黄色变为默认的白色星星

splice&&slice实现

在说第一种实现方式之前,先了解一下splice和slice的基本用法

splice基本用法

splice主要功能是通过删除现有元素和/或添加新元素来更改一个数组的内容

1
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

start是指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数);若只使用start参数而不使用deleteCount、item,如:array.splice(start) ,表示删除[start,end]的元素。

阅读全文 »

Android多渠道批量打包,支持友盟和第三方加固

发表于 2018-05-08 | 分类于 Android

随着应用上线发布以及不断地迭代,Android平台现在发展到了要打20多个渠道包,打完还要使用第三方加固进行加固,所以每次版本一更新,重新打包加固都成了一个挺耗时的工作,个人也感觉这种重复性的工作挺浪费时间的,所以多渠道打包迫在眉睫。其实早在应用第一版上线的时候,自己就打算把多渠道打包这个功能搞一下,但因为公司现在就我一个移动端开发人员,平时事挺多的,加上一开始渠道包并不算多,所以就一直拖着,现在看到要打这么多渠道包,就想着先放下其他工作,优先把这个搞一下。

看完这篇文章你可以学到的内容大概有:

  • 如何查看是v1还是v2签名,以及如何进行v2签名
  • 在v2签名的情况下,怎么通过不重复打包而批量生成多渠道包
  • 如何实现友盟或者其他第三方统计的多渠道包
  • 使用第三方加固怎么实现多渠道打包

好了,现在开始进入正文:

旧的多渠道打包技术

Android多渠道打包之前在开发其他应用的时候就已经搞过,那个时候主要用了三种方式来实现多渠道打包:

1.通过gradle flavor或者简单的重复脚本(已弃用)

这个相对简单,但是也因为没个渠道包都相当于要编译一遍,所以自然也耗费时间

2.通过apktool反编译,然后替换渠道号

首先,我们先打出一个基准渠道包,然后通过apktool命令反编译基准包:

1
java -jar apktool -f d app.apk

接着在AndroidManifest.xml里面找出<meta-data>,根据特征找出你要修改的umeng或者是takingdata字段的渠道号,然后根据规则替换成你想打的渠道号,
替换完成之后通过apktool重新打包成apk文件:

1
java -jar apktool b app/

最后重新签名就ok了,当然这些步骤都是通过脚本执行的,因为只需要打一个包,剩下的都是脚本来做反编译-替换渠道号-重新打包,所以速度比第一种是有质的提升。而且这种方式还可以解决有些特殊需求,比如有的接入的一些第三方的支付宝会把支付渠道放到assets/config.properties里面,这个时候通过修改一下脚本,AndroidManifest.xml和config.properties里面的都替换,能够很好地解决这种特殊情况,这种需求下第三种方法都是不能处理的

3.解压apk修改,修改META-INF信息

再怎么说,上面那种还是需要反编译,重新编译,重新签名等。这相对来说是有点麻烦而且需要一点时间的,而且因为apktool版本的不同,会导致很多时候反编译失败,总之痛点也还是有的。这个时候自然而然就出现了解决这些痛点的第三种多渠道打包方式。因为实践发现:在apk解压之后的META-INF文件夹中,添加一个空白文件是不会破坏apk的签名的(现在的v2签名针对这种情况做出了调整),所以可以直接在解压之后的META-INF里面来添加一个自定义的渠道文件,然后在代码中动态去获取添加的渠道号
因为这种方式不需要反编译-重新编译-重新签名,所以自然而然比第二种方式会快很多,不过这种对于友盟等等第三方统计的工具的话,就需要在代码中动态获取和注册渠道号了,而不能通过AndroidManifest.xml静态注册了

面临的问题

随着Android各方面技术的不断发展,Google官方在Android7.0的时候推出了v2签名方案,关于v2签名不做重点讲解,贴两张官方的简介图,感兴趣的可以到官方查看v2签名

阅读全文 »

React Native中ScrollView和弹出键盘的冲突

发表于 2018-04-26 | 分类于 ReactNative

最近写的React Native项目中有一个页面是外层ScrollView里面包含一个TextInput输入框,和一个提交按钮,大致结构如下:

1
2
3
4
5
6
7
<ScrollView>
<TextInput>
</TextInput>
<CustomButton>
</CustomButton>
...
</ScrollView>

点击输入框TextInput会弹出软键盘供用户输入内容,输入完成之后点击CustomButton会有后续的提交动作

问题

功能实现很简单,提交测试之后发现被提了一个issue,内容是:

每次输入完内容点击CustomButton提交的时候,都要点击两次才真正提交,点击CustomButton第一次只是会关闭软键盘,第二次才是真正的提交动作,希望能够改为点击一次就完成提交动作

看到这个issue之后,赶紧安装测试了一下,发现真的是每次要提交的时候需要点击两次,一次关闭软键盘,一次提交动作,那既然真有问题,就要解决啊

根据之前多年开发Android的经验,我首先觉得是外层的ScrollView拦截了点击事件,如果软键盘在的话dismiss掉软键盘,同时消费掉了点击事件,不再向下传递。从而导致点击事件在软键盘出现的时候,无法到达CustomButton组件

根据猜想搜索了一下,发现确实有网友遇到这种情况,问题的原因也大致就是我上面的猜想,既然涉及到点击事件传递问题,那么通过组件重写点击事件获取过程中的onStartShouldSetResponderCapture回调是可以达到目的的,这种相对比较复杂,需要对React Native的事件获取-分发-消费有比较清晰和深入的了解,因为这里官方提供了更方便的解决方法,一般情况下就不会选择这种解法了,不过了解ReactNative的事件流程还是有必要的,改天我详细写写ReactNative的事件分化相关的内容

解法

在ScrollView中添加如下属性:

1
2
3
keyboardShouldPersistTaps='handled'
或者
keyboardShouldPersistTaps='always'

如果你的rn版本比较低,那么使用下面的属性:

1
keyboardShouldPersistTaps='true'

这些属性代表什么意思,官方文档说的很清楚,其实无非就是帮我们处理这个点击事件ScrollView拦截还是不拦截,是否允许子组件收到点击事件,文档解释如下:

1
2
3
4
5
6
7
8
keyboardShouldPersistTaps
Determines when the keyboard should stay visible after a tap.

'never': (the default), tapping outside of the focused text input when the keyboard is up dismisses the keyboard. When this happens, children won't receive the tap.
'always': the keyboard will not dismiss automatically, and the scroll view will not catch taps, but children of the scroll view can catch taps.
'handled': the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor).
false: deprecated, use 'never' instead
true: deprecated, use 'always' instead

终于折腾好了

发表于 2018-04-24 | 分类于 Twitter

终于将博客换成hexo+github page了,真的是不折腾会死。。。

iOS不显示LaunchScreen上的图片

发表于 2018-03-06 | 分类于 iOS

因为并没有学习过iOS开发,现在用的react native开发的app,iOS和Android App上的启动屏都是原生代码实现的,现在新版启动屏ui图片有变化,然后技术主管又休假了,只能自己研究研究了。

遇到的问题

大概网上搜索学习了解了一下iOS的项目结构和程序入口,知道了LaunchScreen.storyboard是iOS的启动屏,AppDelegate是程序入口,于是就开始比着葫芦画瓢,将启动屏需要的图片资源添加到Images.scassets里面的splash文件夹里面,每个图片位置按照设计稿调整了一下,看效果图感觉差不多了,就开始跑一下试试,结果启动屏除了设置的背景颜色,上面的图片都没有显示。这就奇怪了,预览图上都有,怎么会不显示。。

如何解决

于是开始google,看来也有很多人遇到这种问题,有的说卸载重新安装就好了,试了没用;有的说把配置里面的Launch Screen File置空,试了还是没用;还有的说是因为Images.xcassets里面的图片应用启动的时候还没有以引用,把图片放到项目根目录就好了,我差点就信这个准备试试了,但是一想之前的图片都在这里面放着都是可以的,肯定不是这个问题,思来想去决定卸载重启试试,重启之后再安装启动,神奇般地显示启动屏上的图片了。。果然是重启大法好啊

JS基础之函数调用的困惑

发表于 2017-09-28 | 分类于 JavaScript

前言

习惯了写java代码,然后开始学习js的时候,一开始总是会被js函数调用搞得有点晕乎,觉得有必要搞清楚js中函数调用不同的写法的一些含义和区别

js中的函数

要搞清楚js中函数调用为什么会这样,首先需要明白js中的一个概念,那就是:函数是JavaScript中的「一等公民」(Function is first-class citizen)。
当你能够传递,返回和分配某个类型的时,那这个类型就被称为”一等公民”,js中的函数恰好就满足这些条件,所以js中的函数被称为是”一等公民”。
好了,不管js中函数是几等公民了,直接上代码来解决疑惑吧,假设我们页面中有一个按钮,点击的时候调用函数打印Hello World,函数代码如下:

1
2
3
function hello(){
document.write('Hello World');
}

看起来这段代码规规矩矩,没有什么问题,然后我们希望在一个组件被按压的时候调用这个函数,通常习惯了Java中函数调用的,可能顺手就是:onPress = hello();这对于习惯了java的人来说,可能觉得再普通不过了,但是对于js来说是有问题的。

阅读全文 »

React Native基础之箭头函数

发表于 2017-09-26 | 分类于 ReactNative

前言

我们知道ES6允许使用“箭头”(=>)定义函数,习惯Java中函数定义之后,刚开始接触js,每次看到箭头函数都感觉怪怪的,那么为什么ES6要引入箭头函数呢,这个问题也一直困扰这我,虽然只要明白了箭头函数的语法,基本就可以正常的学习rn,使用rn开始开发,但是有些东西搞不清楚,心里头就感觉不踏实,今天咨询了一下做前后端开发的大学室友,才稍微明白了一点

引入箭头函数的原因

  1. 更简短的函数书写
  2. 对this的词法解析

更简短的函数书写

1
2
3
4
5
6
// 正常函数写法
[1,2,3].map(function (x) {
return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);

上面的箭头函数的第二种写法里面的x => x * x是等价于(x) => {return x * x},一个参数的时候小括号可以省略,后面的大括号如果省略的话,代表是一个隐式的返回值,具体这个箭头函数的语法可以看前一篇基础总结里面有提到

阅读全文 »

React Native基础之调用Android本地方法

发表于 2017-09-18 | 分类于 Android , React Native

前言

学习了一周React native之后,感觉还挺有意思的,今天来说说通过React native调用Android平台的一些本地方法(API),以我目前的水平,感觉这个功能可能平时用的不会太多,但我感觉通过React native开发Android应用的过程中肯定会有用到的时候,本文以调用Android平台的Toast为例来讲讲如何通过React native调用Android
原生的一些方法(API)。

下面开始项目从创建到运行成功的全过程

创建项目

1
react-native init CallNativeToast

创建一个NativeModule

本地模块一般是继承ReactContextBaseJavaModule的Java类,然后实现React native(js)调用Android本地API所需的功能,我们这次目标是通过js调用Android来展示一个Toast,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ToastExample";
}
@Nullable
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}

有几点需要说明:

阅读全文 »
12…7
picksomething

picksomething

专注Android,Java,RN,Python

65 日志
17 分类
148 标签
RSS
© 2018 PICKSOMETHING
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4