背景

一款轻阅读应用ReadIT,支持功能:优质文章推送、评论点赞、计划制定、计划闹钟、天气预报、收藏文章、深浅两套主题、多语言切换、极光推送等功能。后续还会继续集成功能。前后端均自主研发,借鉴市面较好的种子工程,目前未上应用市场,文章目前也比较少,后续会持续补充优质文章。

展示效果

点我

下载体验(目前只有安卓版)

Github

https://github.com/xiaobinwu/readIt

技能树

1、客户端(react-native、@react-navigation、react-native第三方库、typescript、mobx、marked等技术)

2、中台后管系统(antd4、react、redux、react-router4、hook等技术)

3、后端程序(koa、mongoDb、jsonwebtoken、ali-oss等技术)

react-devtools调试(安卓模拟器)

1、开发者菜单中选择"Debug JS Remotely"选项

2、自动打开调试页面 http://localhost:8081/debugger-ui(可做断点调试)

3、打开有异常时暂停(Pause On Caught Exceptions)选项,能够获得更好的开发体验

4、设置环境变量ELECTRON_MIRROR='https://npm.taobao.org/mirrors/electron/',防止下载react-devtool卡住

5、安装react-devtools,package.json配置npm script,执行npm run react-devtools

6、执行adb reverse tcp:8097 tcp:8097

7、目前react-native => 0.61.5,react-devtool => 3.6.3

8、参考资料:参考资料

注意:react-devtools v4 需要 react-native 0.62 或更高版本才能正常工作。一升级就报错,后续跟进

iconfont字体图标使用

1、下载Iconfont字体图标项目,下载至本地,获取iconfont.ttf

2、放至src/assets/fonts目录

3、配置react-native.config.js,参考资料,如下:

    module.exports = {
project: {
ios: {},
android: {}, // grouped into "project"
},
assets: ["./src/assets/fonts/"], // stays the same
};

4、运行npm run link,将对应iconfont.ttf分别添加至iOSInfo.plistFonts provided by application下添加一行iconfont.ttf)、Android(复制至app/src/main/assets/fonts文件夹中,并且app/src/build.gradle添加配置)

5、将iconfont.json复制至src/components/common/iconfont

6、字体图标封装可参考第4步目录相对应组件文件

7、参考资料:参考资料

tsconfig.json配置

1、详细各个配置项解析,可查看tsconfig.json

2、配置paths,结果不起效,需在src目录添加package.json,配置如下

{
"name": "@app"
}

第三方库

1、autobind-decorator => 自动将方法绑定到类实例,针对babel7需额外配置插件,如下:

    {
plugins: ["@babel/plugin-proposal-decorators", { legacy: true }]
}

2、mobx / mobx-react => 简单、可扩展的状态管理,前往

3、@react-navigation/bottom-tabs / @react-navigation/native / @react-navigation/stack => 跨平台导航方案,前往

4、react-native-appearance => 在iOS,Android和Web上访问操作系统外观信息。目前支持检测首选配色方案(浅色/深色),前往

5、react-native-localize => 用于React Native应用本地化的工具箱,前往

6、@react-native-community/async-storage => 简单的、异步的、持久化的 Key-Value 存储系统,前往

7、react-native-actionsheet => 跨平台ActionSheet,前往

8、react-native-webview => WebView,旨在替代内置WebView,前往

9、marked => markdown编译器,前往

10、highlight.js => 代码高亮工具,前往

11、react-native-autoheight-webview => React Native的自动高度webview,前往

12、react-native-image-viewing => 图片滑动浏览控件,前往

13、react-native-root-toast => 吐司控件,前往

14、react-native-calendars => 日历,前往

15、jcore-react-nativejpush-react-native => 极光推送

16、react-native-alarm-clock => 闹钟,前往

17、react-native-amap-geolocation => 高德地址服务,前往

18、 react-native-device-info => 获取设备信息,前往

19、 react-native-image-picker => 上传图片,前往

20、react-native-modal-datetime-picker => 时间选择器,前往

21、react-native-picker-select => 下拉框选择器,前往

22、react-native-splash-screen => 应用启动图,前往

第三方库躺坑

如何获取当前天气、未来三天天气?

使用的是和风天气API,需要经纬入参,所以必须先获取位置,需要申请和风天气的appKey。

推送服务

极光推送服务 jcore-react-nativejpush-react-native,需要申请AppKey。

如何获取位置?

Part1,使用react-native-geolocation-service第三方库,获取经纬度进行高德逆地理编码API调用,获取城市,开启google play服务,需要有处理获取位置的服务程序app/services/location(参考react-native-geolocation-service github example),以及修改android/app/src/main/AndroidManifest.xml,添加<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 安卓添加权限。结果不行,针对google play服务国内不能使用,所以该方案得摒弃掉,对应app/services/location会删除。

Part2,使用react-native-amap-geolocation第三方库,接口文档使用指南

图片上传问题

对于react-native-image-picker第三方库, 对于3.1.4版本,minSdkVersion最少要21以上,在使用的react-native 0.61.5下,修改android/build.gradleminSdkVersion配置

阿里oss aliyun-oss-rn,需要更改aliyun-oss-rn npm包的android/build.gradle(如下配置),提高SDK版本号,以及修改主项目AndroidManifest.xml,添加android:allowBackup="true",目前使用上仍有问题,于是放弃该方案,改用oss postObject直传方式,参考资料,使用sts临时授权、policy、Signature配合上传。

buildscript {
repositories {
jcenter()
} dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
} apply plugin: 'com.android.library' android {
compileSdkVersion 28
buildToolsVersion '28.0.3' defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
} repositories {
mavenCentral()
} dependencies {
implementation 'com.facebook.react:react-native:+'
implementation 'com.aliyun.dpa:oss-android-sdk:+'
}

日历问题

react-native-calendarsAgenda问题如下:

一、国际化切换、主题切换时,日历没有对应切换,对应HACK处理方法,给Agenda组件设置key,强制组件卸载,重新加载

二、Agenda在国际化切换、主题切换、添加日程的时候,会导致Agenda组件内部View组件onLayout重复触发(我是不需要其一直触发),导致this.viewHeight一直发生变化,导致每次动画执行定位不准问题,处理方法,用个变量存储this.viewHeight,示例代码如下:

let VIEW_HEIGHT = 0;

constructor(props) {
this.viewHeight = VIEW_HEIGHT || windowSize.height;
} onLayout = event => {
if (!VIEW_HEIGHT) {
VIEW_HEIGHT = event.nativeEvent.layout.height;
this.viewHeight = event.nativeEvent.layout.height;
this.viewWidth = event.nativeEvent.layout.width;
this.forceUpdate();
}
};

三、日程列表改造,只显示当前选中日期的的日程,Agenda组件代码改造如下:


renderReservations() {
const reservationListProps = extractComponentProps(ReservationList, this.props);
let reservations = {};
const { items } = this.props;
if (this.props.selected && items[this.props.selected.dateString]) {
reservations = { [this.props.selected.dateString]: items[this.props.selected.dateString] };
}
console.log(this.props.selected, '选中的时间'); return (
<ReservationList
{...reservationListProps}
ref={c => (this.list = c)}
reservations={reservations}
selectedDay={this.state.selectedDay}
topDay={this.state.topDay}
onDayChange={this.onDayChange}
onScroll={() => {}}
/>
);
}

闹钟问题

react-native-alarm-clock,目前yarn、npm均不能下载1.0.0,只能将2.0.0版本下载至本地,替换node_moudules中的对应npm包,功能使用还未考证,仍有问题。

选择下拉框问题

react-native-picker-select,报错信息 "RNCAndroidDialogPicker" was not found in the UIManager,参考Issues,解决办法,降级@react-native-picker/picker1.8.3

打包 APK 问题

管理员CMD,参考

#keytool -genkey -dname "CN=wushaobin,OU=个人,O=个人,L=深圳,ST=广东,C=CN" -alias test -keyalg RSA -validity 400000 -keystore test.keystore
#keytool -importkeystore -srckeystore test.keystore -destkeystore test.keystore -deststoretype pkcs12
#keytool -list -v -keystore test.keystore -storepass xxxxxxxxx
或 keytool -genkeypair -v -keystore test.keystore -alias test -keyalg RSA -keysize 2048 -validity 400000

app应用启动图

1、下载react-native-splash-screen

2、android/app/src/main/java/com/readit/MainActivity.java,配置如下:

import com.facebook.react.ReactActivity;

+ import org.devio.rn.splashscreen.SplashScreen;
+ import android.os.Bundle; public class MainActivity extends ReactActivity { /**
@@ -12,4 +15,11 @@
protected String getMainComponentName() {
return "readIt";
} // 添加下面方法
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ SplashScreen.show(this); // here
+ super.onCreate(savedInstanceState);
+ }
}

3、android/app/src/main/res/layout/launch_screen.xml配置如下(没有就添加):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/launch_screen" android:scaleType="centerCrop" />
</LinearLayout>

4、android/app/src/main/res/values/styles.xml配置如下:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:textColor">#000000</item>
+ <!--添加这一行-->
+ <item name="android:windowIsTranslucent">true</item>
</style>

5、使用如下:

import SplashScreen from 'react-native-splash-screen';

...

componentDidMount() {
SplashScreen.hide();
}

app应用图标问题

替换android/app/src/main/res/mipmap-*文件夹中图标图片

./gradlew assembleRelease失败问题

1、先执行./gradlew clean,卸载上一个debug版本

2、再执行./gradlew assembleRelease,生成release版本

常用指令 ./gradlew clean./gradlew build

编译错误:The Kotlin Gradle plugin was loaded multiple times in different subprojects, which is not supported and may break the build. 问题解决方案:

参考: https://forums.expo.io/t/kotlin-error-when-build-or-install/38868

./gradlew assembleRelease 编译失败

失败信息: Error: ENOENT: no such file or directory, open 'F:\Project\reactnative\readIt\android\app\build\generated\sourcemaps\react\release\index.android.bundle.map'

问题解决方案:

参考: https://stackoverflow.com/questions/56808518/android-gradlew-assemblerelease-sourcemap-output-fail-because-bundle-doesnt-e

发布版本时,删除build/debug.apk,执行./gradlew clean

React Native Android9.0以上打包apk后http请求不到解决方法

参考资料

最新文章

  1. ubuntu 加载新硬盘或分区
  2. CSS Sprite雪碧图应用
  3. 关于怎样解决eclipse打开时出现的Failed to load the JNIshared library亲测有效
  4. 数据结构之链表、栈和队列 java代码实现
  5. C# 类型参数的约束
  6. Linux基础 30分钟GDB调试快速突破
  7. 从3D Studio Max导入物体 Importing Objects From 3D Studio Max
  8. ESP8266 TCP传输AT指令顺序
  9. PHP PhantomJs中文文档(翻译)
  10. python退格、方向键无法正常使用解决方法
  11. 简易RPC框架-客户端限流配置
  12. Python学习笔记六
  13. form表单序列化为json格式数据
  14. C#零基础入门03:打老鼠初级
  15. 在已配置成功的opencv3.2.0下配置opencv_contrib模块
  16. 重构指南 - 封装条件(Encapsulate Conditional)
  17. MEF教程
  18. (转)2017年最新企业面试题之shell(一,二)
  19. Uva 11235 RMQ问题
  20. squid cache 服务器端的安装,配置

热门文章

  1. How to use JavaScript to implement precise setTimeout and setInterval
  2. Frameworkless Movement
  3. vscode &amp; ignore .idea
  4. Service Worker in Action
  5. Flutter: MediaQuery
  6. HDFS 01 - HDFS是什么?它的适用场景有哪些?它的架构是什么?
  7. 漫画 | C语言哭了,过年回家,只有我还没对象
  8. 02.描述统计 (descriptive statistics)
  9. [Python] 茎叶图和复合饼图的画法
  10. AForge实现拍照