JS调用Android方法返回数据

作为一名经验丰富的开发者,我很高兴能够分享一些关于如何实现“js调用Android方法返回数据”的知识。这在混合开发中是一种常见的需求,尤其是在React Native或Weex等框架中。下面,我将详细介绍整个流程,并提供相应的代码示例。

流程概述

首先,让我们通过一个表格来概述整个流程:

步骤描述
1在Android端定义一个方法
2在Android端注册该方法到JS环境中
3在JS端调用Android方法
4Android端处理JS的调用并返回数据
5JS端接收并处理返回的数据

详细步骤

步骤1:在Android端定义一个方法

首先,我们需要在Android端定义一个方法,这个方法将被JS调用。这里我们以一个简单的示例为例,定义一个返回当前时间的方法。

public class MainActivity extends Activity {
    private static Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
    }

    public static String getCurrentTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date());
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
步骤2:在Android端注册该方法到JS环境中

接下来,我们需要将这个方法注册到JS环境中,以便JS能够调用它。这通常通过桥接实现。以下是使用React Native的示例:

public class MainApplication extends Application implements ReactApplication {
    @Override
    public ReactNativeHost getReactNativeHost() {
        return new ReactNativeHost(this) {
            @Override
            protected boolean getUseDeveloperSupport() {
                return BuildConfig.DEBUG;
            }

            @Override
            protected List<ReactPackage> getPackages() {
              return Arrays.<ReactPackage>asList(
                  new MainReactPackage()
              );
            }
        };
    }

    @Override
    public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

MainReactPackage中,我们注册了getCurrentTime方法:

public class MainReactPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(
            new MainModule(reactContext)
        );
    }

    public class MainModule extends ReactContextBaseJavaModule {
        private final ReactApplicationContext reactContext;

        MainModule(ReactApplicationContext reactContext) {
            super(reactContext);
            this.reactContext = reactContext;
        }

        @Override
        public String getName() {
            return "MainModule";
        }

        @ReactMethod
        public void getCurrentTime(Promise promise) {
            promise.resolve(MainActivity.getCurrentTime());
        }
    }
}
  • 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.
步骤3:在JS端调用Android方法

现在,我们可以在JS端调用Android方法了。以下是使用React Native的示例:

import { NativeModules } from 'react-native';

const { MainModule } = NativeModules;

export default {
  getCurrentTime: () => {
    return new Promise((resolve, reject) => {
      MainModule.getCurrentTime()
        .then(currentTime => {
          resolve(currentTime);
        })
        .catch(error => {
          reject(error);
        });
    });
  }
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
步骤4:Android端处理JS的调用并返回数据

在Android端,我们已经在MainModule中处理了JS的调用,并返回了当前时间。

步骤5:JS端接收并处理返回的数据

在JS端,我们通过Promise接收并处理返回的数据:

import TimeUtils from './TimeUtils';

TimeUtils.getCurrentTime().then(currentTime => {
  console.log('Current Time:', currentTime);
}).catch(error => {
  console.error('Error:', error);
});
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

关系图

以下是JS和Android之间的调用关系图:

erDiagram
    js ||--|| android : calls
    android {
        function getCurrentTime() string
    }
    js {
        function getCurrentTime() Promise
    }

类图

以下是涉及到的类和方法的类图:

contains contains 1 1 MainActivity +Context context +String getCurrentTime() MainApplication +ReactNativeHost getReactNativeHost() MainReactPackage +List getPackages() MainModule +String getCurrentTime(Promise promise)