我正在测试使用JNI异步执行Rust。我想在Rust中执行请求并通过回调异步返回结果给Android。我正在测试在命令行中执行请求的代码,它能正常工作。
以下是在命令行中的工作方式:
回调结构:
struct Processor {
pub(crate) callback: Box<dyn FnMut(String)>,
}
impl Processor {
fn set_callback(&mut self, c: impl FnMut(String) + 'static) {
self.callback = Box::new(c);
}
fn process_events(&mut self, result: String) {
(self.callback)(result);
}
}
Tokio/reqwest:
const DATA_URL: &str = "https://pokeapi.co/api/v2/pokemon/1/";
#[tokio::main]
pub async fn load_swapi_async_with_cb(callback: Box<dyn FnMut(String)>) -> Result<(), Box<dyn std::error::Error>> {
println!("load_swload_swapi_async_with_cbapi_async started");
let mut cb = Processor {
callback: Box::new(callback),
};
let body = reqwest::get(DATA_URL)
.await?
.json::<HashMap<String, String>>()
.await?;
//println!("{:#?}", body);
let name = match body.get("name") {
Some(name) => name,
None => "Failed to parse"
}.to_string();
println!("Name is: {} ", name);
cb.process_events(name);
Ok(())
}
并且 JNI 部分:
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn Java_com_omg_app_greetings_MainActivity_callback(env: JNIEnv,
_class: JClass,
callback: JObject) {
static callback: dyn FnMut(String) + 'static = |name| {
let response = env.new_string(&name).expect("Couldn't create java string!");
env.call_method(callback, "rustCallbackResult", "(Ljava/lang/String;)V",
&[JValue::from(JObject::from(response))]).unwrap();
};
pokemon_api(callback);
}
关于 pokemon API 的方法:
#[no_mangle]
pub extern fn pokemon_api(callback: impl FnMut(String) + 'static) {
let cb_box = Box::new(callback);
swapi::load_swapi_async_with_cb(cb_box);
}
我遇到的错误:
- JNI环境
env非常量值
:
let response = env.new_string(&name).expect("Couldn't create java string!");
| ^^^ non-constant value
回调函数 -
在编译时大小未知
:static callback: dyn FnMut(String) + 'static = |name| {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
我在检查这个工作原理,但这个示例似乎已经过时: * https://github.com/mozilla/rust-android-gradle/blob/master/samples/rust/src/lib.rs
JNIEnv*
都绑定到创建它的线程,并且在不同的线程上使用JNIEnv
是致命错误。幸运的是,您可以使用AttachCurrentThreadAsDaemon
来获取有效的JNIEnv
。 - Botje