iText.Commons.Utils.DIContainer.GetInstance[T] 在Android Unity中抛出空引用异常

移动开发 2026-07-09

我正在使用iText生成PDF。在编辑器(Windows)中运行正常,但在进行Android构建时,抛出以下异常:

2026/06/01 12:45:41.669 29785 29810错误Unity
NullReferenceException: 对象引用未设置到对象的实例。

2026/06/01 12:45:41.669 29785 29810错误Unity
at iText.Commons.Utils.DIContainer.GetInstance[T] () [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity
at iText.Kernel.Pdf.PdfPagesTree..ctor (iText.Kernel.Pdf.PdfCatalog pdfCatalog) [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity
at iText.Kernel.Pdf.PdfCatalog..ctor (iText.Kernel.Pdf.PdfDictionary pdfObject) [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity
at iText.Kernel.Pdf.PdfDocument.Open (iText.Kernel.Pdf.PdfVersion newPdfVersion) [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity
at iText.Kernel.Pdf.PdfDocument..ctor (iText.Kernel.Pdf.PdfWriter writer) [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity
at PdfGenerator.CreatePdfFromImages (System.Collections.Generic.List`1[T] imagePaths, System.String pdfFileName, System.String ouputPath) [0x00000] in <00000000000000000000000000000000>:0

2026/06/01 12:45:41.669 29785 29810错误Unity

以下是我部分的PDF生成代码。我可以确认 pdfdocument 日志没有出现:

Debug.Log("=====PDF GENERATION STARTED=====");

// 1. Initialize PDF writer and PDF document
PdfWriter writer = new PdfWriter(savePath);
Debug.Log("PDF Writer initialized at: " + savePath);
System.Runtime.CompilerServices.RuntimeHelpers
      .RunClassConstructor(typeof(iText.Commons.Utils.DIContainer).TypeHandle);
Debug.Log("DIContainer cctor forced");

PdfDocument pdfDoc = new PdfDocument(writer);
Debug.Log("PDF Document created successfully.");

// 2. Initialize layout Document (Defaults to A4)
Document document = new Document(pdfDoc, PageSize.A4);
Debug.Log("Layout Document initialized with A4 page size.");

// 2. Instantiate your custom handler
HeaderFooterHandler handler = new HeaderFooterHandler();

以下是我的 link.xml 文件,以确保最终构建中不会排除任何代码。也许这会有问题?

<linker>
    <!-- Force preservation of DIContainer AND its static constructor -->
    <assembly fullname="itext.commons" preserve="all">
        <type fullname="iText.Commons.Utils.DIContainer" preserve="all">
            <method signature="Void .cctor()" />
        </type>
        <type fullname="iText.Commons.Utils.DIContainerConfigurations" preserve="all">
            <method signature="Void .cctor()" />
            <method signature="Microsoft.Extensions.DependencyInjection.IServiceProvider Build()" />
            <method signature="Microsoft.Extensions.DependencyInjection.IServiceCollection Configure(Microsoft.Extensions.DependencyInjection.IServiceCollection)" />
        </type>
        <type fullname="iText.Commons.Actions.ProductProcessorFactoryKeeper" preserve="all">
            <method signature="Void .cctor()" />
        </type>
        <type fullname="iText.Commons.Actions.Processors.DefaultProductProcessorFactory" preserve="all">
            <method signature="Void .cctor()" />
        </type>
        <type fullname="iText.Commons.Bouncycastle.BouncyCastleFactoryCreator" preserve="all">
            <method signature="Void .cctor()" />
        </type>
    </assembly>

    <assembly fullname="itext.kernel" preserve="all">
        <type fullname="iText.Kernel.Pdf.PdfDocument" preserve="all">
            <method signature="Void .cctor()" />
        </type>
        <type fullname="iText.Kernel.Pdf.PdfPagesTree" preserve="all">
            <method signature="Void .cctor()" />
        </type>
    </assembly>

    <!-- Keep everything else the same as before -->
    <assembly fullname="itext" preserve="all"/>
    <assembly fullname="itext.io" preserve="all"/>
    <assembly fullname="itext.layout" preserve="all"/>
    <assembly fullname="itext.bouncy-castle-adapter" preserve="all"/>
    <assembly fullname="itext.bouncy-castle-fips-adapter" preserve="all"/>
    <assembly fullname="BouncyCastle.Cryptography" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.DependencyInjection" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.DependencyInjection.Abstractions" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.Logging" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.Logging.Abstractions" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.Options" preserve="all"/>
    <assembly fullname="Microsoft.Extensions.Primitives" preserve="all"/>
    <assembly fullname="Microsoft.Bcl.AsyncInterfaces" preserve="all"/>
    <assembly fullname="System.Text.Json" preserve="all"/>
    <assembly fullname="System.Text.Encodings.Web" preserve="all"/>
    <assembly fullname="System.Runtime.Loader" preserve="all"/>
    <assembly fullname="System.Reflection.TypeExtensions" preserve="all"/>
</linker>

解决方案

你能指明你正在使用的版本吗?
另外,在Android部署方面你使用的是怎样的设置?如果你在使用AOT,可能需要告诉AOT哪些反射类会被使用。

你可能需要使用一个:ILLink.Descriptors.xml(将其放在项目根文件夹中,紧邻csproj文件)

<linker>
  <assembly fullname="itext.font_asian" preserve="all" />
  <assembly fullname="itext.hyph" preserve="all" />
  <assembly fullname="itext.kernel">
    <type fullname="iText.Kernel.Utils.RegisterDefaultDiContainer" preserve="all" />
  </assembly>
  <assembly fullname="itext.forms">
    <type fullname="iText.Forms.Util.RegisterDefaultDiContainer" preserve="all" />
  </assembly>
</linker>

你可以把它添加到你的 .csproj 中,如下所示:
一些示例csproj文件

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <RootNamespace>aot_cli_sample</RootNamespace>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PublishAot>true</PublishAot>
        <InvariantGlobalization>true</InvariantGlobalization>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="itext" Version="9.7.0-SNAPSHOT" />
        <PackageReference Include="itext.commons" Version="9.7.0-SNAPSHOT" />
        <PackageReference Include="itext.font-asian" Version="9.7.0-SNAPSHOT" />
        <PackageReference Include="itext.hyph" Version="9.7.0-SNAPSHOT" />
        <PackageReference Include="itext.bouncy-castle-adapter" Version="9.7.0-SNAPSHOT" />
    </ItemGroup>
    <ItemGroup>
        <EmbeddedResource Include="ILLink.Descriptors.xml">
            <LogicalName>ILLink.Descriptors.xml</LogicalName>
        </EmbeddedResource>
    </ItemGroup>
</Project>

如果那样不起作用(应该会起作用),你也可以尝试手动添加依赖。

DocumentProperties documentProperties = new DocumentProperties();
documentProperties.RegisterDependency(typeof(IPageTreeListFactory), new DefaultPageTreeListFactory(50000));
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new ByteArrayOutputStream()), documentProperties);

但请注意,这并不是唯一会被自动注册的依赖,因此ILink的 XML文件是更好的选择,否则你可能还需要再添加其他一些内容。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章