如何在原生 App 中调用 Uniapp 的页面?

简介: 如何在原生 App 中调用 Uniapp 的页面?

在原生 App(Android/iOS)中调用 Uniapp 的页面,核心是通过 Uniapp 提供的原生 SDK 或 WebView 加载 Uniapp 编译后的资源,并实现页面跳转逻辑。以下分平台(Android/iOS)详细说明具体流程,包括准备工作、调用方式及通信处理。

一、准备工作(通用步骤)

  1. Uniapp 端生成可被原生调用的资源

    • 在 HBuilderX 中,将 Uniapp 项目通过“发行 → 原生 App-本地打包”生成资源包(含 www 目录,存放页面、JS、CSS 等),资源包文件夹以 __UNI__XXX 命名(XXX 为项目唯一标识,即 manifest.json 中的 appid)。
    • 记录该 appid(后续原生端需通过它定位 Uniapp 应用)。
  2. 原生端集成 Uniapp SDK

    • 下载对应平台的 Uniapp 原生 SDK(Android SDK / iOS SDK),并导入原生项目(具体导入步骤见下文分平台说明)。

二、Android 原生 App 调用 Uniapp 页面

Android 端通过 Uniapp SDK 提供的 UniActivity 或自定义容器加载 Uniapp 页面,支持直接打开首页或指定页面。

1. 基础配置(SDK 导入与资源放置)

  • 将下载的 Android SDK 中 libs 目录下的 uniapp-v8-release.aar 等依赖包复制到原生项目的 app/libs 目录,并在 build.gradle 中添加依赖:
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'])
        // 其他必要依赖(如 androidx 相关库)
    }
    
  • 将 Uniapp 生成的 __UNI__XXX 资源包复制到原生项目的 app/src/main/assets/apps 目录下(若没有 apps 文件夹则手动创建)。
  • assets/data 目录下创建 dcloud_control.xml,配置 Uniapp 应用信息(appid 需与资源包一致):
    <?xml version="1.0" encoding="UTF-8"?>
    <dcloud-control>
        <apps>
            <app appid="__UNI__XXX" appver="1.0.0" /> <!-- appver 为 Uniapp 版本号 -->
        </apps>
    </dcloud-control>
    

2. 调用 Uniapp 页面(两种方式)

方式 1:直接打开 Uniapp 首页

通过继承 UniActivity(SDK 提供的 Activity 基类),直接加载 Uniapp 项目中 pages.json 配置的首页:

// 新建一个 Activity 用于承载 Uniapp 页面
public class UniappHomeActivity extends UniActivity {
   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        // 无需额外代码,SDK 会自动加载 __UNI__XXX 的首页
    }
}

在原生其他页面(如 MainActivity)中通过 Intent 跳转:

// 从原生页面跳转到 Uniapp 首页
findViewById(R.id.btn_open_uniapp).setOnClickListener(v -> {
   
    Intent intent = new Intent(MainActivity.this, UniappHomeActivity.class);
    startActivity(intent);
});
方式 2:打开 Uniapp 指定页面(带参数)

若需打开 Uniapp 中的某个具体页面(如 pages/detail/detail.vue),可通过 Intent 传递页面路径和参数:

// 在原生页面中跳转时指定 Uniapp 页面路径
Intent intent = new Intent(MainActivity.this, UniappHomeActivity.class);
// 传递页面路径(必填)和参数(可选)
intent.putExtra("pagePath", "pages/detail/detail"); // Uniapp 页面相对路径
intent.putExtra("pageParams", "id=123&name=test"); // 参数以 query 字符串形式传递
startActivity(intent);

UniappHomeActivity 中接收参数并加载指定页面:

@Override
protected void onCreate(Bundle savedInstanceState) {
   
    super.onCreate(savedInstanceState);
    // 获取传递的页面路径和参数
    String pagePath = getIntent().getStringExtra("pagePath");
    String pageParams = getIntent().getStringExtra("pageParams");
    if (pagePath != null) {
   
        // 拼接完整路径(含参数)
        String url = pagePath + (pageParams != null ? "?" + pageParams : "");
        // 加载指定页面
        loadUrl(url);
    }
}

3. Uniapp 页面接收原生传递的参数

在 Uniapp 的目标页面(如 pages/detail/detail.vue)中,通过 onLoad 生命周期接收参数:

export default {
   
    onLoad(options) {
   
        console.log("从原生接收的参数:", options); // 输出 { id: "123", name: "test" }
    }
}

三、iOS 原生 App 调用 Uniapp 页面

iOS 端通过 DCUniSDK 框架加载 Uniapp 资源,支持在 UIViewController 中嵌入 Uniapp 页面,并跳转至指定页面。

1. 基础配置(SDK 导入与资源放置)

  • 将下载的 iOS SDK 中 DCUniSDK.framework 等文件拖拽到 Xcode 项目,勾选“Copy items if needed”,并在 Build Settings 中设置 Framework Search Paths 指向 SDK 目录,Other Linker Flags 添加 -ObjC
  • 将 Uniapp 生成的 __UNI__XXX 资源包复制到 Xcode 项目的 Resources/apps 目录(右键项目 → “Add Files to Project”,勾选“Create folder references”)。
  • Resources/data 目录下创建 dcloud_control.xml,配置内容与 Android 一致(appid 需匹配)。

2. 调用 Uniapp 页面(两种方式)

方式 1:打开 Uniapp 首页

在原生 UIViewController 中初始化 DCUniSDK 并加载首页:

#import <DCUniSDK/DCUniSDK.h>

// 自定义承载 Uniapp 页面的 ViewController
@interface UniContainerVC : UIViewController
@end

@implementation UniContainerVC
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    // 初始化 SDK,指定 Uniapp 的 appid
    [DCUniSDK sharedInstance].launchOptions = @{@"appid": @"__UNI__XXX"};
    // 加载 Uniapp 应用
    __weak typeof(self) weakSelf = self;
    [[DCUniSDK sharedInstance] loadAppWithCompletion:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            // 获取 Uniapp 根视图并添加到当前页面
            UIView *uniView = [DCUniSDK sharedInstance].rootView;
            uniView.frame = weakSelf.view.bounds;
            [weakSelf.view addSubview:uniView];
        }
    }];
}
@end

在原生其他页面(如 MainViewController)中跳转:

// 从原生页面跳转到 Uniapp 首页
- (IBAction)openUniappClick:(UIButton *)sender {
    UniContainerVC *vc = [[UniContainerVC alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}
方式 2:打开 Uniapp 指定页面(带参数)

通过 DCUniSDKopenPage 方法指定页面路径和参数:

// 在 UniContainerVC 中加载指定页面
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    // 初始化 SDK
    [DCUniSDK sharedInstance].launchOptions = @{@"appid": @"__UNI__XXX"};
    __weak typeof(self) weakSelf = self;
    [[DCUniSDK sharedInstance] loadAppWithCompletion:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            // 打开指定页面(路径+参数)
            NSString *pagePath = @"pages/detail/detail"; // 页面路径
            NSDictionary *params = @{@"id": @"123", @"name": @"test"}; // 参数
            [[DCUniSDK sharedInstance] openPage:pagePath withParams:params completion:^(BOOL success, NSError * _Nullable error) {
                if (success) {
                    UIView *uniView = [DCUniSDK sharedInstance].rootView;
                    uniView.frame = weakSelf.view.bounds;
                    [weakSelf.view addSubview:uniView];
                }
            }];
        }
    }];
}

3. Uniapp 页面接收 iOS 原生传递的参数

与 Android 一致,在 Uniapp 目标页面的 onLoad 中接收参数:

export default {
   
    onLoad(options) {
   
        console.log("从 iOS 原生接收的参数:", options); // 输出 { id: "123", name: "test" }
    }
}

四、原生调用 Uniapp 页面后的返回与通信

  1. Uniapp 页面返回原生页面
    Uniapp 中可通过 uni.navigateBack 关闭当前页面,若需返回到原生页面,可在 Uniapp 中调用原生方法通知关闭容器:

    // Uniapp 端调用原生方法请求关闭页面
    const nativeModule = uni.requireNativePlugin('NativeModule');
    nativeModule.closeUniappPage();
    

    原生端实现关闭逻辑(Android):

    // 在 NativeModule 中定义关闭方法
    @UniJSMethod(uiThread = true)
    public void closeUniappPage() {
         
        // 关闭当前 Uniapp 容器 Activity
        ((Activity) mUniSDKInstance.getContext()).finish();
    }
    
  2. 原生与 Uniapp 页面的实时通信
    除了跳转时传递参数,还可通过“事件监听”实现实时通信(如原生推送数据到 Uniapp 页面):

    • 原生端发送事件(Android):
      // 原生端发送事件到 Uniapp
      UniSDKEngine.sendEvent("native_data", "{\"message\": \"实时数据\"}");
      
    • Uniapp 端监听事件:
      // Uniapp 端监听原生事件
      uni.onNativeEventReceive((res) => {
             
          console.log("收到原生实时数据:", res.message); // 输出 "实时数据"
      }, "native_data");
      

五、注意事项

  1. 页面路径正确性:Uniapp 页面路径需与 pages.json 中配置的一致(如 pages/detail/detail,不带 .vue 后缀)。
  2. 参数格式:原生传递的参数建议用 JSON 字符串或 query 格式,Uniapp 会自动解析为对象。
  3. 资源同步:若 Uniapp 页面更新,需重新生成资源包并替换原生项目中的 __UNI__XXX 文件夹,避免加载旧版本页面。
  4. 权限与配置:确保原生 App 已声明 Uniapp 页面所需的权限(如网络、存储),否则可能导致页面加载失败。

通过以上方式,原生 App 可灵活调用 Uniapp 的任意页面,并实现参数传递和双向通信,兼顾原生 App 的功能完整性和 Uniapp 跨平台开发的效率。

相关文章
|
24天前
|
JavaScript API 开发工具
如何在原生App中调用Uniapp的原生功能?
如何在原生App中调用Uniapp的原生功能?
413 139
|
24天前
|
JSON JavaScript Android开发
原生与 Uniapp 的通信机制是如何实现双向调用的?
原生与 Uniapp 的通信机制是如何实现双向调用的?
302 137
|
24天前
|
移动开发 开发工具 Android开发
Uniapp与原生App集成的流程
Uniapp与原生App集成的流程
340 3
|
物联网 开发工具 Android开发
UniApp调用SDK原生接口
UniApp调用SDK原生接口
2345 0
UniApp调用SDK原生接口
|
24天前
|
移动开发 JavaScript API
Uniapp 与原生 App 集成时如何解决兼容性问题?
Uniapp 与原生 App 集成时如何解决兼容性问题?
338 136
|
24天前
|
缓存 JavaScript 小程序
怎样对UniApp的首屏渲染进行优化?
怎样对UniApp的首屏渲染进行优化?
312 140
|
开发框架 JavaScript 小程序
uni-app——如何阻止事件冒泡
uni-app——如何阻止事件冒泡
641 0
|
24天前
|
移动开发 JavaScript 开发工具
uniapp接入app
uniapp接入app
258 1
|
24天前
|
移动开发 JavaScript API
如何保证 UniApp 插件接口与 UniApp 规范兼容?
如何保证 UniApp 插件接口与 UniApp 规范兼容?
239 137