Rust JNI asyn c обратный вызов с Tokio и Reqwest для Android - PullRequest
0 голосов
/ 15 апреля 2020

Я тестирую Rust с JNI asyn c выполнение. Я хочу выполнить запросы в 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);
    }

И метод 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 env non-constant value:
let response = env.new_string(&name).expect("Couldn't create java string!");
   |                        ^^^ non-constant value

  • обратный вызов - doesn't have a size known at compile-time:
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

1 Ответ

0 голосов
/ 03 мая 2020

Я исправил свою проблему с использованием https://github.com/Dushistov/rust_swig После того, как вы интегрируете его, он автоматически сгенерирует код, и вы сможете проверить, как он это делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...