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

7

我已经在我的安卓应用中集成了pjsua2。当我发送短信时,应用程序会崩溃。它并非每次都会崩溃,而是随机发生(每发送10条消息中会出现一次)。

我的代码如下:

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()函数。但是在endpoint中我已经有了libRegisterThread()方法,因此我按照以下方式使用它。
MyApp.ep.libRegisterThread("SipApi");

日志如下:

../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个回答

5

对于那些想知道为什么它解决了问题的人:

为了澄清Gangadhar的解决方案,这个问题是由垃圾收集器引起的。根据PJSIP文档:

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

  1. 它延迟了Java对象(包括pjsua2对象)的销毁,导致对象析构函数中的代码执行顺序错误
  2. gc操作可能在不事先注册到PJLIB的不同线程上运行

解决方案是

应用程序必须立即使用对象的delete()方法销毁pjsua2对象,而不能依赖gc清理对象。

正如您可以在他的解决方案中看到的,他调用了MyBuddy的delete方法:

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

1
我不得不将 myBuddy.delete(); 移动到 finally 子句中,因为当你在异常退出时,对象没有被删除。 - Adrian C.

4

这里是正确的答案。

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

0
为了避免这种错误,您必须在调用libCreate()方法后立即注册外部线程(如Java线程);否则,将显示相同的错误。PJSUA2首先将当前线程注册为主线程,然后在libCreate()内部。因此,要注册不同的线程,您必须执行以下操作之一-
  1. 从要注册为主线程的线程中调用libCreate()。
  2. 在调用libCreate()后调用libRegisterThread(您想要的线程名称)。新线程将被注册为辅助线程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接