You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Aspera SDK集成到React Native及Android端实现文件传输

React Native Android 集成 Aspera SDK 分步指南

我之前刚完成了React Native Android端集成Aspera SDK的文件传输需求,给你整理了一套亲测有效的分步指南,涵盖从准备到测试的全流程:

1. 前期准备

  • 先从IBM获取Aspera Mobile SDK for Android的资源包(通常是.aar格式的文件),还有官方提供的依赖清单、集成文档,这是基础前提
  • 确保你的React Native项目环境正常运行:Android SDK、NDK(如果SDK要求)都配置到位,RN版本建议用0.60+,因为autolinking能省不少配置功夫
  • 在RN项目的android/app/目录下新建libs文件夹,把下载好的Aspera .aar文件放进去

2. 配置Android项目

2.1 修改build.gradle依赖

打开android/app/build.gradle文件,做两处修改:

  • 在android块里添加本地仓库配置,让项目能识别libs里的aar文件:
repositories {
    flatDir {
        dirs 'libs'
    }
}
  • 在dependencies块里添加本地aar依赖,以及Aspera SDK要求的其他第三方依赖(比如okhttp、gson,具体看官方文档):
implementation files('libs/aspera-sdk-release.aar')
// 示例依赖,根据实际SDK要求调整版本
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'com.google.code.gson:gson:2.10.1'

2.2 配置Manifest权限

打开android/app/src/main/AndroidManifest.xml,添加文件传输必需的权限:

<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 文件读写权限(适配Android版本) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />

注意:如果Aspera SDK需要后台服务支持,记得按照官方文档在Manifest里注册对应的服务组件

3. 编写Native Module桥接原生SDK

React Native无法直接调用原生SDK,所以需要写一个Native Module做桥接:

3.1 创建Transfer模块类

在android/app/src/main/java/com/你的项目包名/目录下新建AsperaFileTransferModule.java,封装上传、下载和进度回调:

package com.yourprojectpackage;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.ibm.aspera.sdk.transfer.TransferManager;
import com.ibm.aspera.sdk.transfer.TransferConfig;
import com.ibm.aspera.sdk.transfer.TransferCallback;

public class AsperaFileTransferModule extends ReactContextBaseJavaModule {
    private TransferManager transferManager;

    public AsperaFileTransferModule(ReactApplicationContext reactContext) {
        super(reactContext);
        // 根据Aspera服务器配置初始化TransferManager
        TransferConfig config = new TransferConfig.Builder()
                .setServerUrl("你的Aspera服务器地址")
                .setUsername("服务器账号")
                .setPassword("服务器密码")
                .build();
        transferManager = new TransferManager(config);
    }

    @Override
    public String getName() {
        return "AsperaFileTransfer"; // RN层调用的模块名
    }

    // 上传文件方法,暴露给RN
    @ReactMethod
    public void uploadFile(String localFilePath, String remotePath, Promise promise) {
        try {
            transferManager.upload(localFilePath, remotePath, new TransferCallback() {
                @Override
                public void onSuccess() {
                    promise.resolve("上传完成");
                }

                @Override
                public void onError(Exception e) {
                    promise.reject("UPLOAD_FAILED", e.getMessage());
                }

                @Override
                public void onProgress(long bytesTransferred, long totalBytes) {
                    // 发送进度事件到RN层
                    sendTransferProgressEvent((int) (bytesTransferred * 100 / totalBytes));
                }
            });
        } catch (Exception e) {
            promise.reject("UPLOAD_FAILED", e.getMessage());
        }
    }

    // 下载文件方法,暴露给RN
    @ReactMethod
    public void downloadFile(String remoteFilePath, String localSavePath, Promise promise) {
        try {
            transferManager.download(remoteFilePath, localSavePath, new TransferCallback() {
                @Override
                public void onSuccess() {
                    promise.resolve("下载完成");
                }

                @Override
                public void onError(Exception e) {
                    promise.reject("DOWNLOAD_FAILED", e.getMessage());
                }

                @Override
                public void onProgress(long bytesTransferred, long totalBytes) {
                    sendTransferProgressEvent((int) (bytesTransferred * 100 / totalBytes));
                }
            });
        } catch (Exception e) {
            promise.reject("DOWNLOAD_FAILED", e.getMessage());
        }
    }

    // 发送进度事件到RN的工具方法
    private void sendTransferProgressEvent(int progress) {
        getReactApplicationContext()
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("TransferProgress", progress);
    }
}

3.2 创建Package注册模块

新建AsperaFileTransferPackage.java,用来注册刚才的Module:

package com.yourprojectpackage;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AsperaFileTransferPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new AsperaFileTransferModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

注意:RN 0.60+版本支持autolinking,不需要手动注册Package;如果是旧版本,需要在MainApplication.java的getPackages()方法里添加packages.add(new AsperaFileTransferPackage());

4. React Native层封装与调用

4.1 创建工具类封装方法

在RN项目根目录新建AsperaTransfer.js,封装Native Module的方法和事件监听:

import { NativeModules, NativeEventEmitter } from 'react-native';

const { AsperaFileTransfer } = NativeModules;
const asperaEventEmitter = new NativeEventEmitter(AsperaFileTransfer);

// 监听传输进度
export const subscribeToProgress = (callback) => {
    return asperaEventEmitter.addListener('TransferProgress', (progress) => {
        callback(progress);
    });
};

// 上传文件
export const uploadFile = async (localPath, remotePath) => {
    try {
        const result = await AsperaFileTransfer.uploadFile(localPath, remotePath);
        return result;
    } catch (error) {
        throw new Error(`上传失败:${error.message}`);
    }
};

// 下载文件
export const downloadFile = async (remotePath, localSavePath) => {
    try {
        const result = await AsperaFileTransfer.downloadFile(remotePath, localSavePath);
        return result;
    } catch (error) {
        throw new Error(`下载失败:${error.message}`);
    }
};

4.2 在组件中使用

比如在App.js里实现上传功能和进度显示:

import React, { useEffect, useState } from 'react';
import { View, Button, Text, Alert } from 'react-native';
import { uploadFile, subscribeToProgress } from './AsperaTransfer';

const App = () => {
    const [transferProgress, setTransferProgress] = useState(0);

    useEffect(() => {
        // 订阅传输进度事件
        const progressSubscription = subscribeToProgress((progress) => {
            setTransferProgress(progress);
        });
        // 组件卸载时取消订阅
        return () => progressSubscription.remove();
    }, []);

    const handleUpload = async () => {
        try {
            // 替换为实际的本地文件路径和远程服务器路径
            const localFilePath = '/storage/emulated/0/Download/test.pdf';
            const remoteFilePath = '/server/storage/path/test.pdf';
            const result = await uploadFile(localFilePath, remoteFilePath);
            Alert.alert('成功', result);
            setTransferProgress(0);
        } catch (error) {
            Alert.alert('失败', error.message);
            setTransferProgress(0);
        }
    };

    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Button title="上传测试文件" onPress={handleUpload} />
            {transferProgress > 0 && (
                <Text style={{ marginTop: 20 }}>传输进度:{transferProgress}%</Text>
            )}
        </View>
    );
};

export default App;

5. 测试与注意事项

  • 测试前确保设备/模拟器有网络,Aspera服务器配置(地址、账号密码)正确,并且服务器允许该账号进行文件传输
  • Android 10+的文件权限需要特殊处理:要么申请MANAGE_EXTERNAL_STORAGE权限,要么使用MediaStore或SAF来获取文件路径,避免权限被拒绝
  • 调试时可以在Native层添加日志(比如Log.d("AsperaModule", "上传进度:" + progress)),方便定位问题
  • 如果遇到SDK初始化失败,先检查依赖是否全部添加,.aar文件是否正确放置在libs目录

内容的提问来源于stack exchange,提问作者Nikesh Yerneni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:07:32