从未知/外部线程调用pjlib。你必须" "使用pj_thread_register()注册外部线程

时间:2015-06-18 12:01:23

标签: android pjsip

我在我的Android应用程序中集成了pjsua2。发送短信时应用程序崩溃。它不会每次都崩溃,而是随机发生的。 (每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 个答案:

答案 0 :(得分:4)

(对于那些想知道为什么解决问题的人)

为了澄清Gangadhar的解决方案,问题是由垃圾收集器引起的。根据{{​​3}}:

  

Java垃圾收集器(gc)存在两个问题:

     
      
  1. 它延迟了Java对象(包括pjsua2对象)的破坏,   导致对象的析构函数中的代码无序执行
  2.   
  3. gc操作可以在不同的线程上运行,而不是之前   注册到PJLIB
  4.   

解决方案是

  

应用程序必须立即使用object摧毁pjsua2对象   delete()方法,而不是依赖于gc来清理对象。

你可以在他的解决方案中看到调用MyBuddy的删除方法:

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

答案 1 :(得分:3)

这是正确答案。

/**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;
    }
}

答案 2 :(得分:0)

为了避免这种错误,你必须在调用libCreate()方法之后注册外部线程(如Java线程);否则,将显示相同的错误。 PJSUA2首先将当前线程注册为libCreate()内的主线程。因此,要注册不同的线程,您必须执行以下操作之一 -

  1. 从要注册为main的线程中调用libCreate() 线。
  2. 之后调用libRegisterThread(所需线程的名称) 调用libCreate()。新线程将注册为辅助线程。