Peterfei

上主是我的牧者,我实在一无所缺


  • 首页

  • 归档

  • 标签

ReactNative之Realm预加载数据

发表于 2019-04-11   |   分类于 前端   |  

realm 数据预加载

Require Env:
1
2
3
npm i realm
npm i react-native-fs
react-native link

分别拷贝数据库至原生公用目录

Android端

android/app/src/main/assets/demo.realm

IOS端

Build Phases->Copy Bundle Resources->demo.realm

前端

执行Realm 提供的copyBundledRealmFiles,可以将共用的数据库文件拷贝至应用安装的Documents目录.

Realm.copyBundledRealmFiles();

实例
prepare-realm-data-demo

记IOS开发之我是如何解决react-native-unity-view插件在Product模式闪退

发表于 2019-04-10   |   分类于 IOS   |  

事件起因:

公司在使用react-native开发解剖3D软件,需要和unity进行融合,在组件选择上,使用了react-native-unity-view这款插件,在融合过程中,踩了很多坑,花费精力最大的,是年后IOS升级为12.1后,集成方案集中出现闪退.

Issue #79

iOS crashes on launch in release builds only #79

Cash log 如下

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
29
30
31
32
33
34
35
36
37
38
39
40
41
Thread 7 name: com.facebook.react.JavaScript
Thread 7 Crashed:
0 libsystem_kernel.dylib 0x00000001fbbbd104 __pthread_kill + 8
1 libsystem_pthread.dylib 0x00000001fbc3ca00 pthread_kill$VARIANT$armv81 + 296
2 libsystem_c.dylib 0x00000001fbb14d78 abort + 140
3 libsystem_malloc.dylib 0x00000001fbc11768 _malloc_put + 0
4 libsystem_malloc.dylib 0x00000001fbc11924 malloc_report + 64
5 libsystem_malloc.dylib 0x00000001fbc042d0 free + 376
6 libc++.1.dylib 0x00000001fb1bf120 std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string+ 258336 () + 32
7 UnityTest 0x0000000102de23a4 std::__1::__vector_base<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::~__vector_base() + 730020 (vector:451)
8 UnityTest 0x0000000103385214 facebook::react::ModuleRegistry::getConfig+ 6640148 (std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 100
9 UnityTest 0x0000000103394168 facebook::react::JSCNativeModules::createModule+ 6701416 (std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, OpaqueJSContext const*) + 292
10 UnityTest 0x0000000103393cc8 facebook::react::JSCNativeModules::getModule+ 6700232 (OpaqueJSContext const*, OpaqueJSString*) + 188
11 UnityTest 0x000000010338e85c OpaqueJSValue const* (*facebook::react::(anonymous namespace)::exceptionWrapMethod<&(facebook::react::JSCExecutor::getNativeModule(OpaqueJSValue*, OpaqueJSString*))>())(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSString*, OpaqueJSValue const**)::funcWrapper::call+ 6678620 (OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSString*, OpaqueJSValue const**) + 104
12 JavaScriptCore 0x0000000203350404 JSC::JSCallbackObject<JSC::JSDestructibleObject>::getOwnPropertySlot+ 574468 (JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&) + 340
13 JavaScriptCore 0x0000000203a354f0 llint_slow_path_get_by_id + 2008
14 JavaScriptCore 0x0000000203328928 llint_entry + 11528
15 JavaScriptCore 0x000000020332d134 llint_entry + 29972
16 JavaScriptCore 0x000000020332d134 llint_entry + 29972
17 JavaScriptCore 0x000000020332d134 llint_entry + 29972
18 JavaScriptCore 0x000000020332d134 llint_entry + 29972
19 JavaScriptCore 0x000000020332d134 llint_entry + 29972
20 JavaScriptCore 0x0000000203325a1c vmEntryToJavaScript + 300
21 JavaScriptCore 0x000000020399bfe4 JSC::Interpreter::executeProgram+ 7176164 (JSC::SourceCode const&, JSC::ExecState*, JSC::JSObject*) + 9620
22 JavaScriptCore 0x0000000203b77218 JSC::evaluate+ 9122328 (JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 316
23 JavaScriptCore 0x000000020334e634 JSEvaluateScript + 472
24 UnityTest 0x000000010336dad0 facebook::react::evaluateScript+ 6544080 (OpaqueJSContext const*, OpaqueJSString*, OpaqueJSString*) + 80
25 UnityTest 0x000000010338c918 facebook::react::JSCExecutor::loadApplicationScript+ 6670616 (std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) + 528
26 UnityTest 0x0000000103392ba4 std::__1::__function::__func<facebook::react::NativeToJsBridge::loadApplication(std::__1::unique_ptr<facebook::react::RAMBundleRegistry, std::__1::default_delete<facebook::react::RAMBundleRegistry> >, std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_0, std::__1::allocator<facebook::react::NativeToJsBridge::loadApplication(std::__1::unique_ptr<facebook::react::RAMBundleRegistry, std::__1::default_delete<facebook::react::RAMBundleRegistry> >, std::__1::unique_ptr<facebook::react::JSBigString const, std::__1::default_delete<facebook::react::JSBigString const> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)::$_0>, void (facebook::react::JSExecutor*)>::operator()+ 6695844 (facebook::react::JSExecutor*&&) + 144
27 UnityTest 0x0000000103393ba8 std::__1::function<void (facebook::react::JSExecutor*)>::operator()+ 6699944 (facebook::react::JSExecutor*) const + 40
28 UnityTest 0x000000010330c9cc facebook::react::tryAndReturnError(std::__1::function<void + 6146508 ()> const&) + 24
29 UnityTest 0x0000000103302528 facebook::react::RCTMessageThread::tryFunc(std::__1::function<void + 6104360 ()> const&) + 24
30 CoreFoundation 0x00000001fbfb6408 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20
31 CoreFoundation 0x00000001fbfb5d08 __CFRunLoopDoBlocks + 272
32 CoreFoundation 0x00000001fbfb1220 __CFRunLoopRun + 2376
33 CoreFoundation 0x00000001fbfb05b8 CFRunLoopRunSpecific + 436
34 UnityTest 0x00000001032e36a4 +[RCTCxxBridge runRunLoop] + 264
35 Foundation 0x00000001fcad73b0 __NSThread__start__ + 1040
36 libsystem_pthread.dylib 0x00000001fbc412fc _pthread_body + 128
37 libsystem_pthread.dylib 0x00000001fbc4125c _pthread_start + 48
38 libsystem_pthread.dylib 0x00000001fbc44d08 thread_start + 4
最初的解决方案
  • 升级react-native版本到0.57.0
  • rm -fr node_modules
  • 升级插件版本react-native-unity-view": "^1.2.1"
  • 在Xcode里Setting "Strip Linked Product" to NO

成功阻止了编译闪退,但发布后被审核告知闪退.来来回回几次后,终于重新测试发现,居然是打包为release IPA file后才开始闪退-_-!!

再次尝试

之后在issue里提问回帖,得到如下方案:

在配置文件里加入

1
2
3
COPY_PHASE_STRIP = YES;
ENABLE_BITCODE = NO;
STRIP_INSTALLED_PRODUCT = NO;

之后在测试机上运行,没有闪退.于是提交审核,发布了版本.之后有用户反馈在IPHONE XS Max上闪退 -_-!!!

最后的尝试

之后继续回帖,在 JanOwiesniak和mtostenson 的建议下,进行如下改动:

  • using XCodes new build system or the legacy build system
  • Reinstall node_modues
  • Update Unity from 2018.2.14f1 to 2018.3.6f1
  • Build UnityExport
  • Patch UnityExport jiulongw/swift-unity#120 (comment) #79 (comment)
  • Update react-native-unity-view to 1.3.3
  • Update react-native to 0.57+
  • Patch react-native moduleNames() (#79 (comment)
  • Add AVKit.framework in Xcode
最终成功解决iphone xs max 12.1兼容

使用WPF加载Unity可执行程序

发表于 2019-04-09   |   分类于 WPF   |  

公司有开发wpf需求,模型主要是由Unity开发,导出后是.exe可执行程序,
外层是利用react-native编写界面,主要组件为react-native-windows,于是需要融合二者.
首先是写入wpf调用外部exe组件:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace Vesal_PC
{
// GameHost is a FrameworkElement and can be added to controls like so:
// var gameHost = new GameHost(container.ActualWidth, container.ActualHeight);
// container.Child = gameHost;
//
// Sources:
// - https://msdn.microsoft.com/en-us/library/ms752055.aspx
// - Another source I can't remember or find, concerning running a standalone Unity process using parentHWND parameter
internal class GameHost : HwndHost
{
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const int HOST_ID = 0x00000002;
private IntPtr hwndHost;
private int hostHeight, hostWidth;
private Process process;
private IntPtr unityHWND = IntPtr.Zero;
private const int WM_ACTIVATE = 0x0006;
private readonly IntPtr WA_ACTIVE = new IntPtr(1);
private readonly IntPtr WA_INACTIVE = new IntPtr(0);
public GameHost(double width, double height)
{
hostHeight = (int)height;
hostWidth = (int)width;
}
protected override HandleRef BuildWindowCore(HandleRef hwndParent)
{
hwndHost = IntPtr.Zero;
hwndHost = CreateWindowEx(0, "static", "",
WS_CHILD | WS_VISIBLE,
0, 0,
hostWidth, hostHeight,
hwndParent.Handle,
(IntPtr)HOST_ID,
IntPtr.Zero,
0);
{
try
{
process = new Process();
process.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "win/vesal.exe";
process.StartInfo.Arguments = "-parentHWND " + hwndHost.ToInt32() + " " + Environment.CommandLine;
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForInputIdle();
// Doesn't work for some reason ?!
//unityHWND = process.MainWindowHandle;
EnumChildWindows(hwndHost, WindowEnum, IntPtr.Zero);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "GameHost: Could not find game executable.");
}
}
return new HandleRef(this, hwndHost);
}
protected override void DestroyWindowCore(HandleRef hwnd)
{
try
{
process.CloseMainWindow();
System.Threading.Thread.Sleep(1000);
while (process.HasExited == false)
process.Kill();
}
catch (Exception)
{
}
DestroyWindow(hwnd.Handle);
}
private void ActivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
}
private void DeactivateUnityWindow()
{
SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
}
protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
handled = false;
return IntPtr.Zero;
}
private int WindowEnum(IntPtr hwnd, IntPtr lparam)
{
unityHWND = hwnd;
ActivateUnityWindow();
return 0;
}
//PInvoke declarations
[DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)]
internal static extern IntPtr CreateWindowEx(int dwExStyle,
string lpszClassName,
string lpszWindowName,
int style,
int x, int y,
int width, int height,
IntPtr hwndParent,
IntPtr hMenu,
IntPtr hInst,
[MarshalAs(UnmanagedType.AsAny)] object pvParam);
[DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)]
internal static extern bool DestroyWindow(IntPtr hwnd);
[DllImport("User32.dll")]
static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
}
}

编写react-native UnityView组件:

ReactUnityManager.cs

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) Microsoft Corporation. All rights reserved.
// Portions derived from React Native:
// Copyright (c) 2015-present, Facebook, Inc.
// Licensed under the MIT License.
using Newtonsoft.Json.Linq;
using ReactNative.Collections;
using ReactNative.Modules.Image;
using ReactNative.UIManager;
using ReactNative.UIManager.Annotations;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Controls;
namespace Vesal_PC
{
/// <summary>
/// The view manager responsible for rendering native images.
/// </summary>
public class ReactUnityManager : SimpleViewManager<Border>
{
private readonly ConcurrentDictionary<Border, List<KeyValuePair<string, double>>> _imageSources =
new ConcurrentDictionary<Border, List<KeyValuePair<string, double>>>();
Border view;
/// <summary>
/// The view manager name.
/// </summary>
public override string Name
{
get
{
return "RCTUnityView";
}
}
/// <summary>
/// The view manager event constants.
/// </summary>
public override JObject CustomDirectEventTypeConstants
{
get
{
return new JObject
{
{
"topLoadStart",
new JObject
{
{ "registrationName", "onLoadStart" }
}
},
{
"topLoad",
new JObject
{
{ "registrationName", "onLoad" }
}
},
{
"topLoadEnd",
new JObject
{
{ "registrationName", "onLoadEnd" }
}
},
{
"topError",
new JObject
{
{ "registrationName", "onError" }
}
},
};
}
}
/// <summary>
/// Called when view is detached from view hierarchy and allows for
/// additional cleanup.
/// </summary>
/// <param name="reactContext">The React context.</param>
/// <param name="view">The view.</param>
public override void OnDropViewInstance(ThemedReactContext reactContext, Border view)
{
base.OnDropViewInstance(reactContext, view);
_imageSources.TryRemove(view, out _);
}
[ReactPropGroup(
ViewProps.BorderWidth,
ViewProps.BorderLeftWidth,
ViewProps.BorderRightWidth,
ViewProps.BorderTopWidth,
ViewProps.BorderBottomWidth,
DefaultDouble = double.NaN)]
public void SetBorderWidth(Border view, int index, double width)
{
var _width = width;
//view.SetBorderWidth(ViewProps.BorderSpacingTypes[index], width);
}
/// <summary>
/// Creates the image view instance.
/// </summary>
/// <param name="reactContext">The React context.</param>
/// <returns>The image view instance.</returns>
protected override Border CreateViewInstance(ThemedReactContext reactContext)
{
var border = new Border
{
};
var gameHost = new GameHost((int)MainWindow.mw.ActualWidth, (int)MainWindow.mw.ActualHeight-60);
// container.Child = gameHost;
border.Child = gameHost;
var a = view;
return border;
}
}
}

注册组件:

MyReactPage.cs

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
29
30
31
32
33
34
35
36
using ReactNative.Bridge;
using ReactNative.Modules.Core;
using ReactNative.UIManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vesal_PC.MyModel;
namespace Vesal_PC
{
public class MyReactPage : IReactPackage
{
public static ReactContext context;
public IReadOnlyList<INativeModule> CreateNativeModules(ReactContext reactContext)
{
context = reactContext;
MyDialogModel mdm = new MyDialogModel(reactContext);
return new List<INativeModule>
{
mdm,
};
}
public IReadOnlyList<IViewManager> CreateViewManagers(ReactContext reactContext)
{
return new List<IViewManager> {
new ReactUnityManager()
};
}
}
}

AppReactPage.cs

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using ReactNative;
using ReactNative.Bridge;
using ReactNative.Modules.Core;
using ReactNative.Shell;
using ReactNative.UIManager;
using System;
using System.Collections.Generic;
using ReactNative.Modules.Dialog;
namespace Vesal_PC
{
internal class AppReactPage : ReactPage
{
public override string MainComponentName => "Vesal_PC";
public override string JavaScriptMainModuleName => "index";
#if BUNDLE
public override string JavaScriptBundleFile => AppDomain.CurrentDomain.BaseDirectory + "ReactAssets/index.wpf.bundle";
#endif
public override List<IReactPackage> Packages => new List<IReactPackage>
{
new MainReactPackage(),
new MyReactPage(),
};
public override bool UseDeveloperSupport
{
get
{
#if !BUNDLE || DEBUG
return true;
#else
return false;
#endif
}
}
}
}

前端:

UnityView.js

1
2
3
4
5
6
7
8
9
import { PropTypes, Component } from "react";
import { requireNativeComponent, View, ViewPropTypes } from "react-native";
class UnityView extends Component {
render() {
return <RCTUnityView {...this.props} />;
}
}
module.exports = requireNativeComponent("RCTUnityView", UnityView);

使用:

1
<UnityView style={{width:1680,height:1050}}/>

服务器监控脚本

发表于 2019-04-09   |   分类于 Python   |  

monitor.py

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# coding:utf-8
# !/usr/bin/env python3
import os
import time
from aliyunsdkdysmsapi.request.v20170525 import SendSmsRequest
from aliyunsdkdysmsapi.request.v20170525 import QuerySendDetailsRequest
from aliyunsdkcore.client import AcsClient
import uuid
from aliyunsdkcore.profile import region_provider
from aliyunsdkcore.http import method_type as MT
from aliyunsdkcore.http import format_type as FT
import const
# from config import Alarm_cache
from config import Settings
# 监控逻辑
# 注意:不要更改
REGION = "cn-hangzhou"
PRODUCT_NAME = "Dysmsapi"
DOMAIN = "dysmsapi.aliyuncs.com"
acs_client = AcsClient(const.ACCESS_KEY_ID, const.ACCESS_KEY_SECRET, REGION)
region_provider.add_endpoint(PRODUCT_NAME, REGION, DOMAIN)
def send_sms(phone_numbers, sign_name, template_code, template_param=None):
smsRequest = SendSmsRequest.SendSmsRequest()
# 申请的短信模板编码,必填
smsRequest.set_TemplateCode(template_code)
# 短信模板变量参数
if template_param is not None:
smsRequest.set_TemplateParam(template_param)
# 短信签名
smsRequest.set_SignName(sign_name)
# 数据提交方式
# smsRequest.set_method(MT.POST)
# 数据提交格式
# smsRequest.set_accept_format(FT.JSON)
# 短信发送的号码列表,必填。
smsRequest.set_PhoneNumbers(phone_numbers)
# 调用短信发送接口,返回json
smsResponse = acs_client.do_action_with_exception(smsRequest)
# TODO 业务处理
return smsResponse
def monitor():
print('***启动监控***')
while True:
ports = [8000, 8001, 8002]
for port in ports:
check_url = "http://api.XXX.cn:%s/server?type=0" % (
port)
command = "curl -I -m 30 -o /dev/null -s -w %{http_code} " + check_url
http_code = os.popen(command).read()
print("ping %s 状态码为%s" % (check_url, http_code))
if http_code != "200":
# Alarm_cache["ping_error"].append(diff)
# 发短信
print("###发送短信给相关的人###")
params = "{\"interface\":\"%s\"}" % (port)
for phone in Settings["alarm_phones"]:
print(send_sms(phone, "thisissignname", "SMS_99999999", params))
time.sleep(300)
print('5分钟后检查')
if __name__ == '__main__':
monitor()

config.py

1
2
3
4
5
6
7
8
# coding:utf-8
Alarm_cache = {
"ping_error": []
}
# 配置
Settings = {
"alarm_phones": ['thisiscellphone']
}

Android 调试|日志脚本

发表于 2019-04-08   |   分类于 前端   |  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
PackageName=$1
#PackageName=com.example.appinfomanagertinno
pid="$(adb shell ps | grep $PackageName | awk '{print $2}')"
echo "PackageName-----"
echo "$PackageName"
echo "-----------------------------------------"
echo "-----------------------------------------"
echo "pid-----"
echo "$pid"
echo "-----------------------------------------"
echo "-----------------------------------------"
adb logcat | grep $pid

使用方法
./logcat_package.sh com.XXX.XXX

1…456…16
peterfei

peterfei

peterfei|技术|上主是我的牧者

79 日志
14 分类
62 标签
RSS
github
© 2025 peterfei
由 Hexo 强力驱动
主题 - NexT.Mist