Вызов pjlib из неизвестного / внешнего потока. Вы должны " "зарегистрировать внешние потоки с регистром потоков pj()

я интегрировал pjsua2 в мое приложение для android. Приложение аварийно завершает работу, когда я отправляю SMS. Это происходит не каждый раз, это происходит случайно. (каждые 10 сообщений).

MyCode является:

public void sendInstantMessage(String number, String msgBody) {

    String buddy_uri = "<sip:" + number + "@" + mPref.getString(PREF_SIPSERVER, "") + ">";
    Log.e(TAG, "sendInstantMessage ==== "+buddy_uri);

    BuddyConfig bCfg = new BuddyConfig();
    bCfg.setUri(buddy_uri);
    bCfg.setSubscribe(false);

    MyBuddy im = new MyBuddy(bCfg);
    SendInstantMessageParam prm = new SendInstantMessageParam();
    prm.setContent(msgBody);
    prm.setContentType("text/plain; charset=utf-8");

    try {
        im.create(account, bCfg);
        boolean valid1 = im.isValid();
        Log.e(TAG, "valid1 ======= "+valid1);
        im.sendInstantMessage(prm);
    } catch (Exception e) {
        Log.e(TAG, "sendInstantMessage ==== "+e);
        e.printStackTrace();
        return;
    }

}

согласно logcat, я должен вызвать pj_thread_register (). Но у меня есть метод libRegisterThread () в конечной точке, поэтому я использовал его, как показано ниже

MyApp.ep.libRegisterThread("SipApi");

вот logcat:

../src/pj/os_core_unix.c:692: pj_thread_this: assertion "!"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions."" failed

3 ответов


(для тех из вас, кто задается вопросом, почему он решил проблему)

чтобы прояснить решение Gangadhar, проблема была вызвана сборщиком мусора. Согласно PJSIP документы:

есть две проблемы с Java garbage collector (gc):

  1. это задерживает уничтожение объектов Java (включая объекты pjsua2), выполнение кода в деструкторе объекта не по порядку
  2. операция gc может запускаться в другом потоке, не ранее зарегистрирован на PJLIB

решение

приложение должно немедленно уничтожить объекты pjsua2 с помощью объекта метод delete () вместо того, чтобы полагаться на gc для очистки объекта.

Как вы можете видеть в его решение, которое называется метод удаления функции MyBuddy это:

try {
    myBuddy.create(account, bCfg);
    myBuddy.sendInstantMessage(prm);
    myBuddy.delete();
} catch (Exception e) {
    e.printStackTrace();
    return;
}

вот правильный ответ.

/**Send message to this number
 * @param String number
 * @param String msgBody*/
public void sendInstantMessage(String number, String msgBody) {
    String sipServer = "aaa.ggg.net";
    String buddy_uri = "<sip:" + number + "@" + sipServer + ">";

    BuddyConfig bCfg = new BuddyConfig();
    bCfg.setUri(buddy_uri);
    bCfg.setSubscribe(false);

    MyBuddy myBuddy = new MyBuddy(bCfg);
    SendInstantMessageParam prm = new SendInstantMessageParam();
    prm.setContent(msgBody);

    try {
        myBuddy.create(account, bCfg);
        myBuddy.sendInstantMessage(prm);
        myBuddy.delete();
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }
}

чтобы избежать такого рода ошибок, вы должны зарегистрировать внешний поток (например, поток Java) сразу после вызова метода libCreate (); в противном случае будет показана та же ошибка. Pjsua2 сначала зарегистрирует текущий поток как основной поток внутри libCreate (). Итак, чтобы зарегистрировать другой поток, вам нужно сделать одно из следующих действий -

  1. вызовите libCreate () из потока, который вы хотите зарегистрировать как main нитка.
  2. вызов libRegisterThread (имя нужного потока) после вызов libCreate(). Новый поток будет зарегистрирован как вторичный поток.