【问题标题】:Android VpnService.Builder.establish() sporadically nullAndroid VpnService.Builder.establish() 偶尔为空
【发布时间】:2017-12-28 16:10:39
【问题描述】:

当我尝试为我的 VpnService 创建隧道接口时,我收到以下错误:

Attempt to invoke virtual method 'java.lang.String android.os.ParcelFileDescriptor.toString()' on a null object reference

我目前唯一的解决办法是在发生这种情况时重新启动设备。如果不这样做,我根本无法创建隧道。

我创建隧道的代码:

// This is inside my VpnService implementation 

private ParcelFileDescriptor configureTunnelWithPushOpts(PushOpts popts)
{
    VpnService.Builder builder = this.new Builder();

    builder.setMtu       ( currentServerPrefs.SERVER_MTU );
    builder.addAddress   ( popts.ip, 32                  );
    builder.addDnsServer ( popts.dns1                    );
    builder.addDnsServer ( popts.dns2                    );
    builder.addRoute     ( "0.0.0.0", 0                  );


    // Note: Blocking mode is now enabled in native
    // code under the setFileDescriptor function.
    // builder.setBlocking(true);

    builder.setConfigureIntent(
            PendingIntent.getActivity(
                    this,
                    0,
                    new Intent(
                            this,
                            MainActivity.class
                    ),
            PendingIntent.FLAG_UPDATE_CURRENT)
    );

    final ParcelFileDescriptor vpnInterface;

    synchronized (this) {
        builder.setSession(currentServerPrefs.SERVER_ADDRESS);
        vpnInterface = builder.establish();
    }

    Logger.info("New interface: " + vpnInterface.toString(), this);
    return vpnInterface;
}

编辑:

根据文档,如果 VpnService 尚未准备好,establish 函数将返回 null,但是我在运行上述函数之前使用它来准备它。

// This is inside my MainActivity class

Intent intent = VpnService.prepare(getApplicationContext());
if (intent != null) {
    startActivityForResult(intent, 0);
} else {
    onActivityResult(0, RESULT_OK, null);
}

. . . 

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        Intent intent = new Intent(this, MyVpnService.class);
        startService(intent);
    }
}

我用于调试的手机

Google Nexus 5 Running Android 5.0.1

编辑

我想出了如何复制它,这样它就不再是零星的了。 基本上,如果我在连接 VPN 时卸载应用程序,然后重新安装并尝试重新启动它,当我运行 builder.establish() 时会收到空响应。我担心当应用程序通过 Google Play 商店更新时,这可能会带来潜在的问题。

除此之外,请不要将此问题标记为重复。关于这个问题的所有其他问题都得到了答案,即服务需要在构建器建立之前准备好,但是我正在准备它,并且我的问题有不同的原因。任何帮助,将不胜感激。

【问题讨论】:

  • 你看过OnRevoke方法吗?其他东西可能使用vpn
  • 我知道这是一个老问题,但你找到解决这个问题的方法了吗?我面临同样的行为(在 5.0.1 Android、三星 Galaxy S5 上)。提前致谢。
  • @Cyber​​MJ 仍然没有找到解决方案:/.

标签: android android-vpn-service parcelfiledescriptor


【解决方案1】:

非常感谢您的提示,它让我找到了解决方案!

我在 Android 5.0.2 中遇到了同样的问题:一切正常,我安装了我正在开发的 vpn 应用程序。第二天,突然,一个无法解析的NullPointerException,尽管prepare 被正确调用了。

可以通过以下步骤在我的环境中解决该问题:

  • 卸载应用程序。应用是否仍具有有效的 VPN 功能并不重要。
  • 重启手机。确保它已完全关闭。
  • 重启后,确保不再安装该应用(我遇到了一些奇怪的开发问题,即重启手机后重新安装了一个应用)。
  • 再次安装您的 VPN 应用程序。它现在应该会收到一个 vpn 接口,而不再是 null

【讨论】:

  • 这样做的问题是最终用户可能会做同样的事情,卸载应用程序然后重新安装它并遇到相同的 NullPointerException。我不想告诉我的最终用户重新启动他们的手机只是为了使用该应用程序。
  • 也许有人可以用一个均匀的监听器捕获卸载,然后优雅地停用/关闭 vpn?这个问题是只出现在开发环境(也可能和adb有关),还是你用生产App测试过?
猜你喜欢
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-29
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多