Запустить тяжелую задачу, запрограммированную в Rust, которая вызывается из Kotlin - PullRequest
0 голосов
/ 26 марта 2020

Я работаю над приложением и использую API Rust, который я написал. Я борюсь с темами / сопрограммами. У меня есть следующий код для запуска

#[no_mangle]
pub unsafe extern "C" fn Java_com_example_..._MainActivity_init (env: JNIEnv, _: JObject) {
    error!("pks8: {:?}", Path::new("PA").exists());
    if !Path::new("PASSWORD.txt").exists() {
        error!("in ");
        File::create("PASSWORD.txt").expect("Unable to create meta.json file");

        // Generate key
        let rng = rand::SystemRandom::new();
        let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
        error!("next");
}

Так как я думал, что это будет тяжелая задача, я решил запустить его в потоке, поэтому я сделал следующее

val init_rust = Thread {
     if (init()) {
        sleep(1000)
        runOnUiThread() {
            amountAv.text = get_amount()
        }
     } else {
        println("Init err")
     }
}

init_rust.start()

Однако это бросает следующая ошибка

Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 11068 (Thread-3), pid 11009 (le....)

Насколько я понял, это означает, что задача перегружает поток пользовательского интерфейса, чего я не понимаю, так как поток не должен запускаться за ее пределами?

Итак, я создал поток Rust в своей функции и решил запустить тело функции внутри нее.

thread::spawn(move || {
 ... body of the function
}).join();

Это, похоже, решило проблему с запуском в главном потоке, но потом это делает не запускается до конца, код останавливается на уровне ошибки! («в»), поэтому я предполагаю, что поток уничтожен.

Поскольку запуск его в потоке не работал, я попытался использовать сопрограммы, я сделал следующее:

launch(Dispatchers.Default) {
    init_rust()
}

private suspend fun init_rust(amountAv: TextView) {
        if (init()) {
            //Toast.makeText(this, "Send failed", Toast.LENGTH_LONG).show()
            sleep(1000)
            runOnUiThread() {
                amountAv.text = get_amount()
            }
        } else {
            println("Init err")
        }
    }

Я также попытался с Default.IO, но это дает мне тот же результат чем используя темы. Я добавил следующие права доступа к манифесту:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

У кого-нибудь есть идеи, как я могу это исправить?

Редактировать 1: Я обнаружил, что если я использовал следующий код:

 let x = thread::spawn(move || { 
   ...
 });
 let result = x.join();
 println!("Result {:?}", result.unwrap());

Я получаю ошибку:

A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 21459 (DefaultDispatch), pid 21386 (le. ...)

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